|
REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
|
Search acceleration: pattern analysis and candidate-finding. More...
#include "real/version.hpp"#include "real/core/config.hpp"#include <algorithm>#include <cstdint>#include <cstring>#include <limits>#include <span>#include <string_view>#include <type_traits>#include <vector>#include "real/core/charclass.hpp"#include "real/core/program.hpp"#include "real/engine/simd.hpp"#include "real/unicode/unicode_props.hpp"#include <array>#include <atomic>Classes | |
| struct | real::detail::shape_lead |
A fixed shape's lead: save 0, an optional \A/^, an optional \b/\B. More... | |
| struct | real::detail::shape_close |
The shape_lead counterpart: optional trail \b/\B, optional \Z/$, then exactly save 1, match ending the program. More... | |
| struct | real::detail::literal_density |
| What the adaptive literal search learned about one subject: whether the needle's rarest byte is common there. More... | |
| struct | real::detail::literal_memo |
The two literal densities of one subject, held in a std::optional built at the first literal search, so constructing a search state (every search does) writes no densities. More... | |
| struct | real::detail::alternation_pairs |
| Two probe bytes per branch of a literal alternation: the branch's first byte and one byte further in it, for the pair filter an alternation's block scan turns to once the first bytes prove common. More... | |
| struct | real::detail::alternation_density |
| Whether an alternation's first bytes are dense in one subject, decided once from a sample of it. More... | |
Namespaces | |
| namespace | real |
| REAL's public API: real::regex, real::static_regex, real::flags and the match/iterator types built on them. | |
| namespace | real::detail |
| DFA construction internals: subset construction over a flattened NFA. Not a stable API. | |
Functions | |
| std::atomic< std::uint64_t > & | real::detail::tally (counter c) noexcept |
| The value of a test counter, to read or to reset. | |
| constexpr void | real::detail::note (counter c, std::uint64_t n=1) noexcept |
Bills n to a test counter. A no-op unless the test binary defines REAL_TEST_INSTRUMENT. | |
| bool & | real::detail::alternation_avx2_disabled () |
| Test seam: keep the alternation fingerprint on 16-byte blocks where the CPU has AVX2, so a differential can compare both widths in one binary. Not for production use. | |
| bool & | real::detail::literal_avx2_disabled () |
| Test seam: keep the literal filter on 16-byte blocks where the CPU has AVX2, so a differential can compare both widths in one binary. Not for production use. | |
| constexpr bool | real::detail::is_word_boundary_kind (assert_kind kind) noexcept |
True if kind is \b or \B (the only position asserts a fast path wraps). | |
| constexpr std::uint8_t | real::detail::wb_hint_of (assert_kind kind) noexcept |
Encodes kind as a wb_lead/wb_trail hint value (1 = \b, 2 = \B); 0 if not a word boundary. | |
| constexpr bool | real::detail::peel_optional_wb (std::span< const instr > code, std::size_t &p, std::uint8_t &hint) noexcept |
Peels an optional \b/\B assertion at p, lead or trail alike. | |
| constexpr shape_lead | real::detail::parse_shape_lead (std::span< const instr > code) noexcept |
Peels a fixed shape's save 0 and its optional lead \b/\B. | |
| constexpr shape_close | real::detail::parse_shape_close (std::span< const instr > code, std::size_t from) noexcept |
Peels a fixed shape's optional trail \b/\B, then its save 1 and match. | |
| constexpr bool | real::detail::is_full_ascii_word_class (const char_class &cls) noexcept |
True if cls is exactly the ASCII word set [0-9A-Za-z_] (\w under bytes/re.A). | |
| constexpr bool | real::detail::is_ascii_word_subset_class (const char_class &cls) noexcept |
True if every member of cls is an ASCII word byte (subset of \w under bytes/re.A). | |
| constexpr bool | real::detail::is_full_unicode_word_cp_class (const cp_class &cc, std::span< const code_range > all_ranges) noexcept |
True if cc is exactly the canonical Unicode \w class (not a user superset). | |
| constexpr bool | real::detail::wb_redundant_for_full_word (std::uint8_t lead, std::uint8_t trail) noexcept |
The DROP rule: \b next to a full-\w maximal run is redundant (\B never is). | |
| constexpr bool | real::detail::resolve_class_wb_hints (bool full_word, bool word_sub, bool maximal_run, std::uint8_t lead, std::uint8_t trail, std::uint8_t &out_lead, std::uint8_t &out_trail) noexcept |
DROP / WRAP policy for class / cp-class loops under optional \b/\B wraps. | |
| constexpr bool | real::detail::word_ranges_cover_interval_from (char32_t lo, char32_t hi, std::size_t &cursor) noexcept |
True if every code point in [lo, hi] is a Unicode word char (word_ranges), resuming the scan at cursor and leaving it past the last range consulted. | |
| constexpr bool | real::detail::word_ranges_cover_interval (char32_t lo, char32_t hi) noexcept |
True if every code point in [lo, hi] is a Unicode word char (covered by word_ranges). Standalone form of word_ranges_cover_interval_from. | |
| constexpr bool | real::detail::is_unicode_word_subset_cp_class (const cp_class &cc, std::span< const code_range > all_ranges) noexcept |
True if cc is a non-empty subset of Unicode \w (safe for maximal-run + \b wrap). | |
| constexpr bool | real::detail::cp_class_may_contain_ascii_byte (const cp_class &cc, std::uint8_t b) noexcept |
Whether byte b could be a member of cc; a delimiter that could hide in a possessive code-point loop makes the delimited fast path decline (pattern_hints::possessive_prefix). | |
| constexpr bool | real::detail::is_fixed_alternation (std::span< const instr > code, std::uint8_t *out_wb_lead=nullptr, std::uint8_t *out_wb_trail=nullptr, std::uint8_t *out_body_pc=nullptr, std::int32_t *out_branch_count=nullptr) |
Alternation of straight-line byte/klass branches, optionally wrapped in \b/\B. | |
| constexpr void | real::detail::extract_anchoring (std::span< const instr > code, pattern_hints &hints) |
Records start anchoring: the first non-save instruction tells whether every match must begin at position 0 (\A/^ non-multiline) or at a line start. | |
| constexpr void | real::detail::extract_prefix (std::span< const instr > code, pattern_hints &hints) |
| Collects the required literal prefix and the exact-literal fast-path length. | |
| constexpr void | real::detail::compute_first_bytes (std::span< const instr > code, std::span< const char_class > classes, std::span< const cp_class > cp_classes, pattern_hints &hints) |
| Computes the possible first-byte set by a DFS over the epsilon closure of pc 0. | |
| constexpr int | real::detail::class_range_count (const char_class &klass, std::uint8_t &lo0, std::uint8_t &hi0, std::uint8_t &lo1, std::uint8_t &hi1) |
Reports klass as up to two contiguous byte ranges. | |
| REAL_BUILD_COLD constexpr void | real::detail::detect_fast_shapes (std::span< const instr > code, std::span< const char_class > classes, std::span< const cp_class > cp_classes, std::span< const code_range > cp_ranges, std::int32_t cp_mark_ascii, std::int32_t cp_mark_offset, std::int32_t cp_mark_end, std::span< const lookaround_sub > lookarounds, pattern_hints &hints) |
Detects the whole-pattern fast-path shapes and sets their hint flags: class+, fixed-shape straight runs, a single codepoint class (./negated, optional +), an alternation of straight-line branches, and trailing-lookaround class+. | |
| constexpr std::uint16_t | real::detail::byte_frequency (std::uint8_t b) |
Approximate static frequency of a byte in mixed English and source text, per 10000, used only to rank candidate prefilter bytes: a rare required byte (-, @) is a far more selective memchr target than a common first-byte class. | |
| constexpr std::uint8_t | real::detail::literal_rarest_offset (std::string_view literal) |
Offset of the rarest byte of literal by byte_frequency (the first of equals). | |
| constexpr void | real::detail::extract_rare_byte (std::span< const instr > code, pattern_hints &hints) |
Records a required literal byte at a FIXED offset far rarer than the first-byte set (pattern_hints::rare_byte / rare_offset), so the search can memchr that one byte. | |
| constexpr void | real::detail::extract_rare_discriminant (std::span< const instr > code, pattern_hints &hints) |
Arms the rare-discriminant prefilter for shapes like https?://…: fixed prefix (http) + optional mono-byte (s?) + fixed mid with a rare disc (://). | |
| constexpr bool | real::detail::capture_free_walk_structural (std::span< const instr > code) noexcept |
The structural half of pattern_hints::capture_free_walk, that save 0 is the program's first instruction. | |
| constexpr pattern_hints | real::detail::analyze_program (std::span< const instr > code, std::span< const char_class > classes, std::span< const cp_class > cp_classes, std::span< const code_range > cp_ranges, std::int32_t cp_mark_ascii, std::int32_t cp_mark_offset, std::int32_t cp_mark_end, std::span< const lookaround_sub > lookarounds={}) |
| Walks a compiled program once to derive its search hints. | |
| constexpr bool | real::detail::fixed_shape_walk_pays (std::span< const instr > code, const pattern_hints &hints) noexcept |
| Whether a search over this fixed shape (pattern_hints::fixed_shape) should walk each candidate start rather than run the lazy DFA. | |
| constexpr std::size_t | real::detail::find_byte (std::string_view text, std::size_t pos, char byte) |
Index of byte in text[pos..), or real::npos. | |
| constexpr std::size_t | real::detail::find_rare_disc_candidate (std::string_view text, std::size_t pos, const pattern_hints &hints, bool *density_abandon=nullptr) |
| Next candidate start for the rare-discriminant prefilter, or real::npos. | |
| constexpr void | real::detail::store_literal_density (literal_density &density, std::uint32_t cands, std::size_t origin, std::size_t next) noexcept |
| Writes the adaptive search's local density back (find_literal_adaptive_rest keeps it in locals while it scans). | |
| std::size_t | real::detail::find_literal_adaptive_rest (std::string_view text, std::size_t pos, std::string_view literal, std::size_t rare, literal_density &density) |
| The body of find_literal_adaptive past its first stop: the pair filter for a dense subject, else the rarest-byte scan that counts its stops and judges their density. | |
| std::size_t | real::detail::find_literal_adaptive (std::string_view text, std::size_t pos, std::string_view literal, std::size_t rare, literal_density &density) |
Index of the first occurrence of literal in text[pos..), or real::npos, by its rarest byte while that byte is rare in the subject and by the two-byte block filter once it is not. | |
| bool | real::detail::alternation_nibbles_supported () |
| Whether the nibble fingerprint can run here: AArch64 always, x86 when the build enables SSSE3 or, with gcc or clang, when the running CPU has it. A plan built elsewhere never claims one: the fingerprint's reach is shorter than the pairs', and a scan that bounded its blocks by it while masking by the pairs would read past the subject. | |
| constexpr std::size_t | real::detail::find_literal (std::string_view text, std::size_t pos, std::string_view literal) |
Index of the first occurrence of literal in text[pos..), or real::npos. | |
| constexpr std::size_t | real::detail::find_prefix (std::string_view text, std::size_t pos, std::string_view prefix) |
First position >= pos where prefix occurs in text, or npos; the dispatch of find_literal. | |
| std::size_t | real::detail::find_members (std::string_view text, std::size_t pos, const std::array< std::uint8_t, 8 > &mem, std::uint8_t n) |
Least index at or after pos whose byte is one of n members, in ONE pass. | |
| std::size_t | real::detail::find_folded_literal (std::string_view text, std::size_t pos, std::string_view lit, std::uint16_t folded, std::size_t rare) |
The first occurrence at or after pos of a literal some of whose letters match in either case. | |
| constexpr std::size_t | real::detail::find_line_end_cr (std::string_view text, std::size_t pos) |
Where an ECMAScript line ends: the index of the first \n or \r in text[pos..), or real::npos. | |
| constexpr std::size_t | real::detail::find_bytes_cascade (std::string_view text, std::size_t pos, const char *set, std::uint8_t n) |
Index of the first byte in text[pos..) that belongs to a small first-byte set. | |
| constexpr std::size_t | real::detail::first_high_byte (std::string_view text, std::size_t pos, std::size_t end) |
Index of the first byte >= 0x80 in text[pos, end), or end if the range is pure ASCII. | |
Variables | |
| constexpr std::size_t | real::detail::fixed_shape_walk_max_width {8} |
| Widest unfiltered shape kept on the walk. | |
| constexpr std::uint32_t | real::detail::rare_disc_fail_abandon {32} |
Consecutive disc hits that fail back-verify before the density gate trips. Dense : filler (e.g. a:b:c:d…) makes memchr+verify lose to a selective http prefix. | |
| constexpr std::uint32_t | real::detail::literal_dense_min_cands {8} |
| Stops the rarest-byte scan makes before its density is judged: fewer say nothing. | |
| constexpr std::size_t | real::detail::literal_dense_gap {64} |
| Mean bytes between stops below which the rarest byte counts as common: under it, a stop costs more than the pair filter spends crossing that many bytes. | |
| constexpr std::size_t | real::detail::alternation_nibbles_min_branches {3} |
| Fewest branches for which the fingerprint replaces the pairs. Two pairs are two compares a block, a fingerprint six table lookups: on x86 (SSSE3) two branches lose by the fingerprint and three break even; AArch64's lookups are cheap enough that two branches already gain. | |
| constexpr std::size_t | real::detail::alternation_sample_min {4096} |
| Shorter rests are scanned by the first bytes, unsampled (at least the sample and its reach). | |
| constexpr std::size_t | real::detail::alternation_sample_bytes {512} |
| Bytes sampled for the first bytes' density. | |
| constexpr std::size_t | real::detail::alternation_wide_min_branches {2} |
| Fewest branches the wide route considers: branches that open on classes outgrow the small set with a few. | |
| constexpr std::size_t | real::detail::alternation_wide_max_branches {16} |
| Most branches the fingerprint's plan holds. | |
| constexpr std::size_t | real::detail::alternation_wide_false_budget {256} |
| Past this many false candidates times branches in a sample, the automaton scans cheaper than the fingerprint and its verifier. | |
| constexpr std::size_t | real::detail::alternation_dense_gap {32} |
| Mean bytes between first-byte hits in the sample below which the pair filter takes over (both ISAs: where the first-byte scan and the pair filter crossed on 500 KB of log lines). | |
| constexpr std::size_t | real::detail::alternation_dense_gap_nibbles {128} |
| The same threshold for a plan masking by the nibble fingerprint, whose cost per block is fixed: it crossed the first-byte loop at 256-512 bytes between false stops (arm64, x86-64 AVX2, 3 to 10 branches); at 128 its worst ratio was 0.77 of the loop's time. | |
| constexpr bool | real::detail::have_members_scan {false} |
| Whether a consumer should ARM a filter on find_members (one ISA only, measured). | |
Search acceleration: pattern analysis and candidate-finding.
Extracts real::detail::pattern_hints from a compiled program (literal prefix, start anchoring, first-byte set, fast-path shapes) and provides the skip-ahead primitives used when no thread is alive: memchr / the platform substring search at run time, plain loops in constexpr. Hints change only speed, never what matches; an equivalence test runs the engine with hints disabled.