REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
real::detail::range_intern_table Struct Reference

Intern table for UTF-8 edge byte ranges, keyed by the exact 16-bit (lo << 8) | hi. More...

#include <lazy_dfa.hpp>

Public Member Functions

constexpr std::uint16_t find (std::uint16_t key) const noexcept
 Returns the interned class index for key, or absent.
 
constexpr void insert (std::uint16_t key, std::uint16_t idx)
 Records idx for key, doubling the table first when it would pass half load.
 

Static Public Member Functions

static constexpr std::size_t bucket (std::uint16_t key, std::size_t mask) noexcept
 Probe start for key: Fibonacci hashing — the key times 2^64/phi, keeping the high bits.
 

Public Attributes

std::vector< std::uint32_t > slots {std::vector<std::uint32_t>(1024U, 0U)}
 Power of two; 1024 covers the ~476 ranges a \w-heavy program interns without a rehash.
 
std::size_t count {0}
 Occupied slots, for the load factor.
 

Static Public Attributes

static constexpr std::uint16_t absent {0xFFFFU}
 find's miss answer (never a valid index: it would be slot 0x10000).
 

Detailed Description

Intern table for UTF-8 edge byte ranges, keyed by the exact 16-bit (lo << 8) | hi.

An open-addressed probe table over a flat buffer rather than std::unordered_map, because this builder must also run inside a constant expression: static_storage builds its byte program at compile time, and no node-based standard container is constexpr-constructible before C++23.

A slot holds (key << 16) | (index + 1), so a zero slot means empty and the range 0x00..0x00 stays a legal key. The table grows at half load rather than capping, so a pattern with many distinct Unicode classes degrades in speed and never in correctness — a fixed capacity would either fill and spin or silently stop interning.

Member Function Documentation

◆ bucket()

static constexpr std::size_t real::detail::range_intern_table::bucket ( std::uint16_t  key,
std::size_t  mask 
)
inlinestaticconstexprnoexcept

Probe start for key: Fibonacci hashing — the key times 2^64/phi, keeping the high bits.

The keys cluster hard and arrive in near-runs (lo walks a trie node's disjoint ranges in order, and the continuation range 0x80..0xBF sits on nearly every node), so the stride between consecutive keys is what decides whether the table is used or a quarter of it is. Taking the high bits of the 64-bit product gives a stride coprime with the table size; the 32-bit constant shifted by a fixed amount does not — its stride shares a factor of 4 with 1024, so three of every four buckets would be unreachable for a run of keys and the reachable quarter would be over 100% loaded at the half-load rehash point. Wrapping is intended (it is the modular multiply).

Parameters
[in]keyThe 16-bit packed byte range.
[in]maskslots.size() - 1, the table being a power of two.
Returns
The first bucket to probe.

◆ find()

constexpr std::uint16_t real::detail::range_intern_table::find ( std::uint16_t  key) const
inlineconstexprnoexcept

Returns the interned class index for key, or absent.

Parameters
[in]keyThe 16-bit packed byte range.
Returns
The class index recorded for key, or absent when it was never interned.

◆ insert()

constexpr void real::detail::range_intern_table::insert ( std::uint16_t  key,
std::uint16_t  idx 
)
inlineconstexpr

Records idx for key, doubling the table first when it would pass half load.

Parameters
[in]keyThe 16-bit packed byte range.
[in]idxThe class index to record for it.

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