Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE > Class Template Reference

Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed automatically switches to heap based so can grow - BUF_SIZE is number of T elements allocated inline. More...

#include <InlineBuffer.h>

Public Member Functions

 InlineBuffer () noexcept
 
nonvirtual operator const T * () const noexcept
 returns the same value as data () - a live pointer to the start of the buffer.
 
nonvirtual pointer data () noexcept
 returns a (possibly const) pointer to the start of the live buffer data. This return value can be invalidated by any changes in size/capacity of the InlineBuffer (but not by other changes, like at).
 
nonvirtual reference at (size_t i) noexcept
 
nonvirtual reference operator[] (size_t i) noexcept
 
constexpr size_t capacity () const noexcept
 
nonvirtual void reserve (size_t newCapacity, bool atLeast=true)
 
nonvirtual size_t GetSize () const noexcept
 
nonvirtual size_t size () const noexcept
 
nonvirtual bool empty () const noexcept
 
nonvirtual void resize (size_t nElements)
 
nonvirtual void resize_uninitialized (size_t nElements)
 same as resize (), except leaves newly created elements uninitialized (requires is_trivially_copyable_v<T>)
 
nonvirtual void ShrinkTo (size_t nElements)
 
nonvirtual void GrowToSize (size_t nElements)
 
nonvirtual void GrowToSize_uninitialized (size_t nElements)
 same as GrowToSize (), except leaves newly created elements uninitialized (requires is_trivially_copyable_v<T>)
 
nonvirtual void insert (iterator i, const_pointer from, const_pointer to)
 
nonvirtual void push_back (Common::ArgByValueType< T > e)
 
template<ISpan SPAN_T>
nonvirtual void push_back_coerced (const SPAN_T &copyFrom)
 same as push_back (span{}) except that the span type doesn't need to match exactly, so long as indirected items can be copied to destination (with static_cast).
 

Static Public Attributes

static constexpr size_t kMinCapacity = BUF_SIZE
 

Detailed Description

template<typename T = byte, size_t BUF_SIZE = InlineBuffer_DefaultInlineSize<T> ()>
class Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >

Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed automatically switches to heap based so can grow - BUF_SIZE is number of T elements allocated inline.

Typically, InlineBuffer<> combines the performance of using a pre-allocated fixed-sized buffer to store arrays with the safety and flexibility of using the free store (malloc).

Think of it as a hybrid between std::vector<> and std::array - with functionality like std::vector, but performance more like std::array.

Note
if BUF_SIZE is zero, this class behaves much like 'vector<T>'

Internally, InlineBuffer maintains a fixed buffer (of size given by its BUFFER_SIZE template parameter) and it uses that while things fit, and switches to using a free-store-allocated data as needed. Pick the BUF_SIZE wisely, and you always end up with fixed sized objects. Pick poorly, and it will still work, but allocating the data on the free store.

typically sizeof(InlineBuffer<T,BUF_SIZE>) will come to roughly BUF_SIZE*sizeof(T).

See also
also StackBuffer<T,BUF_SIZE> - similar, but less flexible, and could someday be more performant.

All allocated objects are default initialized, unless they are allocated through a call to resize_uninitialized(), or the constructor with the argument eUninitialized

Note
Until Stroika 2.1r4, this class was called SmallStackBuffer<>, cuz that's basically the most common scenario it was used for up til that point.
Example Usage
See also
Samples/SimpleService project
Memory::InlineBuffer<byte> useKey{keyLen}; // no need to default initialize cuz done automatically
(void)::memcpy (useKey.begin (), key.begin (), min (keyLen, key.size ()));
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
OR
Memory::InlineBuffer<byte> useKey{Memory::eUninitialized, keyLen};
(void)::memset (useKey.begin (), 0, keyLen);
(void)::memcpy (useKey.begin (), key.begin (), min (keyLen, key.size ()));
Note
Thread-Safety C++-Standard-Thread-Safety
InlineBuffer<T> can roughly be used as a replacement for vector<> - behaving similarly, except that its optimized for the case where the caller statically knows GENERALLY the right size for the buffer, in which case it can be allocated more cheaply.

InlineBuffer<T> CAN be copied, and will properly construct/destruct array members as they are added/removed. (new feature as of Stroika v2.1b6).

Note
We do not provide an operator[] overload because this creates ambiguity with the operator* overload.
Implementation Note - we store the store the 'capacity' in a union (fCapacityOfFreeStoreAllocation_) overlapping with fInlinePreallocatedBuffer_ if its > BUF_SIZE, and pin it at the minimum to BUF_SIZE

Definition at line 90 of file InlineBuffer.h.

Constructor & Destructor Documentation

◆ InlineBuffer()

template<typename T , size_t BUF_SIZE>
Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::InlineBuffer ( )
noexcept

InlineBuffer::InlineBuffer (size_t) specifies the initial size - like InlineBuffer::InlineBuffer {} followed by resize (n); InlineBuffer::default-ctor creates a zero-sized stack buffer (so resize with resize, or push_back etc).

Definition at line 27 of file InlineBuffer.inl.

Member Function Documentation

◆ operator const T *()

template<typename T , size_t BUF_SIZE>
Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::operator const T * ( ) const
explicitnoexcept

returns the same value as data () - a live pointer to the start of the buffer.

Note
This was changed from non-explicit to explicit in Stroika v3.0d1

Definition at line 558 of file InlineBuffer.inl.

◆ at()

template<typename T , size_t BUF_SIZE>
InlineBuffer< T, BUF_SIZE >::reference Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::at ( size_t  i)
noexcept
Precondition
i < size ()

Definition at line 426 of file InlineBuffer.inl.

◆ operator[]()

template<typename T , size_t BUF_SIZE>
auto Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::operator[] ( size_t  i)
noexcept
Precondition
i < size ()

Definition at line 438 of file InlineBuffer.inl.

◆ capacity()

template<typename T , size_t BUF_SIZE>
constexpr size_t Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::capacity ( ) const
constexprnoexcept

Returns the 'size' the InlineBuffer can be resized up to without any additional memory allocations. This always returns a value at least as large as the BUF_SIZE template parameter.

See also
reserve

Definition at line 308 of file InlineBuffer.inl.

◆ reserve()

template<typename T , size_t BUF_SIZE>
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::reserve ( size_t  newCapacity,
bool  atLeast = true 
)

Provide a hint as to how much (contiguous) space to reserve.

if (default true) atLeast flag is true, newCapacity is adjusted (increased) with GetScaledUpCapacity to minimize needless copies as buffer grows, but only if any memory allocation would have been needed anyhow.

if atLeast is false, then reserve sets the capacity to exactly the amount prescribed (unless its less than BUF_SIZE). This can be used to free-up used memory.

See also
capacity
Precondition
(newCapacity >= size ());
Postcondition
(newCapacity <= BUF_SIZE and capacity () == BUF_SIZE) or (newCapacity > BUF_SIZE and newCapacity == capacity ());

Definition at line 322 of file InlineBuffer.inl.

◆ GetSize()

template<typename T , size_t BUF_SIZE>
size_t Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::GetSize ( ) const
noexcept

Returns the number of (constructed) elements in the buffer in ELEMENTS (not necessarily in bytes).

Postcondition
GetSize () <= capacity ();

Definition at line 409 of file InlineBuffer.inl.

◆ size()

template<typename T , size_t BUF_SIZE>
size_t Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::size ( ) const
noexcept

Returns the number of (constructed) elements in the buffer.

See also
GetSize (); // alias
capacity ();
Postcondition
size () <= capacity ();

Definition at line 415 of file InlineBuffer.inl.

◆ empty()

template<typename T , size_t BUF_SIZE>
bool Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::empty ( ) const
noexcept

returns true iff size () == 0

Definition at line 421 of file InlineBuffer.inl.

◆ resize()

template<typename T , size_t BUF_SIZE>
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::resize ( size_t  nElements)

Grow or shrink the buffer. The 'size' is the number of constructed elements, and this function automatically assures the capacity is maintained at least as large as the size.

If resize () causes the list to grow, the new elements are default-initialized()

Postcondition
GetSize () <= capacity ();

Definition at line 231 of file InlineBuffer.inl.

◆ resize_uninitialized()

template<typename T , size_t BUF_SIZE>
requires (is_trivially_copyable_v<T> and is_trivially_destructible_v<T>)
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::resize_uninitialized ( size_t  nElements)

same as resize (), except leaves newly created elements uninitialized (requires is_trivially_copyable_v<T>)

Precondition
is_trivially_copyable_v<T>
Postcondition
GetSize () <= capacity ();

Definition at line 256 of file InlineBuffer.inl.

◆ ShrinkTo()

template<typename T , size_t BUF_SIZE>
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::ShrinkTo ( size_t  nElements)

Same as resize (nElements), except asserts (documents) the new size must be smaller or equal to the old size.

Precondition
nElements <= size ()

Definition at line 267 of file InlineBuffer.inl.

◆ GrowToSize()

template<typename T , size_t BUF_SIZE>
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::GrowToSize ( size_t  nElements)

Grow the buffer to at least nElements in size (wont shrink). The 'size' is the number of constructed elements, and this function automatically assures the capacity is maintained at least as large as the size.

Postcondition
GetSize () <= capacity ();

Definition at line 213 of file InlineBuffer.inl.

◆ GrowToSize_uninitialized()

template<typename T , size_t BUF_SIZE>
requires (is_trivially_copyable_v<T>)
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::GrowToSize_uninitialized ( size_t  nElements)

same as GrowToSize (), except leaves newly created elements uninitialized (requires is_trivially_copyable_v<T>)

Precondition
is_trivially_copyable_v<T>
Postcondition
GetSize () <= capacity ();

Definition at line 221 of file InlineBuffer.inl.

◆ insert()

template<typename T , size_t BUF_SIZE>
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::insert ( iterator  i,
const_pointer  from,
const_pointer  to 
)

mimic the std::vector::insert () API - but better to call Insert ()

Definition at line 488 of file InlineBuffer.inl.

◆ push_back()

template<typename T , size_t BUF_SIZE>
void Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::push_back ( Common::ArgByValueType< T >  e)

With a single T argument, this is somewhat STLISH, but also takes overload of a span, so you can append multiple.

Aliases
Append
See also
also push_back_coerced ()

Definition at line 493 of file InlineBuffer.inl.

Member Data Documentation

◆ kMinCapacity

template<typename T = byte, size_t BUF_SIZE = InlineBuffer_DefaultInlineSize<T> ()>
constexpr size_t Stroika::Foundation::Memory::InlineBuffer< T, BUF_SIZE >::kMinCapacity = BUF_SIZE
staticconstexpr

kMinCapacity is the baked in minimum capacity of this buff (inline allocated part).

Definition at line 118 of file InlineBuffer.h.


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