memory_stack< BlockOrRawAllocator > Class Template Reference
Allocator implementations

## Detailed Description

template<class BlockOrRawAllocator = default_allocator>
class foonathan::memory::memory_stack< BlockOrRawAllocator >

A stateful RawAllocator that provides stack-like (LIFO) allocations.

It uses a memory_arena with a given `BlockOrRawAllocator` defaulting to growing_block_allocator to allocate huge blocks and saves a marker to the current top. Allocation simply moves this marker by the appropriate number of bytes and returns the pointer at the old marker position, deallocation is not directly supported, only setting the marker to a previously queried position.

## Typedefs

using | allocator_type = make_block_allocator_t< BlockOrRawAllocator >
using | marker = implementation_defined
| The marker type that is used for unwinding.

## Static Functions

static constexpr std::size_t | min_block_size (std::size_t byte_size) noexcept

## Member Functions

template<typename... Args>
| memory_stack (std::size_t block_size, Args &&... args)
void * | allocate (std::size_t size, std::size_t alignment)
void * | try_allocate (std::size_t size, std::size_t alignment) noexcept
marker | top () const noexcept
void | unwind (marker m) noexcept
void | shrink_to_fit () noexcept
std::size_t | capacity_left () const noexcept
std::size_t | next_capacity () const noexcept
allocator_type & | get_allocator () noexcept

## Typedefs

## marker

template<class BlockOrRawAllocator = default_allocator>

using marker = implementation_defined

The marker type that is used for unwinding.

The exact type is implementation defined, it is only required that it is efficiently copyable and has all the comparision operators defined for two markers on the same stack. Two markers are equal, if they are copies or created from two `top()` calls without a call to `unwind()` or `allocate()`. A marker `a` is less than marker `b`, if after `a` was obtained, there was one or more call to `allocate()` and no call to `unwind()`.

## Constructors

## memory_stack()

template<class BlockOrRawAllocator = default_allocator>
template<typename... Args>

memory_stack | ( | std::size_t | block_size,
|  | Args &&... | args
| ) |  |

explicit

Effects:
  Creates it with a given initial block size and and other constructor arguments for the BlockAllocator. It will allocate the first block and sets the top to its beginning.

Requires:
  `block_size` must be at least `min_block_size(1)`.

## Member Functions

## min_block_size()

template<class BlockOrRawAllocator = default_allocator>

static constexpr std::size_t min_block_size | ( | std::size_t | byte_size | ) |

static constexpr noexcept

Returns:
  The minimum block size required for a stack containing the given amount of memory. If a stack is created with the result of `min_block_size(n)`, the resulting capacity will be exactly `n`.

Requires:
  `byte_size` must be a positive number.

Note
  Due to debug fence sizes, the actual amount of usable memory can vary. However, this is impossible to compute without knowing the exact allocation pattern before, so this is just a rough estimate.

## allocate()

template<class BlockOrRawAllocator = default_allocator>

void * allocate | ( | std::size_t | size,
|  | std::size_t | alignment
| ) |  |

Effects:
  Allocates a memory block of given size and alignment. It simply moves the top marker. If there is not enough space on the current memory block, a new one will be allocated by the BlockAllocator or taken from a cache and used for the allocation.

Returns:
  A node with given size and alignment.

Throws:
  Anything thrown by the BlockAllocator on growth or bad_allocation_size if `size` is too big.

Requires:
  `size` and `alignment` must be valid.

## try_allocate()

template<class BlockOrRawAllocator = default_allocator>

void * try_allocate | ( | std::size_t | size,
|  | std::size_t | alignment
| ) |  |

noexcept

Effects:
  Allocates a memory block of given size and alignment, similar to allocate(). But it does not attempt a growth if the arena is empty.

Returns:
  A node with given size and alignment or `nullptr` if there wasn't enough memory available.

## top()

template<class BlockOrRawAllocator = default_allocator>

marker top | ( |  | ) | const

noexcept

Returns:
  A marker to the current top of the stack.

## unwind()

template<class BlockOrRawAllocator = default_allocator>

void unwind | ( | marker | m | ) |

noexcept

Effects:
  Unwinds the stack to a certain marker position. This sets the top pointer of the stack to the position described by the marker and has the effect of deallocating all memory allocated since the marker was obtained. If any memory blocks are unused after the operation, they are not deallocated but put in a cache for later use, call shrink_to_fit() to actually deallocate them.

Requires:
  The marker must point to memory that is still in use and was the whole time, i.e. it must have been pointed below the top at all time.

## shrink_to_fit()

template<class BlockOrRawAllocator = default_allocator>

void shrink_to_fit | ( |  | ) |

noexcept

Effects:
  unwind() does not actually do any deallocation of blocks on the BlockAllocator, unused memory is stored in a cache for later reuse. This function clears that cache.

## capacity_left()

template<class BlockOrRawAllocator = default_allocator>

std::size_t capacity_left | ( |  | ) | const

noexcept

Returns:
  The amount of memory remaining in the current block. This is the number of bytes that are available for allocation before the cache or BlockAllocator needs to be used.

## next_capacity()

template<class BlockOrRawAllocator = default_allocator>

std::size_t next_capacity | ( |  | ) | const

noexcept

Returns:
  The size of the next memory block after the current block is exhausted and the arena grows. This function just forwards to the memory_arena.

Note
  All of it is available for the stack to use, but due to fences and alignment buffers, this may not be the exact amount of memory usable for the user.

## get_allocator()

template<class BlockOrRawAllocator = default_allocator>

allocator_type & get_allocator | ( |  | ) |

noexcept

Returns:
  A reference to the BlockAllocator used for managing the arena.

Requires:
  It is undefined behavior to move this allocator out into another object.