-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f20e742
commit bb8daf0
Showing
4 changed files
with
127 additions
and
0 deletions.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
modules/common/chowdsp_data_structures/Structures/chowdsp_StackAllocator.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#pragma once | ||
|
||
#include <vector> | ||
|
||
namespace chowdsp | ||
{ | ||
/** A simple stack allocator */ | ||
class StackAllocator | ||
{ | ||
public: | ||
StackAllocator() = default; | ||
|
||
StackAllocator (const StackAllocator&) = delete; | ||
StackAllocator& operator= (const StackAllocator&) = delete; | ||
|
||
StackAllocator (StackAllocator&&) noexcept = default; | ||
StackAllocator& operator= (StackAllocator&&) noexcept = default; | ||
|
||
/** Re-allocates the internal buffer with a given number of bytes */ | ||
void reset (size_t new_size_bytes) | ||
{ | ||
clear(); | ||
raw_data.resize (new_size_bytes, {}); | ||
} | ||
|
||
/** Resets the allocator */ | ||
void clear() noexcept | ||
{ | ||
bytes_used = 0; | ||
} | ||
|
||
/** Returns the number of bytes currently being used */ | ||
[[nodiscard]] size_t get_bytes_used() const noexcept { return bytes_used; } | ||
|
||
/** Allocates a given number of bytes */ | ||
void* allocate_bytes (size_t num_bytes) noexcept | ||
{ | ||
if (bytes_used + num_bytes > raw_data.size()) | ||
return nullptr; | ||
|
||
auto* pointer = raw_data.data() + bytes_used; | ||
bytes_used += num_bytes; | ||
return pointer; | ||
} | ||
|
||
/** Allocates space for some number of objects of type T */ | ||
template <typename T, typename IntType> | ||
T* allocate (IntType num_Ts) noexcept | ||
{ | ||
return static_cast<T*> (allocate_bytes ((size_t) num_Ts * sizeof (T))); | ||
} | ||
|
||
/** Returns a pointer to the internal buffer with a given offset in bytes */ | ||
template <typename T, typename IntType> | ||
T* data (IntType offset_bytes) noexcept | ||
{ | ||
return reinterpret_cast<T*> (raw_data.data() + offset_bytes); | ||
} | ||
|
||
/** | ||
* Creates a "frame" for the allocator. | ||
* Once the frame goes out of scope, the allocator will be reset | ||
* to whatever it's state was at the beginning of the frame. | ||
*/ | ||
struct StackAllocatorFrame | ||
{ | ||
explicit StackAllocatorFrame (StackAllocator& allocator) | ||
: alloc (allocator), | ||
bytes_used_at_start (alloc.bytes_used) | ||
{ | ||
} | ||
|
||
~StackAllocatorFrame() | ||
{ | ||
alloc.bytes_used = bytes_used_at_start; | ||
} | ||
|
||
StackAllocator& alloc; | ||
const size_t bytes_used_at_start; | ||
}; | ||
|
||
private: | ||
std::vector<std::byte> raw_data {}; | ||
size_t bytes_used = 0; | ||
}; | ||
} // namespace chowdsp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
tests/common_tests/chowdsp_data_structures_test/StackAllocatorTest.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#include <CatchUtils.h> | ||
#include <chowdsp_data_structures/chowdsp_data_structures.h> | ||
|
||
TEST_CASE ("Stack Allocator Test", "[common][data-structures]") | ||
{ | ||
chowdsp::StackAllocator allocator; | ||
allocator.reset (150); | ||
|
||
// allocate doubles | ||
{ | ||
auto* some_doubles = allocator.allocate<double> (10); | ||
REQUIRE ((void*) some_doubles == allocator.data<void> (0)); | ||
REQUIRE (allocator.get_bytes_used() == 80); | ||
} | ||
|
||
// allocate ints | ||
{ | ||
auto* some_ints = allocator.allocate<int32_t> (10); | ||
REQUIRE ((void*) some_ints == allocator.data<void> (80)); | ||
REQUIRE (allocator.get_bytes_used() == 120); | ||
} | ||
|
||
// allocate with stack frame | ||
{ | ||
chowdsp::StackAllocator::StackAllocatorFrame frame { allocator }; | ||
auto* some_chars = allocator.allocate<char> (30); | ||
juce::ignoreUnused (some_chars); | ||
REQUIRE (allocator.get_bytes_used() == 150); | ||
} | ||
|
||
REQUIRE (allocator.get_bytes_used() == 120); | ||
|
||
// overfull allocation | ||
REQUIRE (allocator.allocate<double> (100) == nullptr); | ||
|
||
// clear allocator | ||
allocator.clear(); | ||
REQUIRE (allocator.get_bytes_used() == 0); | ||
} |