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

Fixed-capacity vector backed by an inline array (no heap). More...

#include <storage.hpp>

Public Member Functions

constexpr static_vec () noexcept
 Value-initializes data_ during constant evaluation only.
 
constexpr void push_back (const T &value)
 Appends value.
 
constexpr void clear ()
 Removes all elements (capacity unchanged).
 
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
 Returns the number of elements.
 
constexpr bool empty () const
 Returns true if empty.
 
constexpr T & operator[] (std::size_t i)
 Returns reference to the element at i.
 
constexpr const T & operator[] (std::size_t i) const
 Returns const reference to the element at i.
 
constexpr T & back ()
 Returns reference to the last element. Precondition: the vector is non-empty.
 
constexpr void pop_back ()
 Removes the last element. Precondition: the vector is non-empty.
 

Private Attributes

std::array< T, Cap > data_
 Inline element storage, deliberately NOT value-initialized at run time.
 
std::size_t size_ {}
 Number of elements in use.
 

Detailed Description

template<typename T, std::size_t Cap>
class real::detail::static_vec< T, Cap >

Fixed-capacity vector backed by an inline array (no heap).

The subset of std::vector the Pike VM uses, for the static storage mode. Overflow cannot happen for the engine's own containers: static_storage sizes each one exactly via its measure pass, so the length_error guards are an unreachable structural safety net — kept deliberately, and never hit at run time (hence not covered by the runtime coverage report).

Template Parameters
TElement type.
CapInline capacity.

Constructor & Destructor Documentation

◆ static_vec()

template<typename T , std::size_t Cap>
constexpr real::detail::static_vec< T, Cap >::static_vec ( )
inlineconstexprnoexcept

Value-initializes data_ during constant evaluation only.

MSVC's constant evaluator refuses an object with an indeterminate subobject even when nothing reads it: static_regex's compile-time static_asserts failed with C2131 (expression did not evaluate to a constant) when this storage was left trivially initialized everywhere. clang and gcc accept it (C++20 P1331R2), so the runtime path — where the whole point is not paying for the clear — keeps the trivial initialization on every toolchain.

Member Function Documentation

◆ assign()

template<typename T , std::size_t Cap>
constexpr void real::detail::static_vec< T, Cap >::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.
Exceptions
std::length_errorif count exceeds the capacity Cap.

◆ back()

template<typename T , std::size_t Cap>
constexpr T & real::detail::static_vec< T, Cap >::back ( )
inlineconstexpr

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

Returns
A reference to the last element.

◆ empty()

template<typename T , std::size_t Cap>
constexpr bool real::detail::static_vec< T, Cap >::empty ( ) const
inlineconstexpr

Returns true if empty.

Returns
Whether the vector holds no elements.

◆ ensure_size()

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

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

find_iter reuses capture storage; after the first match size already equals the program slot count and the fast path overwrites every used index — a full assign of npos is dead work. Never shrinks (a multi-group path may have already sized to slot_count > 2 before a span write).

Parameters
[in]countMinimum size.
Exceptions
std::length_errorif count exceeds the capacity Cap.

◆ operator[]() [1/2]

template<typename T , std::size_t Cap>
constexpr T & real::detail::static_vec< T, Cap >::operator[] ( std::size_t  i)
inlineconstexpr

Returns reference to the element at i.

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

◆ operator[]() [2/2]

template<typename T , std::size_t Cap>
constexpr const T & real::detail::static_vec< T, Cap >::operator[] ( std::size_t  i) const
inlineconstexpr

Returns const reference to the element at i.

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

◆ push_back()

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

Appends value.

Parameters
[in]valueThe element to append.
Exceptions
std::length_errorif the capacity Cap is exceeded.

◆ size()

template<typename T , std::size_t Cap>
constexpr std::size_t real::detail::static_vec< T, Cap >::size ( ) const
inlineconstexpr

Returns the number of elements.

Returns
The element count.

Member Data Documentation

◆ data_

template<typename T , std::size_t Cap>
std::array<T, Cap> real::detail::static_vec< T, Cap >::data_
private

Inline element storage, deliberately NOT value-initialized at run time.

static_regex is stateless (sizeof 1), so a search() builds a fresh state on the stack every call, and value-initializing here zeroed the whole worst-case capacity each time – a cost the dynamic storage does not pay, since its state lives in the regex object and is reused. Nothing reads above size_, which starts at 0, so the zeros were never observed. C++20 permits the trivial default initialization even in a constant expression (P1331R2); reading an element before writing it would be diagnosed there rather than silently returning garbage.

On a short subject this is most of the cost of a search: the clear is proportional to the worst-case capacity while the work is proportional to the subject.


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