REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
real::regex_set Class Reference

Multi-pattern set: which patterns match the subject at least once. More...

#include <regex_set.hpp>

Public Member Functions

 regex_set (std::span< const std::string_view > patterns, flags compile_flags=flags::none)
 Compiles every pattern in patterns (construction order = bitset order).
 
 regex_set (const std::string_view *patterns, std::size_t n, flags compile_flags=flags::none)
 Convenience: compile from a contiguous array of string views.
 
 regex_set (std::initializer_list< std::string_view > patterns, flags compile_flags=flags::none)
 Brace-init: regex_set{"a", "b", R"(\\d+)"} .
 
 regex_set (std::span< const std::string > patterns, flags compile_flags=flags::none)
 Compile from owning strings (e.g. std::vector<std::string>).
 
std::size_t size () const noexcept
 Number of patterns in the set (bitset length).
 
bool empty () const noexcept
 True if the set has no patterns.
 
flags compile_flags () const noexcept
 Compilation flags shared by every member.
 
bool uses_fused () const noexcept
 True when a fused single-pass DFA is active (eligible.count ≥ threshold).
 
std::size_t eligible_count () const noexcept
 How many members the fused DFA holds, or 0 when uses_fused is false.
 
bool is_match (std::string_view text, std::size_t pos=0, std::size_t endpos=npos) const
 True if any pattern matches the subject at least once.
 
std::vector< bool > matches (std::string_view text, std::size_t pos=0, std::size_t endpos=npos) const
 Which patterns match at least once (construction-order bitset).
 
std::vector< std::size_t > which (std::string_view text, std::size_t pos=0, std::size_t endpos=npos) const
 Indices of patterns that match (construction order, ascending).
 
const regexoperator[] (std::size_t i) const
 Access the compiled pattern at construction index i.
 

Static Public Attributes

static constexpr std::size_t fused_min_eligible {56}
 Eligible-member count at which the set builds a fused single-pass DFA.
 

Private Member Functions

void build_from_views (std::span< const std::string_view > patterns)
 Compiles every pattern, then splits them into the DFA-eligible subset (fused when it reaches the threshold) and the ineligible remainder each query searches individually.
 
void arm_byte_filter ()
 Classifies members into a SPARSE partition one scan can serve, and arms the filter.
 
bool is_sparse (std::size_t i) const noexcept
 One bit, no search: is member i served by the byte filter?
 
bool filter_excludes (std::string_view text, std::size_t pos, std::size_t endpos) const
 True when the filter PROVES no member it serves can match in the region.
 

Private Attributes

std::vector< regexmembers_
 Every compiled pattern, in construction order.
 
flags flags_ {flags::none}
 Flags shared by every member.
 
std::optional< dfafused_
 Present when eligible ≥ threshold.
 
std::vector< std::size_t > eligible_orig_
 fused rule k → construction index.
 
std::vector< std::size_t > ineligible_orig_
 construction indices needing search.
 
std::vector< std::uint64_t > sparse_bits_
 Bit i set when the byte filter serves member i.
 
std::array< std::uint8_t, 8 > filter_bytes_ {}
 The served members' first-byte union, in the mask load's layout.
 
std::uint8_t filter_count_ {0}
 Valid entries in filter_bytes_; 0 = filter off.
 

Static Private Attributes

static constexpr std::uint8_t filter_union_max {8}
 Widest first-byte union the byte filter carries: one 16-byte masked block's capacity.
 

Detailed Description

Multi-pattern set: which patterns match the subject at least once.

Construction compiles every pattern (same flags as regex). If any pattern is invalid or unsupported, the constructor throws regex_error — there is no silent skip. Capture groups are not reported by the set; re-run the individual regex if groups are needed.

Bitset order is the construction order: index 0 is the first pattern, etc.

Constructor & Destructor Documentation

◆ regex_set() [1/4]

real::regex_set::regex_set ( std::span< const std::string_view >  patterns,
flags  compile_flags = flags::none 
)
inlineexplicit

Compiles every pattern in patterns (construction order = bitset order).

Parameters
[in]patternsPattern texts; an empty set is allowed.
[in]compile_flagsFlags applied to every pattern (same as regex).
Exceptions
regex_errorif any pattern fails to compile.

◆ regex_set() [2/4]

real::regex_set::regex_set ( const std::string_view *  patterns,
std::size_t  n,
flags  compile_flags = flags::none 
)
inline

Convenience: compile from a contiguous array of string views.

Parameters
[in]patternsPointer to the first pattern.
[in]nPattern count.
[in]compile_flagsFlags shared by every member.

◆ regex_set() [3/4]

real::regex_set::regex_set ( std::initializer_list< std::string_view >  patterns,
flags  compile_flags = flags::none 
)
inline

Brace-init: regex_set{"a", "b", R"(\\d+)"} .

Parameters
[in]patternsThe patterns to compile.
[in]compile_flagsFlags shared by every member.

◆ regex_set() [4/4]

real::regex_set::regex_set ( std::span< const std::string >  patterns,
flags  compile_flags = flags::none 
)
inlineexplicit

Compile from owning strings (e.g. std::vector<std::string>).

Parameters
[in]patternsThe patterns to compile; only borrowed for the duration of the call.
[in]compile_flagsFlags shared by every member.

Member Function Documentation

◆ arm_byte_filter()

void real::regex_set::arm_byte_filter ( )
inlineprivate

Classifies members into a SPARSE partition one scan can serve, and arms the filter.

ZERO WORK PER CALL is the design constraint, not an optimisation. Classifying inside the walk – a lookup per member per query – charges every call, including the one an any-match walk is fastest at: the set whose first member matches immediately. No scan primitive, however fast, recovers a cost paid before it runs. Everything here happens once, in the constructor, and the walks below test one bit.

THE CLASSIFICATION IS THE ENGINE'S OWN, not a re-derivation. first_bytes_valid plus either single_first or a small_set_size of 2..8 is exactly "this pattern has at most eight possible leading bytes, enumerated". Soundness rests on the hint builder: it walks all 256 bytes of first_bytes and sets small_set ONLY when the count lands in 2..8, so in that case the array is the COMPLETE set rather than a sample – which is what makes skipping a member safe. Past eight, neither hint is set, so the member falls to the wide partition. A nullable pattern has first_bytes_valid false and is wide with no special case.

THE UNION IS CAPPED IN CONSTRUCTION ORDER. Taking narrowest-first looks better and is worse: it reorders which members the filter serves for no gain. The cap is what stops several five-byte members from combining into a twenty-byte union – dense again, one level later, which is the very gate this mechanism replaces. A member whose own leading set is wide never joins, so one \w-leading pattern in a set costs the others nothing: it keeps being walked, the ones already in the union stay.

◆ build_from_views()

void real::regex_set::build_from_views ( std::span< const std::string_view >  patterns)
inlineprivate

Compiles every pattern, then splits them into the DFA-eligible subset (fused when it reaches the threshold) and the ineligible remainder each query searches individually.

Parameters
[in]patternsThe patterns to compile, in construction order.
Exceptions
regex_errorif any pattern fails to compile.

◆ compile_flags()

flags real::regex_set::compile_flags ( ) const
inlinenoexcept

Compilation flags shared by every member.

Returns
The flag set every member was compiled with.

◆ eligible_count()

std::size_t real::regex_set::eligible_count ( ) const
inlinenoexcept

How many members the fused DFA holds, or 0 when uses_fused is false.

Below the threshold every member walks individually, so this is 0 even for patterns a DFA would have accepted.

Returns
The fused subset size, or 0.

◆ empty()

bool real::regex_set::empty ( ) const
inlinenoexcept

True if the set has no patterns.

Returns
Whether the set is empty.

◆ filter_excludes()

bool real::regex_set::filter_excludes ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos 
) const
inlineprivate

True when the filter PROVES no member it serves can match in the region.

Parameters
[in]textSubject.
[in]posStart offset, as regex::search takes it.
[in]endposRegion end, as regex::search takes it (truncates the view).
Returns
Whether every served member can be skipped.

◆ is_match()

bool real::regex_set::is_match ( std::string_view  text,
std::size_t  pos = 0,
std::size_t  endpos = npos 
) const
inline

True if any pattern matches the subject at least once.

Stops at the first matching pattern (any-match early exit). Region semantics match regex::searchendpos truncates the view; pos is the start offset (not a slice).

Parameters
[in]textSubject.
[in]posByte offset the search starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
Whether at least one pattern matches.

◆ is_sparse()

bool real::regex_set::is_sparse ( std::size_t  i) const
inlineprivatenoexcept

One bit, no search: is member i served by the byte filter?

Parameters
[in]iConstruction index of the member.
Returns
Whether the filter's union covers every byte this member can start with.

◆ matches()

std::vector< bool > real::regex_set::matches ( std::string_view  text,
std::size_t  pos = 0,
std::size_t  endpos = npos 
) const
inline

Which patterns match at least once (construction-order bitset).

Index i is true iff pattern i matched. Order is always construction order, whether the set walks members individually or through a fused scan.

Parameters
[in]textSubject.
[in]posByte offset the search starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
One bool per member, in construction order.

◆ operator[]()

const regex & real::regex_set::operator[] ( std::size_t  i) const
inline

Access the compiled pattern at construction index i.

Parameters
[in]iConstruction index.
Returns
A reference to the compiled member.
Exceptions
std::out_of_rangewhen i is past the last member.

◆ size()

std::size_t real::regex_set::size ( ) const
inlinenoexcept

Number of patterns in the set (bitset length).

Returns
The member count.

◆ uses_fused()

bool real::regex_set::uses_fused ( ) const
inlinenoexcept

True when a fused single-pass DFA is active (eligible.count ≥ threshold).

Returns
Whether the eligible members share one DFA rather than being searched individually.

◆ which()

std::vector< std::size_t > real::regex_set::which ( std::string_view  text,
std::size_t  pos = 0,
std::size_t  endpos = npos 
) const
inline

Indices of patterns that match (construction order, ascending).

Parameters
[in]textSubject.
[in]posByte offset the search starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The matching members' construction indices, ascending.

Member Data Documentation

◆ filter_union_max

constexpr std::uint8_t real::regex_set::filter_union_max {8}
staticconstexprprivate

Widest first-byte union the byte filter carries: one 16-byte masked block's capacity.

PRIVATE, unlike fused_min_eligible. That one is a contract a caller can reason about – how many eligible members it takes before a set fuses. This is the width of a scan, and nothing outside should depend on it being eight. Keep it private for a second reason: its rationale names detail:: symbols, and a public brief that links to them has nothing to anchor on in the reference page.

◆ fused_min_eligible

constexpr std::size_t real::regex_set::fused_min_eligible {56}
staticconstexpr

Eligible-member count at which the set builds a fused single-pass DFA.

A calibrated threshold: one fused automaton costs a build and a full scan; N walks cost N searches that can each stop early. Below this count every member is searched individually.


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