density
C++11 library for paged memory management, function queues, heterogeneous queues and lifo memory management
|
#include <lifo.h>
Public Types | |
using | underlying_allocator = UNDERLYING_ALLOCATOR |
Public Member Functions | |
constexpr | lifo_allocator () noexcept |
lifo_allocator (const UNDERLYING_ALLOCATOR &i_underlying_allocator) | |
lifo_allocator (UNDERLYING_ALLOCATOR &&i_underlying_allocator) | |
lifo_allocator (const lifo_allocator &)=delete | |
lifo_allocator & | operator= (const lifo_allocator &)=delete |
void * | allocate (size_t i_size) |
void * | allocate_empty () noexcept |
void | deallocate (void *i_block, size_t i_size) noexcept |
void * | reallocate (void *i_block, size_t i_old_size, size_t i_new_size) |
~lifo_allocator () | |
UNDERLYING_ALLOCATOR & | underlying_allocator_ref () noexcept |
const UNDERLYING_ALLOCATOR & | underlying_allocator_ref () const noexcept |
Static Public Attributes | |
static constexpr size_t | alignment = ALIGNMENT |
Class template that provides LIFO memory management.
UNDERLYING_ALLOCATOR | Underlying allocator class, that can be stateless or stateful. It must meet the requirements of both UntypedAllocator and PagedAllocator. |
ALIGNMENT | Alignment of the blocks. It must be non-zero and a power of 2. |
A lifo_allocator uses memory pages allocated from the underlying allocator to provide lifo memory management to the user. It is designed to be efficient, so it does not provide an high-level service. All blocks has the same alignment (specified by the template argument), and the size of the requested blocks must be a multiple of it. Deallocation and reallocation functions require the caller to specify the current size of the block. Blocks that are very large according to a some implementation-defined criteria, are handled with legacy heap allocations.
A living block is a block allocated, eventually reallocated, but not yet deallocated. Reallocating or deallocating a block which is not the most recently allocated living block causes undefined behavior. Instances of lifo_allocator are not interchangeable: blocks allocated by an instance can't be deallocated with another instance. All living blocks must be deallocated before the allocator is destroyed, otherwise the behavior is undefined.
lifo_allocator is a stateful class template (it has non-static data members). It is uncopyable, unmovable and incomparable.
The constructor of lifo_allocator is constexpr and guarantees constant initialization.
A block allocation or deallocation requires only a few ALU instructions and a branch to a slow path, that is taken whenever a page switch occurs. The internal state of the allocator is composed by a pointer, that points to the next block allocate would return. A call to allocate_empty just return the top of the stack, without altering the state of the allocator. lifo_allocator does not cache free pages: when a page or a block is no more used, it is immediately deallocated.
using underlying_allocator = UNDERLYING_ALLOCATOR |
Alias for the template argument UNDERLYING_ALLOCATOR
|
inlinenoexcept |
Default constructor, non-throwing and suitable for constant initialization.
|
inline |
Constructs passing the underlying allocator as l-value
|
inline |
Constructs passing the underlying allocator as r-value
|
delete |
Copy construction not allowed
|
inline |
Destroys the allocator, deallocating the bottom page in case this allocator is not virgin
|
delete |
Copy assignment not allowed
|
inline |
Allocates a memory block. The content of the newly allocated memory is undefined. The new memory block is aligned at least to alignment.
i_size | The size of the requested block, in bytes. |
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).
|
inlinenoexcept |
Allocates a block with size 0.
This function is equivalent to allocate(0), but it is much faster and never throws. The returned block can be reallocated and deallocated.
This function is useful to initialize block owners to an empty state in a noexcept context, without introducing the nullptr special case. The implementation of the default constructor of lifo_buffer uses this function.
Throws: nothing.
Implementation notes: this function just returns the top of the stack, without altering the state of the allocator.
|
inlinenoexcept |
Deallocates the most recently allocated living memory block.
i_block | The memory block to deallocate |
i_size | Size of the block. |
Throws: nothing.
|
inline |
Reallocates the most recently allocated living memory block, changing its size. The address of the block may change. The content of the memory block is preserved up to the existing extend. If the memory block is moved to another address, its content is copied with memcopy.
i_block | block to be resized. After the call, if no exception is thrown, this pointer must be discarded, because it may point to invalid memory. |
i_old_size | the previous size of the block, in bytes. |
i_new_size | the new size requested for the block, in bytes. |
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).
|
inlinenoexcept |
Returns a reference to the underlying allocator
|
inlinenoexcept |
Returns a const reference to the underlying allocator
|
static |
Alias for the template argument ALIGNMENT