|
| | 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 regex & | operator[] (std::size_t i) const |
| | Access the compiled pattern at construction index i.
|
| |
|
| 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.
|
| |
|
|
std::vector< regex > | members_ |
| | Every compiled pattern, in construction order.
|
| |
|
flags | flags_ {flags::none} |
| | Flags shared by every member.
|
| |
|
std::optional< dfa > | fused_ |
| | 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.
|
| |
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.
| 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.
| 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.