REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
real::detail::basic_capture_pool< DataVec, RefVec, FreeVec > Struct Template Reference

Copy-on-write pool of capture blocks (COW) — the one capture-slot mechanism for both storages. More...

#include <pike.hpp>

Public Member Functions

constexpr void reset (std::uint16_t slot_count)
 Reset for a new match run: block 0 = all-npos, held by a permanent sentinel ref.
 
constexpr std::size_t * slots (std::uint32_t b)
 Pointer to block b's width slots. Invalidated by any allocate that grows data.
 
constexpr std::uint32_t allocate ()
 A fresh block with refcount 1 (a recycled index if available, else a grown one).
 
constexpr void incref (std::uint32_t b)
 Take a reference on block b (each closure seeded into the next list holds its own).
 
constexpr void decref (std::uint32_t b)
 Drop a reference on block b, recycling it into the free list at zero.
 
constexpr std::uint32_t cow_write (std::uint32_t b, std::uint16_t slot, std::size_t value)
 Write slots(b)[slot] = value, detaching first if b is shared. The one place a block mutates.
 
constexpr long long total_refs () const
 Sum of all live refcounts — the debug Σ-invariant checks this equals the references the VM actually holds (list blocks + stack frames), catching a leaked or double-freed block.
 

Public Attributes

DataVec data
 Flat slot storage: block b's slots at [b*width, b*width+width).
 
RefVec refcount
 Live references per block (non-atomic — the VM is single-threaded).
 
FreeVec free_list
 Recycled block indices (refcount hit 0).
 
std::uint16_t width {0}
 slot_count (values per block).
 

Static Public Attributes

static constexpr std::uint32_t npos_block {0}
 Canonical all-npos block, shared by every seed.
 

Detailed Description

template<typename DataVec, typename RefVec, typename FreeVec>
struct real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >

Copy-on-write pool of capture blocks (COW) — the one capture-slot mechanism for both storages.

A per-thread value model would snapshot all slot_count capture values every time a thread is stepped or emitted — a fifth to a third of match time on capture-heavy loads. Instead, a thread references a block by index; forks (split) share a block (refcount++), and a save — the ONE write — detaches it first if shared (cow_write). No value-journal, no per-thread copy.

Block 0 is the canonical all-npos block: every seed shares it (a permanent sentinel ref keeps it alive), so seeding a position costs one incref, not an allocation — the first save COWs off it. The pool is trivially-copyable indices with a free list; no RAII handles (they would run destructors in the SBO / static thread lists, which run none — the reserve the review named).

Member Function Documentation

◆ allocate()

template<typename DataVec , typename RefVec , typename FreeVec >
constexpr std::uint32_t real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >::allocate ( )
inlineconstexpr

A fresh block with refcount 1 (a recycled index if available, else a grown one).

Returns
Index of the new block; its slots hold whatever the recycled block last held.

◆ cow_write()

template<typename DataVec , typename RefVec , typename FreeVec >
constexpr std::uint32_t real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >::cow_write ( std::uint32_t  b,
std::uint16_t  slot,
std::size_t  value 
)
inlineconstexpr

Write slots(b)[slot] = value, detaching first if b is shared. The one place a block mutates.

Parameters
[in]bBlock to write through.
[in]slotSlot index within the block.
[in]valueValue to store.
Returns
The block that now holds the write: a fresh private copy when b was shared, else b.

◆ decref()

template<typename DataVec , typename RefVec , typename FreeVec >
constexpr void real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >::decref ( std::uint32_t  b)
inlineconstexpr

Drop a reference on block b, recycling it into the free list at zero.

Parameters
[in]bBlock index.

◆ incref()

template<typename DataVec , typename RefVec , typename FreeVec >
constexpr void real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >::incref ( std::uint32_t  b)
inlineconstexpr

Take a reference on block b (each closure seeded into the next list holds its own).

Parameters
[in]bBlock index.

◆ reset()

template<typename DataVec , typename RefVec , typename FreeVec >
constexpr void real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >::reset ( std::uint16_t  slot_count)
inlineconstexpr

Reset for a new match run: block 0 = all-npos, held by a permanent sentinel ref.

The storage grows by allocate (heap for dynamic; a compile-sized static_vec for static, whose capacity bounds the live-block count and so is never exceeded).

Parameters
[in]slot_countSlots per block, i.e. the program's capture-slot count.

◆ slots()

template<typename DataVec , typename RefVec , typename FreeVec >
constexpr std::size_t * real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >::slots ( std::uint32_t  b)
inlineconstexpr

Pointer to block b's width slots. Invalidated by any allocate that grows data.

Parameters
[in]bBlock index.
Returns
Pointer to the block's first slot.

◆ total_refs()

template<typename DataVec , typename RefVec , typename FreeVec >
constexpr long long real::detail::basic_capture_pool< DataVec, RefVec, FreeVec >::total_refs ( ) const
inlineconstexpr

Sum of all live refcounts — the debug Σ-invariant checks this equals the references the VM actually holds (list blocks + stack frames), catching a leaked or double-freed block.

Returns
The sum, including the sentinel block's permanent reference.

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