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

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.
 

Detailed Description

Backend routing and format expansion for the compat layer. Not a stable API.

Function Documentation

◆ append_awk_escape()

bool real::compat::detail::append_awk_escape ( std::string_view  p,
std::size_t &  i,
std::string &  out 
)
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.

Parameters
[in]pThe pattern being translated.
[in,out]iCursor at the backslash; advanced past the escape on success.
[in,out]outDestination the translated escape is appended to.
Returns
false if the escape is not one awk defines.

◆ append_replacement() [1/2]

template<typename RealMatch >
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).

Parameters
[in,out]outDestination the expansion is appended to.
[in]mThe match whose groups the format refers to.
[in]fmtThe replacement format string.
[in]textThe full subject the match's offsets index into.
[in]prefix_startWhere the unmatched prefix begins — the previous match's end.
[in]sedSelect the format_sed rules.

◆ append_replacement() [2/2]

template<typename RealMatch >
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.

Template Parameters
RealMatchA match with the subject's offsets.
Parameters
[in,out]outThe replacement being built.
[in]matchThe match.
[in]fmtThe format.
[in]textThe subject.
[in,out]last_endThe previous match's end; left at this one's.
[in]no_copyformat_no_copy: the text between matches is dropped.
[in]sedformat_sed: the format follows sed's rules rather than ECMAScript's.

◆ call_stays_real()

bool real::compat::detail::call_stays_real ( regex_constants::match_flag_type  mf,
bool  anchored,
bool  longest,
bool  not_null_ok 
)
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.

Parameters
[in]mfThe match flags the caller passed.
[in]anchoredA whole-sequence match (regex_match).
[in]longestThe pattern searches leftmost-longest (a POSIX grammar on REAL).
[in]not_null_okREAL honors match_not_null for this pattern (see not_null_stays_real).
Returns
true if the call may stay on the real backend.

◆ expand_replacement()

template<bool Sed, typename CharT , typename Put , typename Group , typename Prefix , typename Suffix >
void real::compat::detail::expand_replacement ( const CharT *  first,
const CharT *  last,
Put &&  put,
Group &&  group,
Prefix &&  prefix,
Suffix &&  suffix 
)
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).

Template Parameters
SedSelect the sed rules.
CharTThe character type.
Parameters
[in]firstStart of the format.
[in]lastOne past its end.
[in]putWrites one character.
[in]groupWrites group g (nothing when it does not exist or took no part).
[in]prefixWrites the text before the match.
[in]suffixWrites the text after it.

◆ find_real()

template<typename CharT , typename Traits >
auto real::compat::detail::find_real ( const basic_regex< CharT, Traits > &  re,
std::string_view  view,
call_shape  shape 
)
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]).

Parameters
[in]reThe pattern; real-backed.
[in]viewThe sequence, behind its context.
[in]shapeThe call.
Returns
The engine's result, offsets into view.

◆ format_forces_std()

bool real::compat::detail::format_forces_std ( std::string_view  fmt)
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.

Parameters
[in]fmtThe replacement format.
Returns
true if it holds a construct whose meaning is platform-variant, so the replace routes to std.

◆ grammar_forces_std()

bool real::compat::detail::grammar_forces_std ( regex_constants::syntax_option_type  f)
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).

Parameters
[in]fThe syntax options requested.
Returns
true if, translation having declined, these options cannot be served by REAL.

◆ has_empty_alternation_branch()

bool real::compat::detail::has_empty_alternation_branch ( std::string_view  p)
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.

Parameters
[in]pThe pattern text.
Returns
true if a branch is empty, so the translation declines.

◆ nonempty_at_without_context()

std::optional< real::regex::result_type > real::compat::detail::nonempty_at_without_context ( const real::regex &  engine,
std::string_view  text,
std::size_t  at 
)
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.

Parameters
[in]engineThe pattern.
[in]textThe subject.
[in]atWhere the empty match was.
Returns
The match on text.substr(at), offsets relative to at; empty when there is none.

◆ not_null_stays_real()

template<typename CharT , typename Traits >
bool real::compat::detail::not_null_stays_real ( const basic_regex< CharT, Traits > &  re)
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).

Parameters
[in]reThe pattern; real-backed.
Returns
true if a call under match_not_null may stay on REAL.

◆ pattern_forces_std()

bool real::compat::detail::pattern_forces_std ( std::string_view  p)
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.

Parameters
[in]pThe pattern text.
Returns
true if it holds a construct only the std backend can serve.

◆ posix_class_ranges()

std::string real::compat::detail::posix_class_ranges ( std::string_view  name)
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).

Parameters
[in]nameA POSIX class name without its brackets, e.g. alpha.
Returns
The equivalent range text for a bracket expression, or empty if the name is unknown.

◆ real_engine_for()

template<typename CharT , typename Traits >
const real::regex * real::compat::detail::real_engine_for ( const basic_regex< CharT, Traits > &  re,
regex_constants::match_flag_type  mf,
bool  anchored 
)
private

The REAL engine a regex_search or regex_match with mf runs on, or null for std.

Parameters
[in]reThe pattern.
[in]mfThe match flags.
[in]anchoredA whole-sequence match (regex_match).
Returns
The pattern's engine, its not_eol / not_eow variant, or null.

◆ real_honors()

bool real::compat::detail::real_honors ( regex_constants::match_flag_type  mf)
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).

Parameters
[in]mfThe match flags the caller passed.
Returns
true if the iteration may stay on REAL.

◆ replace_stays_real()

bool real::compat::detail::replace_stays_real ( regex_constants::match_flag_type  f)
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.

Parameters
[in]fThe match/format flags the caller passed to regex_replace.
Returns
true if the real expander honors all of them, so the replace may stay on the real backend.

◆ rewrite_end_context()

std::string real::compat::detail::rewrite_end_context ( std::string_view  pattern,
bool  not_eol,
bool  not_eow,
bool  multiline 
)
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.

Parameters
[in]patternAn ECMAScript pattern as REAL compiles it.
[in]not_eolRewrite $.
[in]not_eowRewrite \b and \B.
[in]multilineThe pattern is multiline.
Returns
The rewritten pattern.

◆ run_copied()

template<typename BidirIt , typename CharT , typename Traits >
bool real::compat::detail::run_copied ( BidirIt  first,
BidirIt  last,
match_results< BidirIt > &  m,
const basic_regex< CharT, Traits > &  re,
call_shape  shape 
)
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.

Parameters
[in]firstStart of the sequence.
[in]lastOne past its end.
[out]mResult; reset over [first, last) by the caller.
[in]reThe pattern; real-backed.
[in]shapeThe call; under match_prev_avail the copy starts at --first.
Returns
true if a match was found and m filled.

◆ run_impl()

template<bool Capture, typename BidirIt , typename CharT , typename Traits >
bool real::compat::detail::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 
)
private

Runs the backend over [first, last), filling m under Capture; a flag REAL cannot honor routes to std.

Template Parameters
CaptureFill m (regex_search / regex_match with results); without it no result is built.
Parameters
[in]firstStart of the sequence to run over.
[in]lastOne past its end.
[out]mUnder Capture, filled on success and left ready-but-unmatched on failure; else unused (null).
[in]reThe pattern, whose backend decides which engine runs.
[in]anchoredWhole-sequence match (regex_match) rather than leftmost search.
[in]mfMatch flags (call_stays_real).
Returns
true if a match was found.

◆ shape_of()

call_shape real::compat::detail::shape_of ( regex_constants::match_flag_type  mf,
bool  anchored,
bool  nullable 
)
inlineprivatenoexcept

The REAL call a regex_search or regex_match with mf makes; see call_stays_real.

Parameters
[in]mfThe match flags, which call_stays_real accepted.
[in]anchoredA whole-sequence match (regex_match).
[in]nullableThe pattern can match empty, so match_not_null changes what it finds.
Returns
The call's shape.

◆ std_call()

template<typename Call >
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.

Template Parameters
CallA callable taking no argument.
Parameters
[in]callThe std operation.
Returns
What call returns.
Exceptions
real::compat::regex_errorwhen call throws a std::regex_error.

◆ std_dollar_zero_is_match()

bool real::compat::detail::std_dollar_zero_is_match ( )
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.

Returns
true when std::regex_replace("a", regex("a"), "$0") gives back "a"; asked once.

◆ std_sed_keeps_final_backslash()

bool real::compat::detail::std_sed_keeps_final_backslash ( )
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.

Returns
true when std::regex_replace("a", regex("a"), "\\", format_sed) gives back a backslash; asked once.

◆ to_real()

real::flags real::compat::detail::to_real ( regex_constants::syntax_option_type  f)
inlinenoexcept

Maps compat options to REAL's flags, always with bytes | ecma: one REAL byte per std::regex char.

Parameters
[in]fThe compat syntax options.
Returns
The equivalent real::flags.

◆ to_std()

std::regex_constants::syntax_option_type real::compat::detail::to_std ( regex_constants::syntax_option_type  f)
inlinenoexcept

Maps compat options to std::regex syntax flags (the fallback path).

Parameters
[in]fThe compat syntax options.
Returns
The equivalent std::regex_constants::syntax_option_type.

◆ to_std_match()

std::regex_constants::match_flag_type real::compat::detail::to_std_match ( regex_constants::match_flag_type  f)
inlineprivatenoexcept

Maps every compat match and format flag to std::regex_constants; a bit missing here would be silently dropped on the std path.

Parameters
[in]fThe compat flags to translate.
Returns
The equivalent std::regex_constants::match_flag_type.

◆ translate_bracket()

bool real::compat::detail::translate_bracket ( std::string_view  p,
std::size_t &  i,
std::string &  out 
)
inline

Translates a POSIX bracket expression, the same in BRE and ERE: a POSIX class becomes its ASCII ranges, other members pass through.

Parameters
[in]pThe pattern being translated.
[in,out]iCursor at the opening bracket; advanced past the expression on success.
[in,out]outDestination the translated bracket is appended to.
Returns
false on an unterminated expression, an unknown class or a collating element; out is then unchanged.

◆ translate_bre()

std::optional< std::string > real::compat::detail::translate_bre ( std::string_view  p)
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.

Parameters
[in]pThe BRE pattern.
Returns
The ECMAScript equivalent, or std::nullopt when it cannot be translated.

◆ translate_ecma_classes()

std::optional< std::string > real::compat::detail::translate_ecma_classes ( std::string_view  p,
bool  icase 
)
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.

Parameters
[in]pThe ECMAScript pattern.
[in]icaseWhether 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:].
Returns
The pattern with each class rewritten, or 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 [.-.]).

◆ translate_ere()

std::optional< std::string > real::compat::detail::translate_ere ( std::string_view  p,
bool  awk = false 
)
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).

Parameters
[in]pThe ERE pattern.
[in]awkWhether awk's extra escapes are in scope.
Returns
The ECMAScript equivalent, or std::nullopt when the pattern cannot be translated.

◆ translate_newline_alt()

template<typename LineFn >
std::optional< std::string > real::compat::detail::translate_newline_alt ( std::string_view  p,
LineFn  translate_line 
)
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.

Parameters
[in]pThe pattern, whose newlines separate alternatives (grep/egrep).
[in]translate_lineApplied to each line; its std::nullopt fails the whole translation.
Returns
The joined ECMAScript alternation, or std::nullopt if any line failed.

◆ translate_posix()

std::optional< std::string > real::compat::detail::translate_posix ( std::string_view  p,
regex_constants::syntax_option_type  f 
)
inline

Dispatches a single POSIX grammar to its translator; nullopt for no grammar bit or several, or under collate or nosubs.

Parameters
[in]pThe pattern text.
[in]fThe syntax options, which select the POSIX grammar to translate from.
Returns
The ECMAScript equivalent, or std::nullopt when the options or pattern decline.

Variable Documentation

◆ real_eligible

template<typename CharT , typename Traits >
constexpr bool real::compat::detail::real_eligible
inlineconstexpr
Initial value:
=
std::is_same_v<CharT, char> && std::is_same_v<Traits, std::regex_traits<char>>

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.