|
REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
|
The result of a match attempt: success, spans and captures. More...
#include <real.hpp>
Public Member Functions | |
| constexpr | basic_match_result ()=default |
| Constructs an empty (non-matched) result. | |
| constexpr | basic_match_result (std::string_view text, SlotStorage &&slots, bool matched, std::string_view pattern, std::span< const detail::named_group > names) |
| Constructs a result from raw slots (used internally by the engine). | |
| template<typename OtherOwner > requires (!std::is_same_v<OtherOwner, NameOwner>) | |
| constexpr | basic_match_result (basic_match_result< SlotStorage, OtherOwner > other) |
| Engine-internal: adopts the fields of the borrowing twin, to be detached next. | |
| constexpr | basic_match_result (std::string_view text, std::string_view pattern, std::span< const detail::named_group > names) |
| Engine-internal: an empty, unmatched result whose slot storage is built IN PLACE. | |
| constexpr SlotStorage & | engine_slots () noexcept |
| Engine-internal: the slot storage, for the engine to fill in place. | |
| constexpr void | engine_set_matched (bool matched) noexcept |
| Engine-internal: records whether the fill that just ran produced a match. | |
| constexpr void | detach_from_regex () |
| Engine-internal: stop borrowing the regex's name tables, because it is about to die. | |
| template<bool Cascade, typename Vm > | |
| constexpr bool | engine_refill (Vm &vm, std::string_view text, std::size_t pos, detail::run_mode mode, std::size_t forbid, std::string_view pattern, std::span< const detail::named_group > names) |
| Engine-internal: re-run the search into this result's OWN slot buffer, reusing its capacity. Not part of the public API. | |
| constexpr void | bind_context (std::string_view text, std::string_view pattern, std::span< const detail::named_group > names) |
| Binds the invariant context (subject, pattern, named groups) once. For an iterator that refills the same result many times, these never change within a walk — set them here, not per match. | |
| template<bool Cascade, typename Vm > | |
| constexpr bool | engine_refill_hot (Vm &vm, std::string_view text, std::size_t pos, detail::run_mode mode, std::size_t forbid, match_semantics sem=match_semantics::first) |
| Per-match refill for an iterator whose context is already bound via bind_context runs the VM and records only the outcome (the invariant fields are already set), the find_iter hot path. | |
| template<typename Vm > | |
| constexpr void | engine_refill_span (Vm &vm, std::size_t s, std::size_t e) |
| Refill from a span the engine already found in a batch, bypassing the VM entirely. | |
| template<bool Cascade, typename Vm > | |
| constexpr bool | engine_refill_trailing_la (Vm &vm, std::string_view text, std::size_t pos) |
| Cold path for TrailingLA walks only (never referenced from pure walks). | |
| constexpr bool | matched () const |
Returns true if the attempt matched. | |
| constexpr | operator bool () const |
Returns true if the attempt matched (explicit bool conversion). | |
| constexpr std::size_t | size () const |
| Returns the number of groups, including group 0 (the whole match). | |
| constexpr std::size_t | start (std::size_t group=0) const |
| Start byte offset of a group. | |
| constexpr std::size_t | end (std::size_t group=0) const |
| End byte offset (exclusive) of a group. | |
| constexpr std::string_view | operator[] (std::size_t group) const |
| View of a group's matched text. | |
| constexpr std::string_view | str (std::size_t group=0) const |
View of a group's matched text — std::smatch's spelling for operator[]. | |
| constexpr std::size_t | group_index (std::string_view name) const |
| Resolves a group name to its number. | |
| constexpr std::size_t | start (std::string_view name) const |
| Returns its start offset, or npos if unknown. | |
| constexpr std::size_t | end (std::string_view name) const |
| Returns its end offset, or npos if unknown. | |
| constexpr std::string_view | operator[] (std::string_view name) const |
| Returns its matched text, empty if unknown/unset. | |
| constexpr std::span< const std::size_t > | spans () const noexcept |
The capture slots as one flat [start0, end0, start1, end1, …] view. | |
Private Attributes | |
| std::string_view | text_ |
| The searched text. | |
| SlotStorage | slots_ |
| Flattened capture slots. | |
| bool | matched_ {} |
| Whether a match occurred. | |
| std::string_view | pattern_ |
| Pattern text (for named lookups). | |
| std::span< const detail::named_group > | names_ |
| NameOwner | owner_ {} |
Friends | |
| template<typename , typename > | |
| class | basic_match_result |
| The twin specialisation reads these fields to adopt them; nothing else does. | |
The result of a match attempt: success, spans and captures.
Group views point into the searched text, which must outlive the result — the rvalue std::string overloads on the regex are deleted so the common dangling mistake is a compile error.
Named-group lookups need the regex's pattern text and name table. A result from a live regex borrows both. A result from a temporary regex is real::basic_regex::owning_result_type — the same class, owning those tables — so names still resolve after the regex dies. find_iter and find_all have no such twin: they are deleted on an rvalue regex.
| SlotStorage | The capture-slot container (vector- or static-backed), supplied by the storage policy. |
| NameOwner | How name tables are held: borrowed from a live regex, or owned after a temporary regex dies. |
|
inlineconstexpr |
Constructs a result from raw slots (used internally by the engine).
| [in] | text | The searched text (borrowed; must outlive the result). |
| [in] | slots | Flattened capture slots (byte offsets, npos for unset). |
| [in] | matched | Whether a match occurred. |
| [in] | pattern | The pattern text (for named-group resolution). |
| [in] | names | The regex's named-group table (borrowed). |
|
inlineexplicitconstexpr |
Engine-internal: adopts the fields of the borrowing twin, to be detached next.
A template, and constrained, so that it exists only for the owning specialisation – the borrowing one is what every walk and every attempt on a live regex yields, and it must stay exactly the type it was.
Taken by value: the caller hands over a prvalue, so nothing is copied, and the slots move out of the parameter rather than out of a subobject of a reference.
| OtherOwner | The source's name owner, necessarily not this one's. |
| [in] | other | The freshly run result to take over. |
|
inlineconstexpr |
Engine-internal: an empty, unmatched result whose slot storage is built IN PLACE.
Paired with engine_slots and engine_set_matched, this is what lets basic_regex::run hand the engine the FINAL slot storage instead of filling a local and moving it in. The move it removes was the last bulk copy per call: gcc lowered it to a rep movsq worth 12.02 % of the inlined per-call path (small_vec::transfer_range<true> through transfer_inline_from), and rep movs pays a fixed startup whatever the volume — which for a groupless pattern is sixteen bytes. run() has a single return statement, so the result is NRVO-constructed in the caller's storage and the engine writes straight into it.
| [in] | text | The searched text (borrowed; must outlive the result). |
| [in] | pattern | The pattern text (for named-group resolution). |
| [in] | names | The regex's named-group table (borrowed). |
|
inlineconstexpr |
Binds the invariant context (subject, pattern, named groups) once. For an iterator that refills the same result many times, these never change within a walk — set them here, not per match.
| [in] | text | The subject the walk runs over. |
| [in] | pattern | The pattern text, for diagnostics and group naming. |
| [in] | names | The pattern's named groups. |
|
inlineconstexpr |
Engine-internal: stop borrowing the regex's name tables, because it is about to die.
search, match and fullmatch are callable on a temporary regex, and must stay so – the one-expression form (real::regex{"a+"}.search(text).matched()) is safe, since the temporary outlives the full-expression, and it is the shape most callers write. What is NOT safe is the result outliving that temporary: group_index reads the pattern text and the named-group table, both of which the regex owns. This copies them into the result instead, so a result from an rvalue regex resolves names correctly for as long as it exists.
The borrowed views are cleared either way: with named groups owner_ becomes the source of truth (which is what keeps the implicit copy constructor correct – a copy deep-copies the box and reads its OWN, rather than inheriting views into the original's), and without them there is nothing to copy, but a dangling view nobody dereferences would still be one.
A no-op on the compile-time policy, whose tables have static storage duration.
|
inlineconstexpr |
End byte offset (exclusive) of a group.
| [in] | group | Group number (0 = whole match). |
|
inlineconstexpr |
Returns its end offset, or npos if unknown.
| [in] | name | Group name. |
|
inlineconstexpr |
Engine-internal: re-run the search into this result's OWN slot buffer, reusing its capacity. Not part of the public API.
The match iterator holds one result and refreshes it in place each step. vm.run fills the slots via assign, which reuses the existing capacity, so a match-dense iteration allocates the slot vector once instead of once per match — the measured per-match cost (a fresh allocation is ~5x a reused one). A user-held copy of a previous match stays independent: copying a result deep-copies its slots, so refilling this one never disturbs it.
| Cascade | Select the memchr-cascade class-run variant (chosen once per walk). |
| Vm | The Pike VM type (kept a template to avoid a header cycle). |
| [in] | vm | The VM to run. |
| [in] | text | The searched text (borrowed). |
| [in] | pos | Start offset for the search. |
| [in] | mode | The run mode. |
| [in] | forbid | The empty-match forbid-until offset. |
| [in] | pattern | The pattern text (for named-group resolution). |
| [in] | names | The regex's named-group table (borrowed). |
|
inlineconstexpr |
Per-match refill for an iterator whose context is already bound via bind_context runs the VM and records only the outcome (the invariant fields are already set), the find_iter hot path.
| Cascade | Whether the VM may take its memchr-cascade tail. |
| Vm | The engine type, deduced. |
| [in,out] | vm | The engine to run. |
| [in] | text | The subject. |
| [in] | pos | Byte offset to attempt at. |
| [in] | mode | Anchoring: full, prefix or search. |
| [in] | forbid | Offset at which a zero-length match is refused (the find_iter no-progress rule). |
| [in] | sem | Leftmost-first or leftmost-longest. |
|
inlineconstexpr |
Refill from a span the engine already found in a batch, bypassing the VM entirely.
| Vm | The engine type, deduced. |
| [in,out] | vm | The engine, used only to reconstruct the slot layout for this span. |
| [in] | s | Match start. |
| [in] | e | Match end. |
|
inlineconstexpr |
Cold path for TrailingLA walks only (never referenced from pure walks).
| Cascade | Whether the VM may take its memchr-cascade tail. |
| Vm | The engine type, deduced. |
| [in,out] | vm | The engine to run. |
| [in] | text | The subject. |
| [in] | pos | Byte offset to attempt at. |
|
inlineconstexprnoexcept |
Engine-internal: records whether the fill that just ran produced a match.
| [in] | matched | Whether a match occurred. |
|
inlineconstexprnoexcept |
Engine-internal: the slot storage, for the engine to fill in place.
|
inlineconstexpr |
Resolves a group name to its number.
| [in] | name | The group name. |
|
inlineconstexpr |
Returns true if the attempt matched.
|
inlineexplicitconstexpr |
Returns true if the attempt matched (explicit bool conversion).
|
inlineconstexpr |
View of a group's matched text.
| [in] | group | Group number (0 = whole match). |
|
inlineconstexpr |
Returns its matched text, empty if unknown/unset.
| [in] | name | Group name. |
|
inlineconstexpr |
Returns the number of groups, including group 0 (the whole match).
|
inlineconstexprnoexcept |
The capture slots as one flat [start0, end0, start1, end1, …] view.
For a caller that copies every group in one pass (the C ABI's spans buffer is this layout). Only meaningful on a matched result — an unmatched one carries whatever the last fill left. Prefer start / end when reading a single group; those return real::npos if it did not participate. Copy pairwise (spans[2g], spans[2g+1]).
2 * size() slot values; empty when there are no slots.
|
inlineconstexpr |
Start byte offset of a group.
| [in] | group | Group number (0 = whole match). |
|
inlineconstexpr |
Returns its start offset, or npos if unknown.
| [in] | name | Group name. |
|
inlineconstexpr |
View of a group's matched text — std::smatch's spelling for operator[].
Exactly operator[], under the name a caller arriving from std::regex writes first. Without it m.str(1) is a compile error that names an internal storage type and suggests nothing. Unlike std::smatch::str it returns a view rather than an owned string, so it never copies and the subject must outlive the result.
That difference bites on the NEXT line the same caller writes: std::string s = m.str(1); does not compile, because std::string_view converts to std::string explicitly. Spell it std::string s {m.str(1)}; when an owned copy is what you want.
| [in] | group | Group number (0 = whole match). |
|
private |
Named-group table: borrowed, or owned via owner_.
|
private |
Owns what pattern_ and names_ point at, once detach_from_regex has run; empty (and zero-sized) on the compile-time policy, null on every result that borrows.