|
REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
|
Backend routing and format expansion for the compat layer. Not a stable API. More...
Classes | |
| struct | call_shape |
What a regex_search or regex_match call asks of REAL, its match flags included. More... | |
| struct | copied_subject |
What a regex_iterator over a non-contiguous range keeps for REAL: one copy of the range, shared by the iterator's copies, and the cursor mapping its offsets back. On the heap because the walker views it: a short string held by value would move its characters with the iterator. More... | |
| struct | end_variant |
One variant of a pattern for match_not_eol / match_not_eow: REAL's compiled rewrite, or the original's own engine when the rewrite changed nothing, or neither when REAL does not compile the rewrite (a $ or \b inside a lookaround would nest one). More... | |
| struct | end_variants |
The three variants a pattern may need: not_eol, not_eow, both. More... | |
| struct | in_place_subject |
What a regex_iterator over contiguous storage keeps of its range for REAL: nothing, REAL searches the range where it lies. More... | |
| class | lazy_std_engine |
| An engine built on first use and published once: a reader after the build takes no lock, and a copy made while another thread builds sees the finished engine or none (and then builds its own). Copyable, so the regex that holds it stays copyable. More... | |
| class | offset_cursor |
Maps offsets into a non-contiguous range's copy back to the caller's iterators by moving one iterator from the last offset mapped; std::next(first, offset) per mark would rewalk a std::list. More... | |
| class | offset_match |
A REAL match found on a suffix of the subject, seen with the subject's offsets: what the format expander and the match-results fill read (size, start, end). More... | |
Typedefs | |
| template<typename BidirIt > | |
| using | subject_for = std::conditional_t< std::contiguous_iterator< BidirIt >, in_place_subject, copied_subject< BidirIt > > |
The subject a regex_iterator over BidirIt keeps for REAL. | |
Functions | |
| bool | grammar_forces_std (regex_constants::syntax_option_type f) noexcept |
Options REAL cannot serve once translate_posix has declined: a POSIX grammar bit, and always collate and nosubs (REAL reports every group, std only group 0 under nosubs). | |
| bool | pattern_forces_std (std::string_view p) noexcept |
| Pattern text REAL accepts but reads differently from std, screened out before REAL compiles it so that the divergence is never silent. | |
| bool | std_sed_keeps_final_backslash () |
Whether the native std keeps a final lone backslash of a format_sed format, as libstdc++ and libc++ do; MS STL drops it. REAL's sed expansion follows the native std there. | |
| bool | std_dollar_zero_is_match () |
Whether the native std reads $0 in a format as the whole match, as libstdc++ and libc++ do; match_results::format follows it, being the one place REAL expands a $0 itself. | |
| template<bool Sed, typename CharT , typename Put , typename Group , typename Prefix , typename Suffix > | |
| void | expand_replacement (const CharT *first, const CharT *last, Put &&put, Group &&group, Prefix &&prefix, Suffix &&suffix) |
Expands a replacement format: the one rule set behind match_results::format and regex_replace. | |
| bool | format_forces_std (std::string_view fmt) noexcept |
Whether a replacement format holds $0, which std implementations read differently (libstdc++: the whole match; MS STL: a literal), so the replace routes to std; $$ is an escaped dollar. | |
| std::string | posix_class_ranges (std::string_view name) |
A POSIX bracket-class name to its ASCII (C-locale) range content, appended inside a [...] during ERE translation. Empty for an unknown name (the caller then falls back to std). | |
| std::optional< std::string > | translate_ecma_classes (std::string_view p, bool icase) |
Rewrites the POSIX classes an ECMAScript bracket may hold ([[:alpha:]], which [re.grammar] adds to ECMAScript) as their ASCII ranges, which REAL reads; everything else passes through unchanged. | |
| bool | translate_bracket (std::string_view p, std::size_t &i, std::string &out) |
| Translates a POSIX bracket expression, the same in BRE and ERE: a POSIX class becomes its ASCII ranges, other members pass through. | |
| bool | append_awk_escape (std::string_view p, std::size_t &i, std::string &out) |
Appends REAL's form of the awk escape at i, as the exact byte \xHH: \b is a backspace, not a word boundary; \a, \n, \t, \r, \f, \v the controls; \/ and \" literals; \ddd an octal byte, up to 0377. | |
| bool | has_empty_alternation_branch (std::string_view p) |
Whether p has an empty alternation branch ((|, |), ||, or a | at either end), which std rejects in the POSIX grammars. Conservative: a false positive costs only linear coverage, a false negative would be a silent over-accept. | |
| std::optional< std::string > | translate_ere (std::string_view p, bool awk=false) |
Translates an ERE pattern (with awk, an awk one: append_awk_escape) to REAL's syntax, or nullopt on a construct the grammars read differently: an ECMAScript shorthand, an ambiguous {, an unknown class, an empty branch (has_empty_alternation_branch). | |
| std::optional< std::string > | translate_bre (std::string_view p) |
Translates a BRE pattern to REAL's syntax, or nullopt: \(, \) and \{n\} group and quantify, a bare ( ) { } | + ? is escaped as the literal it is. Declines on a backreference, an ECMAScript escape, a non-strict \{, an unknown class, a * opening an expression, or a ^ or $ away from the pattern's ends. | |
| template<typename LineFn > | |
| std::optional< std::string > | translate_newline_alt (std::string_view p, LineFn translate_line) |
grep / egrep: each newline-separated line is translated by translate_line and the lines joined with |, the lowest precedence, so each line keeps its own anchors. A line that declines, or an empty one, declines the whole pattern. | |
| std::optional< std::string > | translate_posix (std::string_view p, regex_constants::syntax_option_type f) |
Dispatches a single POSIX grammar to its translator; nullopt for no grammar bit or several, or under collate or nosubs. | |
| real::flags | to_real (regex_constants::syntax_option_type f) noexcept |
Maps compat options to REAL's flags, always with bytes | ecma: one REAL byte per std::regex char. | |
| std::regex_constants::syntax_option_type | to_std (regex_constants::syntax_option_type f) noexcept |
| Maps compat options to std::regex syntax flags (the fallback path). | |
| template<typename Call > | |
| decltype(auto) | std_call (Call &&call) |
Runs call on the std backend and reports its errors as regex_error, the type every error of this layer has. A std::basic_regex can fail while it matches (error_complexity, error_stack), long after it was built. | |
| std::string | rewrite_end_context (std::string_view pattern, bool not_eol, bool not_eow, bool multiline) |
pattern with match_not_eol and match_not_eow written into it, so a REAL search honors them without run-time context: under not_eol a $ holds at no end of the sequence (in multiline only before a line terminator), under not_eow a \b holds at no end and a \B does. | |
| template<typename CharT , typename Traits > | |
| auto | find_real (const basic_regex< CharT, Traits > &re, std::string_view view, call_shape shape) |
The REAL call for shape over view, whose first shape.lead characters are context only: ^, \b and a lookbehind see them, and a non-multiline ^ does not hold after them ([re.matchflag]). | |
| template<typename BidirIt , typename CharT , typename Traits > | |
| bool | run_copied (BidirIt first, BidirIt last, match_results< BidirIt > &m, const basic_regex< CharT, Traits > &re, call_shape shape) |
| run_impl over a non-contiguous range on REAL: the range is copied once, searched, and every offset of the result mapped back to the caller's iterators in one forward walk. | |
| bool | real_honors (regex_constants::match_flag_type mf) noexcept |
Whether an iteration may stay on real under mf: only match_default and match_any (met by the leftmost match) qualify; a constraining bit routes it to std rather than be ignored. A single search or match honors more (call_stays_real). | |
| bool | call_stays_real (regex_constants::match_flag_type mf, bool anchored, bool longest, bool not_null_ok) noexcept |
Whether one regex_search or regex_match call can honor mf on real. | |
| template<typename CharT , typename Traits > | |
| bool | not_null_stays_real (const basic_regex< CharT, Traits > &re) noexcept |
Whether REAL honors match_not_null for re: always when the pattern cannot match empty (the flag then changes nothing); otherwise when its search is leftmost-first and its traversal REAL's (a nullable capturing group under a quantifier takes another last iteration than std's). | |
| call_shape | shape_of (regex_constants::match_flag_type mf, bool anchored, bool nullable) noexcept |
The REAL call a regex_search or regex_match with mf makes; see call_stays_real. | |
| template<typename CharT , typename Traits > | |
| const real::regex * | real_engine_for (const basic_regex< CharT, Traits > &re, regex_constants::match_flag_type mf, bool anchored) |
The REAL engine a regex_search or regex_match with mf runs on, or null for std. | |
| bool | replace_stays_real (regex_constants::match_flag_type f) noexcept |
Whether regex_replace may run on real under f: the real expanders honor format_first_only, format_no_copy, format_sed and match_any; the traversal would ignore a constraining match flag, so any routes the whole substitution to std. | |
| std::regex_constants::match_flag_type | to_std_match (regex_constants::match_flag_type f) noexcept |
Maps every compat match and format flag to std::regex_constants; a bit missing here would be silently dropped on the std path. | |
| template<bool Capture, typename BidirIt , typename CharT , typename Traits > | |
| bool | run_impl (BidirIt first, BidirIt last, std::type_identity_t< match_results< BidirIt > > *m, const basic_regex< CharT, Traits > &re, bool anchored, regex_constants::match_flag_type mf) |
Runs the backend over [first, last), filling m under Capture; a flag REAL cannot honor routes to std. | |
| template<typename RealMatch > | |
| void | append_replacement (std::string &out, const RealMatch &m, std::string_view fmt, std::string_view text, std::size_t prefix_start, bool sed) |
Appends one match's expanded replacement (expand_replacement), the prefix running from prefix_start as in std::regex_replace. A $0 never reaches here (format_forces_std routes it to std). | |
| template<typename RealMatch > | |
| void | append_replacement (std::string &out, const RealMatch &match, std::string_view fmt, std::string_view text, std::size_t &last_end, bool no_copy, bool sed) |
Appends one match's replacement: the text since the previous match (unless format_no_copy), then the expanded format. | |
| std::optional< real::regex::result_type > | nonempty_at_without_context (const real::regex &engine, std::string_view text, std::size_t at) |
The retry [re.regiter.incr] makes after the iteration's first match came out empty at at: a non-empty match starting there, searched without match_prev_avail, so \b, ^ and a lookbehind read at as the start. Later empty matches need no retry: real's own advance is the standard's. | |
Variables | |
| template<typename CharT , typename Traits > | |
| constexpr bool | real_eligible |
Whether REAL can serve this instantiation: char with default traits only, anything else is std. A compile-time gate: REAL's char-only code must be compiled out for other CharT, not skipped. | |
Backend routing and format expansion for the compat layer. Not a stable API.
|
inline |
Appends REAL's form of the awk escape at i, as the exact byte \xHH: \b is a backspace, not a word boundary; \a, \n, \t, \r, \f, \v the controls; \/ and \" literals; \ddd an octal byte, up to 0377.
| [in] | p | The pattern being translated. |
| [in,out] | i | Cursor at the backslash; advanced past the escape on success. |
| [in,out] | out | Destination the translated escape is appended to. |
false if the escape is not one awk defines. | void real::compat::detail::append_replacement | ( | std::string & | out, |
| const RealMatch & | m, | ||
| std::string_view | fmt, | ||
| std::string_view | text, | ||
| std::size_t | prefix_start, | ||
| bool | sed | ||
| ) |
Appends one match's expanded replacement (expand_replacement), the prefix running from prefix_start as in std::regex_replace. A $0 never reaches here (format_forces_std routes it to std).
| [in,out] | out | Destination the expansion is appended to. |
| [in] | m | The match whose groups the format refers to. |
| [in] | fmt | The replacement format string. |
| [in] | text | The full subject the match's offsets index into. |
| [in] | prefix_start | Where the unmatched prefix begins — the previous match's end. |
| [in] | sed | Select the format_sed rules. |
| void real::compat::detail::append_replacement | ( | std::string & | out, |
| const RealMatch & | match, | ||
| std::string_view | fmt, | ||
| std::string_view | text, | ||
| std::size_t & | last_end, | ||
| bool | no_copy, | ||
| bool | sed | ||
| ) |
Appends one match's replacement: the text since the previous match (unless format_no_copy), then the expanded format.
| RealMatch | A match with the subject's offsets. |
| [in,out] | out | The replacement being built. |
| [in] | match | The match. |
| [in] | fmt | The format. |
| [in] | text | The subject. |
| [in,out] | last_end | The previous match's end; left at this one's. |
| [in] | no_copy | format_no_copy: the text between matches is dropped. |
| [in] | sed | format_sed: the format follows sed's rules rather than ECMAScript's. |
|
inlineprivatenoexcept |
Whether one regex_search or regex_match call can honor mf on real.
Beyond what real_honors accepts, match_continuous is a match anchored at first (a POSIX leftmost-longest search has no anchored form, so it stays on std); match_prev_avail is a region search over a view starting one character earlier, under which the standard ignores match_not_bol and match_not_bow ([re.matchflag]); match_not_null needs not_null_ok; match_not_eol and match_not_eow run a rewrite of the pattern (basic_regex::end_engine), which may still decline. not_bol / not_bow alone route to std.
| [in] | mf | The match flags the caller passed. |
| [in] | anchored | A whole-sequence match (regex_match). |
| [in] | longest | The pattern searches leftmost-longest (a POSIX grammar on REAL). |
| [in] | not_null_ok | REAL honors match_not_null for this pattern (see not_null_stays_real). |
true if the call may stay on the real backend.
|
inline |
Expands a replacement format: the one rule set behind match_results::format and regex_replace.
ECMAScript rules: a dollar followed by a dollar, an ampersand, a backtick, a quote or one or two digits inserts a dollar, the match, the prefix, the suffix or that group (nothing for a group that does not exist, its digits consumed; a second digit is taken greedily, $015 being group 1 then a literal 5); any other dollar, a final one included, is itself. $0 reads as the native std reads it (std_dollar_zero_is_match). Under sed, POSIX sed's: & is the whole match, a backslash and a digit that group, a backslash and any other character that character, and a final lone backslash follows the native std (std_sed_keeps_final_backslash).
| Sed | Select the sed rules. |
| CharT | The character type. |
| [in] | first | Start of the format. |
| [in] | last | One past its end. |
| [in] | put | Writes one character. |
| [in] | group | Writes group g (nothing when it does not exist or took no part). |
| [in] | prefix | Writes the text before the match. |
| [in] | suffix | Writes the text after it. |
|
private |
The REAL call for shape over view, whose first shape.lead characters are context only: ^, \b and a lookbehind see them, and a non-multiline ^ does not hold after them ([re.matchflag]).
| [in] | re | The pattern; real-backed. |
| [in] | view | The sequence, behind its context. |
| [in] | shape | The call. |
view.
|
inlinenoexcept |
Whether a replacement format holds $0, which std implementations read differently (libstdc++: the whole match; MS STL: a literal), so the replace routes to std; $$ is an escaped dollar.
| [in] | fmt | The replacement format. |
true if it holds a construct whose meaning is platform-variant, so the replace routes to std.
|
inlinenoexcept |
Options REAL cannot serve once translate_posix has declined: a POSIX grammar bit, and always collate and nosubs (REAL reports every group, std only group 0 under nosubs).
| [in] | f | The syntax options requested. |
true if, translation having declined, these options cannot be served by REAL.
|
inline |
Whether p has an empty alternation branch ((|, |), ||, or a | at either end), which std rejects in the POSIX grammars. Conservative: a false positive costs only linear coverage, a false negative would be a silent over-accept.
| [in] | p | The pattern text. |
true if a branch is empty, so the translation declines.
|
inline |
The retry [re.regiter.incr] makes after the iteration's first match came out empty at at: a non-empty match starting there, searched without match_prev_avail, so \b, ^ and a lookbehind read at as the start. Later empty matches need no retry: real's own advance is the standard's.
| [in] | engine | The pattern. |
| [in] | text | The subject. |
| [in] | at | Where the empty match was. |
text.substr(at), offsets relative to at; empty when there is none.
|
privatenoexcept |
Whether REAL honors match_not_null for re: always when the pattern cannot match empty (the flag then changes nothing); otherwise when its search is leftmost-first and its traversal REAL's (a nullable capturing group under a quantifier takes another last iteration than std's).
| [in] | re | The pattern; real-backed. |
true if a call under match_not_null may stay on REAL.
|
inlinenoexcept |
Pattern text REAL accepts but reads differently from std, screened out before REAL compiles it so that the divergence is never silent.
\0 and a digit: REAL reads a legacy octal escape (\012 is a newline), libstdc++ a NUL then the digit. \C: RE2's one-byte escape, reachable only through this layer's flags::bytes; not ECMAScript. An inline-flags group ((?i), (?-s:...)): REAL honors it, std rejects it. Over-matching is safe.
| [in] | p | The pattern text. |
true if it holds a construct only the std backend can serve.
|
inline |
A POSIX bracket-class name to its ASCII (C-locale) range content, appended inside a [...] during ERE translation. Empty for an unknown name (the caller then falls back to std).
| [in] | name | A POSIX class name without its brackets, e.g. alpha. |
|
private |
The REAL engine a regex_search or regex_match with mf runs on, or null for std.
| [in] | re | The pattern. |
| [in] | mf | The match flags. |
| [in] | anchored | A whole-sequence match (regex_match). |
not_eol / not_eow variant, or null.
|
inlineprivatenoexcept |
Whether an iteration may stay on real under mf: only match_default and match_any (met by the leftmost match) qualify; a constraining bit routes it to std rather than be ignored. A single search or match honors more (call_stays_real).
| [in] | mf | The match flags the caller passed. |
true if the iteration may stay on REAL.
|
inlineprivatenoexcept |
Whether regex_replace may run on real under f: the real expanders honor format_first_only, format_no_copy, format_sed and match_any; the traversal would ignore a constraining match flag, so any routes the whole substitution to std.
| [in] | f | The match/format flags the caller passed to regex_replace. |
true if the real expander honors all of them, so the replace may stay on the real backend.
|
inline |
pattern with match_not_eol and match_not_eow written into it, so a REAL search honors them without run-time context: under not_eol a $ holds at no end of the sequence (in multiline only before a line terminator), under not_eow a \b holds at no end and a \B does.
| [in] | pattern | An ECMAScript pattern as REAL compiles it. |
| [in] | not_eol | Rewrite $. |
| [in] | not_eow | Rewrite \b and \B. |
| [in] | multiline | The pattern is multiline. |
|
private |
run_impl over a non-contiguous range on REAL: the range is copied once, searched, and every offset of the result mapped back to the caller's iterators in one forward walk.
| [in] | first | Start of the sequence. |
| [in] | last | One past its end. |
| [out] | m | Result; reset over [first, last) by the caller. |
| [in] | re | The pattern; real-backed. |
| [in] | shape | The call; under match_prev_avail the copy starts at --first. |
true if a match was found and m filled.
|
private |
Runs the backend over [first, last), filling m under Capture; a flag REAL cannot honor routes to std.
| Capture | Fill m (regex_search / regex_match with results); without it no result is built. |
| [in] | first | Start of the sequence to run over. |
| [in] | last | One past its end. |
| [out] | m | Under Capture, filled on success and left ready-but-unmatched on failure; else unused (null). |
| [in] | re | The pattern, whose backend decides which engine runs. |
| [in] | anchored | Whole-sequence match (regex_match) rather than leftmost search. |
| [in] | mf | Match flags (call_stays_real). |
true if a match was found.
|
inlineprivatenoexcept |
The REAL call a regex_search or regex_match with mf makes; see call_stays_real.
| [in] | mf | The match flags, which call_stays_real accepted. |
| [in] | anchored | A whole-sequence match (regex_match). |
| [in] | nullable | The pattern can match empty, so match_not_null changes what it finds. |
| decltype(auto) real::compat::detail::std_call | ( | Call && | call | ) |
Runs call on the std backend and reports its errors as regex_error, the type every error of this layer has. A std::basic_regex can fail while it matches (error_complexity, error_stack), long after it was built.
| Call | A callable taking no argument. |
| [in] | call | The std operation. |
call returns. | real::compat::regex_error | when call throws a std::regex_error. |
|
inline |
Whether the native std reads $0 in a format as the whole match, as libstdc++ and libc++ do; match_results::format follows it, being the one place REAL expands a $0 itself.
true when std::regex_replace("a", regex("a"), "$0") gives back "a"; asked once.
|
inline |
Whether the native std keeps a final lone backslash of a format_sed format, as libstdc++ and libc++ do; MS STL drops it. REAL's sed expansion follows the native std there.
true when std::regex_replace("a", regex("a"), "\\", format_sed) gives back a backslash; asked once.
|
inlinenoexcept |
Maps compat options to REAL's flags, always with bytes | ecma: one REAL byte per std::regex char.
| [in] | f | The compat syntax options. |
|
inlinenoexcept |
Maps compat options to std::regex syntax flags (the fallback path).
| [in] | f | The compat syntax options. |
std::regex_constants::syntax_option_type.
|
inlineprivatenoexcept |
Maps every compat match and format flag to std::regex_constants; a bit missing here would be silently dropped on the std path.
| [in] | f | The compat flags to translate. |
std::regex_constants::match_flag_type.
|
inline |
Translates a POSIX bracket expression, the same in BRE and ERE: a POSIX class becomes its ASCII ranges, other members pass through.
| [in] | p | The pattern being translated. |
| [in,out] | i | Cursor at the opening bracket; advanced past the expression on success. |
| [in,out] | out | Destination the translated bracket is appended to. |
false on an unterminated expression, an unknown class or a collating element; out is then unchanged.
|
inline |
Translates a BRE pattern to REAL's syntax, or nullopt: \(, \) and \{n\} group and quantify, a bare ( ) { } | + ? is escaped as the literal it is. Declines on a backreference, an ECMAScript escape, a non-strict \{, an unknown class, a * opening an expression, or a ^ or $ away from the pattern's ends.
| [in] | p | The BRE pattern. |
std::nullopt when it cannot be translated.
|
inline |
Rewrites the POSIX classes an ECMAScript bracket may hold ([[:alpha:]], which [re.grammar] adds to ECMAScript) as their ASCII ranges, which REAL reads; everything else passes through unchanged.
| [in] | p | The ECMAScript pattern. |
| [in] | icase | Whether the pattern is case-insensitive: std then tests a class against the folded character, which ranges folded by REAL do not reproduce for [:lower:] or [:upper:]. |
std::nullopt when only std reads it as written: a class under icase, an unknown class name, a collating element [.x.] or an equivalence class [=x=], whose reading the implementations do not share (libstdc++ puts A in [=a=] and rejects [.-.]).
|
inline |
Translates an ERE pattern (with awk, an awk one: append_awk_escape) to REAL's syntax, or nullopt on a construct the grammars read differently: an ECMAScript shorthand, an ambiguous {, an unknown class, an empty branch (has_empty_alternation_branch).
| [in] | p | The ERE pattern. |
| [in] | awk | Whether awk's extra escapes are in scope. |
std::nullopt when the pattern cannot be translated.
|
inline |
grep / egrep: each newline-separated line is translated by translate_line and the lines joined with |, the lowest precedence, so each line keeps its own anchors. A line that declines, or an empty one, declines the whole pattern.
| [in] | p | The pattern, whose newlines separate alternatives (grep/egrep). |
| [in] | translate_line | Applied to each line; its std::nullopt fails the whole translation. |
std::nullopt if any line failed.
|
inline |
Dispatches a single POSIX grammar to its translator; nullopt for no grammar bit or several, or under collate or nosubs.
| [in] | p | The pattern text. |
| [in] | f | The syntax options, which select the POSIX grammar to translate from. |
std::nullopt when the options or pattern decline.
|
inlineconstexpr |
Whether REAL can serve this instantiation: char with default traits only, anything else is std. A compile-time gate: REAL's char-only code must be compiled out for other CharT, not skipped.