REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
real::detail::small_vec< T, InlineCapacity > Class Template Reference

Small-buffer-optimized vector for the dynamic hot paths: up to InlineCapacity elements inline, spilling to the heap beyond that. More...

#include <storage.hpp>

Collaboration diagram for real::detail::small_vec< T, InlineCapacity >:
[legend]

Classes

struct  inline_block
 Inline element block: a struct so the union constructor can activate it whole with construct_at in a constant expression, holding a plain C array the static analyzer can bound (std::array::operator[] trips a false out-of-bounds on transfer_range). More...
 
union  Storage
 The either-or storage: the inline buffer, or a pointer to the heap block once the vector has spilled. is_heap_ says which member is active. More...
 

Public Types

using value_type = T
 Element type.
 

Public Member Functions

constexpr small_vec () noexcept
 Constructs an empty vector in the inline state.
 
constexpr ~small_vec ()
 Destroys elements and frees any heap block.
 
constexpr void push_back (const T &value)
 Appends value, growing to the heap if the inline buffer is full.
 
constexpr void assign (std::size_t count, const T &value)
 Resizes to count copies of value.
 
constexpr void ensure_size (std::size_t count)
 Ensures at least count live elements without re-filling or shrinking.
 
constexpr std::size_t size () const noexcept
 Returns the number of elements.
 
constexpr bool empty () const noexcept
 Returns true if empty.
 
constexpr T & operator[] (std::size_t i) noexcept
 Returns reference to the element at i.
 
constexpr const T & operator[] (std::size_t i) const noexcept
 Returns const reference to the element at i.
 
constexpr void clear () noexcept
 Removes all elements (capacity and heap state unchanged).
 
constexpr T & back () noexcept
 Returns reference to the last element. Precondition: the vector is non-empty.
 
constexpr const T & back () const noexcept
 Returns const reference to the last element. Precondition: the vector is non-empty.
 
constexpr void pop_back () noexcept
 Removes the last element. Precondition: the vector is non-empty.
 
constexpr void reserve (std::size_t new_capacity)
 Ensures capacity for at least new_capacity elements (heap-backed).
 
constexpr small_vec (small_vec &&other) noexcept
 Move constructor: steals other's heap block or moves inline elements.
 
constexpr small_vec & operator= (small_vec &&other) noexcept
 Move assignment.
 
constexpr small_vec (const small_vec &other)
 Copy constructor.
 
constexpr small_vec & operator= (const small_vec &other)
 Copy assignment.
 

Private Member Functions

constexpr void refresh_data () noexcept
 Refreshes data_ to the active storage base (run time only).
 
constexpr T * inline_data () noexcept
 Returns pointer to the inline buffer.
 
constexpr const T * inline_data () const noexcept
 Returns const pointer to the inline buffer.
 
template<bool Move>
constexpr void transfer_range (const T *src, std::size_t count, T *dest)
 Copies or moves count elements from src to dest.
 
template<bool Move>
constexpr void transfer_inline_from (const small_vec &other)
 Transfers other's inline elements into this vector's inline buffer.
 
constexpr void adopt_heap (T *p) noexcept
 Points the union at p, making Storage::heap_ptr the active member.
 
constexpr void revert_to_inline () noexcept
 Makes the inline buffer the active union member again, after the heap block is gone.
 
constexpr void cleanup () noexcept
 Frees the heap block, if any; no element destructor runs (T is trivially destructible).
 
constexpr void extend_capacity ()
 Doubles the capacity (saturating), spilling to the heap as needed.
 

Static Private Member Functions

static constexpr T * allocate_block (std::size_t n)
 Obtains storage for n elements from the allocator the current regime allows.
 
static constexpr void deallocate_block (T *p, std::size_t n) noexcept
 Releases a block from allocate_block.
 

Private Attributes

std::size_t size_ {}
 Number of elements in use.
 
std::size_t capacity_ {InlineCapacity}
 Current capacity.
 
bool is_heap_ {}
 True once spilled to the heap.
 
union real::detail::small_vec::Storage storage_
 The active storage, inline or heap.
 
T * data_ {}
 Cached base of the active storage (run time only); see refresh_data.
 

Detailed Description

template<typename T, std::size_t InlineCapacity>
class real::detail::small_vec< T, InlineCapacity >

Small-buffer-optimized vector for the dynamic hot paths: up to InlineCapacity elements inline, spilling to the heap beyond that.

Note
T must be trivially destructible (static_assert): no element destructor ever runs.
Warning
At run time the inline buffer is UNINITIALIZED (value-initialized only under constant evaluation, in the Storage constructor). Every element's lifetime begins with std::construct_at before it is read, and reads stay within [0, size_); a new accessor must keep that write-before-read order. Only MemorySanitizer detects a breach (the CI sanitize leg is ASan/UBSan): run an MSan build when changing element access.
Template Parameters
TElement type.
InlineCapacityNumber of elements held inline before spilling.

Constructor & Destructor Documentation

◆ small_vec() [1/2]

template<typename T , std::size_t InlineCapacity>
constexpr real::detail::small_vec< T, InlineCapacity >::small_vec ( small_vec< T, InlineCapacity > &&  other)
inlineconstexprnoexcept

Move constructor: steals other's heap block or moves inline elements.

Parameters
[in,out]otherThe vector to move from; left empty and inline.

◆ small_vec() [2/2]

template<typename T , std::size_t InlineCapacity>
constexpr real::detail::small_vec< T, InlineCapacity >::small_vec ( const small_vec< T, InlineCapacity > &  other)
inlineconstexpr

Copy constructor.

Parameters
[in]otherThe vector to copy.

Member Function Documentation

◆ adopt_heap()

template<typename T , std::size_t InlineCapacity>
constexpr void real::detail::small_vec< T, InlineCapacity >::adopt_heap ( T *  p)
inlineconstexprprivatenoexcept

Points the union at p, making Storage::heap_ptr the active member.

Constant evaluation must begin the pointer's lifetime (ending the inline buffer's); run time keeps a plain assignment, on every VM container's spill path.

Parameters
[in]pThe heap block to adopt.

◆ allocate_block()

template<typename T , std::size_t InlineCapacity>
static constexpr T * real::detail::small_vec< T, InlineCapacity >::allocate_block ( std::size_t  n)
inlinestaticconstexprprivate

Obtains storage for n elements from the allocator the current regime allows.

Constant evaluation cannot call a raw allocation operator, so it uses std::allocator, whose transient blocks must all be released before the evaluation ends (cleanup does).

Parameters
[in]nElement count.
Returns
Uninitialized storage for n elements.

◆ assign()

template<typename T , std::size_t InlineCapacity>
constexpr void real::detail::small_vec< T, InlineCapacity >::assign ( std::size_t  count,
const T &  value 
)
inlineconstexpr

Resizes to count copies of value.

Parameters
[in]countNumber of elements.
[in]valueThe value to fill with.

◆ back() [1/2]

template<typename T , std::size_t InlineCapacity>
constexpr const T & real::detail::small_vec< T, InlineCapacity >::back ( ) const
inlineconstexprnoexcept

Returns const reference to the last element. Precondition: the vector is non-empty.

Returns
A const reference to the last element.

◆ back() [2/2]

template<typename T , std::size_t InlineCapacity>
constexpr T & real::detail::small_vec< T, InlineCapacity >::back ( )
inlineconstexprnoexcept

Returns reference to the last element. Precondition: the vector is non-empty.

Returns
A reference to the last element.

◆ deallocate_block()

template<typename T , std::size_t InlineCapacity>
static constexpr void real::detail::small_vec< T, InlineCapacity >::deallocate_block ( T *  p,
std::size_t  n 
)
inlinestaticconstexprprivatenoexcept

Releases a block from allocate_block.

Parameters
[in]pBlock base.
[in]nThe capacity it was allocated with — std::allocator requires the exact count.

◆ empty()

template<typename T , std::size_t InlineCapacity>
constexpr bool real::detail::small_vec< T, InlineCapacity >::empty ( ) const
inlineconstexprnoexcept

Returns true if empty.

Returns
Whether the vector holds no elements.

◆ ensure_size()

template<typename T , std::size_t InlineCapacity>
constexpr void real::detail::small_vec< T, InlineCapacity >::ensure_size ( std::size_t  count)
inlineconstexpr

Ensures at least count live elements without re-filling or shrinking.

Same contract as static_vec::ensure_size, except that the new tail is value-initialized.

Parameters
[in]countMinimum size.

◆ inline_data() [1/2]

template<typename T , std::size_t InlineCapacity>
constexpr const T * real::detail::small_vec< T, InlineCapacity >::inline_data ( ) const
inlineconstexprprivatenoexcept

Returns const pointer to the inline buffer.

Returns
A const pointer to its first element, whether or not the inline state is active.

◆ inline_data() [2/2]

template<typename T , std::size_t InlineCapacity>
constexpr T * real::detail::small_vec< T, InlineCapacity >::inline_data ( )
inlineconstexprprivatenoexcept

Returns pointer to the inline buffer.

Returns
A pointer to its first element, whether or not the inline state is active.

◆ operator=() [1/2]

template<typename T , std::size_t InlineCapacity>
constexpr small_vec & real::detail::small_vec< T, InlineCapacity >::operator= ( const small_vec< T, InlineCapacity > &  other)
inlineconstexpr

Copy assignment.

Parameters
[in]otherSource.
Returns
*this.

◆ operator=() [2/2]

template<typename T , std::size_t InlineCapacity>
constexpr small_vec & real::detail::small_vec< T, InlineCapacity >::operator= ( small_vec< T, InlineCapacity > &&  other)
inlineconstexprnoexcept

Move assignment.

Parameters
[in,out]otherSource (left empty).
Returns
*this.

◆ operator[]() [1/2]

template<typename T , std::size_t InlineCapacity>
constexpr const T & real::detail::small_vec< T, InlineCapacity >::operator[] ( std::size_t  i) const
inlineconstexprnoexcept

Returns const reference to the element at i.

Parameters
[in]iIndex.
Returns
Const reference to the element at i.

◆ operator[]() [2/2]

template<typename T , std::size_t InlineCapacity>
constexpr T & real::detail::small_vec< T, InlineCapacity >::operator[] ( std::size_t  i)
inlineconstexprnoexcept

Returns reference to the element at i.

Parameters
[in]iIndex.
Returns
Reference to the element at i.

◆ push_back()

template<typename T , std::size_t InlineCapacity>
constexpr void real::detail::small_vec< T, InlineCapacity >::push_back ( const T &  value)
inlineconstexpr

Appends value, growing to the heap if the inline buffer is full.

Parameters
[in]valueThe element to append.

◆ reserve()

template<typename T , std::size_t InlineCapacity>
constexpr void real::detail::small_vec< T, InlineCapacity >::reserve ( std::size_t  new_capacity)
inlineconstexpr

Ensures capacity for at least new_capacity elements (heap-backed).

Parameters
[in]new_capacityDesired minimum capacity; smaller is a no-op.

◆ revert_to_inline()

template<typename T , std::size_t InlineCapacity>
constexpr void real::detail::small_vec< T, InlineCapacity >::revert_to_inline ( )
inlineconstexprprivatenoexcept

Makes the inline buffer the active union member again, after the heap block is gone.

Required wherever a spilled vector returns inline (a moved-from source, an assignment target): a later constant-evaluated inline_data read would otherwise touch an inactive member.

◆ size()

template<typename T , std::size_t InlineCapacity>
constexpr std::size_t real::detail::small_vec< T, InlineCapacity >::size ( ) const
inlineconstexprnoexcept

Returns the number of elements.

Returns
The element count.

◆ transfer_inline_from()

template<typename T , std::size_t InlineCapacity>
template<bool Move>
constexpr void real::detail::small_vec< T, InlineCapacity >::transfer_inline_from ( const small_vec< T, InlineCapacity > &  other)
inlineconstexprprivate

Transfers other's inline elements into this vector's inline buffer.

Runs only when other has not spilled, so clamping the count to InlineCapacity changes no value; it stops g++ -O3 propagating a spilled source's size_ into this branch and warning -Wstringop-overflow on the memcpy in transfer_range.

Template Parameters
MoveIf true, move-construct the elements; otherwise copy-construct.
Parameters
[in]otherThe not-yet-spilled source vector.

◆ transfer_range()

template<typename T , std::size_t InlineCapacity>
template<bool Move>
constexpr void real::detail::small_vec< T, InlineCapacity >::transfer_range ( const T *  src,
std::size_t  count,
T *  dest 
)
inlineconstexprprivate

Copies or moves count elements from src to dest.

Template Parameters
MoveIf true, move-construct; otherwise copy-construct.
Parameters
[in]srcSource range.
[in]countElement count.
[out]destDestination (uninitialized) range.

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