iffl  1.3.4
Implements Intrusive Flat Forward List container
Public Member Functions | Protected Member Functions | List of all members
iffl::input_buffer_memory_resource Class Reference

implements std::pmr::memory_resource interface. More...

#include <iffl_allocator.h>

Inheritance diagram for iffl::input_buffer_memory_resource:

Public Member Functions

 input_buffer_memory_resource (void *buffer, size_t buffer_size) noexcept
 Constructs memory resource with information about buffer that should be used for allocation. More...
 
 ~input_buffer_memory_resource () noexcept
 Destructor verifies that there are no outstanding allocations.
 
size_t get_busy_blocks_count () const noexcept
 Can be used to query number of outstanding allocations. More...
 
void validate_no_busy_blocks () const noexcept
 Triggers fail fast if there are outstanding allocations.
 

Protected Member Functions

void * do_allocate (size_t bytes, [[maybe_unused]] size_t alignment) override
 Overrides memory resource virtual method that performs allocation. More...
 
void do_deallocate (void *p, size_t bytes, [[maybe_unused]] size_t alignment) noexcept override
 Overrides memory resource virtual method that performs deallocation. More...
 
bool do_is_equal (memory_resource const &other) const noexcept override
 Validates that two memory resources are equivalent. For this class they must be equal. More...
 

Detailed Description

implements std::pmr::memory_resource interface.

This class can be used with Polymorphic Memory Allocator. Forward Linked List has typedef for PMR called pmr_flat_forward_list. This memory resource allows constructing flat forward list on a buffer owned by someone else.

This memory resource can be instantiated to point to a buffer that is owned elsewhere. Using this memory resource you can allocate buffer to a single owned Consequent allocations will throw bad_alloc until buffer is deallocated. On deallocation it checks that deallocated buffer is the same as allocation buffer. It will fail-fast on mismatch. Deallocated buffer can be allocated again. Deallocation does not free the buffer. It is assumed that buffer is owned by someone else.

Sample usage:

In the below example memory resource is instantiated to point to the input buffer. Container is parametrized to use this memory resource. We resize container buffer to consume entire input buffer in one allocation. After that we keep appending data to the container try_* methods that would not attempt to reallocate larger buffer, and consequently are noexcept as long as caller's functor does not throw. Instead they return false when buffer cannot fit new element. Once a try_* function returns false, we know that buffer is filled, and we can exit. To let caller know how much of the buffer was filled with data we will set output_size to the size of part of the buffer used by the inserted elements. Optionally, if we want caller to adopt buffer without verification, we can return offset to the last element in the buffer. Container destructor will deallocate memory back to resource. Memory resource destructor will detach from the buffer. Buffer content remains unattached, and still contains a valid list. Once method returns, caller can examine buffer using flat forward list reference or view or attach it to the container with allocator compatible to how buffer was allocated.

void build_result(char *buffer, size_t buffer_size, size_t *output_size) {
iffl::input_buffer_memory_resource buffer_memory_resource{buffer, buffer_size};
ffl.resize_buffer(buffer_size);
for(;;) {
if(!ffl.try_push_back(<data>, <data_size>) {
break;
}
}
*output_size = ffl.used_capacity();
}

Thread safety:

This class is not thread safe and cannot be used to perform concurent allocations from multiple threads.

Constructor & Destructor Documentation

◆ input_buffer_memory_resource()

iffl::input_buffer_memory_resource::input_buffer_memory_resource ( void *  buffer,
size_t  buffer_size 
)
inlineexplicitnoexcept

Constructs memory resource with information about buffer that should be used for allocation.

Parameters
buffer- pointer to the buffer that we will return on allocation
buffer_size- size of the buffer

Member Function Documentation

◆ do_allocate()

void* iffl::input_buffer_memory_resource::do_allocate ( size_t  bytes,
[[maybe_unused] ] size_t  alignment 
)
inlineoverrideprotected

Overrides memory resource virtual method that performs allocation.

Parameters
bytes- number of bytes to be allocated.
alignment- alignment requirements for the allocated buffer.
Exceptions
std::bad_allocif allocation fails
Returns
On success return a pointer to the buffer of requested size. On failure throws std::bad_alloc.

◆ do_deallocate()

void iffl::input_buffer_memory_resource::do_deallocate ( void *  p,
size_t  bytes,
[[maybe_unused] ] size_t  alignment 
)
inlineoverrideprotectednoexcept

Overrides memory resource virtual method that performs deallocation.

Parameters
p- pointer to the user buffer that is deallocated.
bytes- buffer size. Mast match to the size that was allocated.
alignment- alignment of the buffer. Must match to alignment at allocation time.
Returns
void. Checks buffer that buffer was allocated, and that deallocated buffer match to the buffer that we own. Triggers fail fast if check does not pass.

◆ do_is_equal()

bool iffl::input_buffer_memory_resource::do_is_equal ( memory_resource const &  other) const
inlineoverrideprotectednoexcept

Validates that two memory resources are equivalent. For this class they must be equal.

Parameters
other- reference to the other memory resource.
Returns
true if other memory resource is the same object, and false otherwise.

◆ get_busy_blocks_count()

size_t iffl::input_buffer_memory_resource::get_busy_blocks_count ( ) const
inlinenoexcept

Can be used to query number of outstanding allocations.

Returns
number of outstanding allocations

The documentation for this class was generated from the following file: