REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
real::basic_match_iterator< Storage, TrailingLA > Class Template Reference

Forward iterator over the non-overlapping matches in a text. More...

#include <real.hpp>

Collaboration diagram for real::basic_match_iterator< Storage, TrailingLA >:
[legend]

Public Types

using value_type = basic_match_result< typename Storage::slot_storage >
 Yielded match type.
 
using difference_type = std::ptrdiff_t
 Iterator traits.
 
using reference = const value_type &
 Dereference type.
 
using pointer = const value_type *
 Arrow type.
 
using iterator_category = std::forward_iterator_tag
 Multipass: copies are independent.
 

Public Member Functions

constexpr basic_match_iterator () noexcept
 Constructs the end sentinel.
 
constexpr basic_match_iterator (detail::program_view prog, std::string_view pattern, std::string_view text, std::size_t start=0, match_semantics sem=match_semantics::first)
 Constructs a begin iterator and finds the first match.
 
constexpr void decide_batching (detail::program_view prog, match_semantics sem, std::size_t text_bytes)
 Once per walk: which batched filler, if any, serves this scan.
 
constexpr const value_type & operator* () const
 Returns the current match.
 
constexpr const value_type * operator-> () const
 Returns pointer to the current match.
 
constexpr basic_match_iterator & operator++ ()
 Advances to the next match.
 
constexpr basic_match_iterator operator++ (int)
 Advances to the next match (post-increment).
 
constexpr bool exhausted () const noexcept
 Whether the walk is over, without building an end sentinel to compare against.
 
constexpr bool operator== (const basic_match_iterator &other) const
 Returns true if both denote the same position in the same walk, or both are the end.
 

Private Member Functions

constexpr std::size_t count_rest ()
 Counts the matches left, the current one included, and ends the walk.
 
constexpr bool refill_batch ()
 Cold half of the batched walk: refills batch_ from the engine.
 
constexpr void advance ()
 Finds the next match, applying the empty-match advance rules.
 

Private Attributes

detail::program_view prog_
 The program being run.
 
std::string_view pattern_
 Pattern text (named lookups).
 
std::string_view text_
 The text being scanned.
 
std::size_t pos_ {}
 Current scan offset.
 
std::size_t forbid_empty_until_ {}
 Empty-match guard (see pike.hpp).
 
bool done_ {true}
 True once exhausted.
 
bool cascade_ {}
 Chosen once — run the memchr-cascade class-run variant for this whole walk.
 
match_semantics sem_ {match_semantics::first}
 leftmost-first (default) or longest (find_iter_longest).
 
value_type current_
 The current match.
 
Storage::state_type state_
 VM scratch, reused across the walk.
 
detail::pike_vm< typenameStorage::state_type, true >::cp_span batch_ [batch_cap] {}
 The buffered spans; indices batch_i_ .. batch_n_ are the unread ones.
 
std::size_t batch_n_ {}
 Spans currently buffered.
 
std::size_t batch_i_ {}
 Next span to hand out.
 
bool batch_eligible_ {}
 Route/shape allows batching (decided once).
 
bool trailing_la_walk_ {}
 This walk takes the trailing-lookaround route ([a-z]+(?=[a-z])), chosen once here rather than by specialization, so basic_regex::find_iter, whose return type fixes the specialization, reaches it too.
 
bool batch_bytes_ {}
 Batch the BYTE-class route rather than the code-point one.
 
bool batch_cp_ascii_ {}
 Batch the ./negated-class route (real::detail::pike_vm::fill_codepoint_class_spans).
 
bool batch_single_cl_ {}
 
bool wb_edge_ {}
 The pattern carries a dropped leading \b (real::detail::pattern_hints::wb_lead_maximal_run): its filler takes the window-edge guard as a template argument, never as a loop test.
 
bool batch_alt_ {}
 Batch the fixed-alternation route (real::detail::pike_vm::fill_alternation_spans).
 
bool batch_alt_asks_ {}
 The alternation batch has yet to ask whether the automaton takes the subject.
 
bool batch_wide_ {}
 Batch the wide alternation route (detail::pike_vm::fill_alternation_wide_spans).
 
bool batch_spent_ {}
 The last fill stopped short of the buffer at the end of the subject.
 
bool batch_lazy_dfa_ {}
 Batch the lazy-DFA route (pike.hpp's fill_lazy_dfa_spans), the one no recognizer claims.
 
bool batch_exact_lit_ {}
 Batch the exact-literal route (pike.hpp's fill_exact_literal_spans).
 
bool batch_inner_lit_ {}
 Batch the inner-literal route (pike.hpp's fill_inner_literal_spans); may stop short, see batch_partial_.
 
bool batch_fixed_ {}
 
bool batch_partial_ {}
 The last fill stopped without proving the subject spent: an empty buffer means "resume on the per-match path", not "the walk is over". Set by the lazy-DFA, inner-literal and wide-alternation fillers and by the automaton's claim; every other filler scans the whole subject.
 
bool wb_kept_ {}
 The pattern keeps a \b/\B wrap, evaluated on every span by the byte and code-point class fillers; the other batched routes decline such patterns.
 

Static Private Attributes

static constexpr std::size_t batch_cap {4}
 Buffered spans for the batched routes — see batch_eligible_.
 

Friends

template<typename >
class basic_regex
 

Detailed Description

template<typename Storage, bool TrailingLA = false>
class real::basic_match_iterator< Storage, TrailingLA >

Forward iterator over the non-overlapping matches in a text.

Follows Python's empty-match rules: an empty match is yielded (even right after a non-empty one), then the scan advances by one codepoint. The regex and the text must outlive the iterator. Obtained from basic_match_range.

Template Parameters
StorageThe regex's storage policy (selects the result/scratch types).

Constructor & Destructor Documentation

◆ basic_match_iterator() [1/2]

template<typename Storage , bool TrailingLA = false>
constexpr real::basic_match_iterator< Storage, TrailingLA >::basic_match_iterator ( )
inlineconstexprnoexcept

Constructs the end sentinel.

User-provided, not = default: end()'s return {} value-initializes, and with a defaulted constructor that zero-fills the whole object (its VM state included, ~10 KB) before constructing it. The members a sentinel is read through carry their own initializers (done_ is true).

◆ basic_match_iterator() [2/2]

template<typename Storage , bool TrailingLA = false>
constexpr real::basic_match_iterator< Storage, TrailingLA >::basic_match_iterator ( detail::program_view  prog,
std::string_view  pattern,
std::string_view  text,
std::size_t  start = 0,
match_semantics  sem = match_semantics::first 
)
inlineconstexpr

Constructs a begin iterator and finds the first match.

Parameters
[in]progThe compiled program to run.
[in]patternThe pattern text (for named-group resolution).
[in]textThe text to iterate over (borrowed).
[in]startByte offset to begin iterating from (0 = the whole text).
[in]semMatch semantics: leftmost-first (default) or the experimental leftmost-longest.

Member Function Documentation

◆ advance()

template<typename Storage , bool TrailingLA = false>
constexpr void real::basic_match_iterator< Storage, TrailingLA >::advance ( )
inlineconstexprprivate

Finds the next match, applying the empty-match advance rules.

Note
Not force-inlined, though its per-match frame is a large share of its cost: always_inline pushes the unit past --param inline-unit-growth and charges unrelated class rows (docs/design.dox 10.1). Shrink the frame instead.

◆ count_rest()

template<typename Storage , bool TrailingLA = false>
constexpr std::size_t real::basic_match_iterator< Storage, TrailingLA >::count_rest ( )
inlineconstexprprivate

Counts the matches left, the current one included, and ends the walk.

The spans a batched fill buffered past the current match are counted without being handed out: handing one out writes its slots, which no count reads. The first span of each fill still goes through advance, so the walk keeps its one path for refills, partial fills and the per-match fallback.

Returns
The number of matches from the current one to the end.

◆ decide_batching()

template<typename Storage , bool TrailingLA = false>
constexpr void real::basic_match_iterator< Storage, TrailingLA >::decide_batching ( detail::program_view  prog,
match_semantics  sem,
std::size_t  text_bytes 
)
inlineconstexpr

Once per walk: which batched filler, if any, serves this scan.

Parameters
[in]progThe compiled program, for its hints.
[in]semThe walk's match semantics.
[in]text_bytesSubject length; the lazy-DFA filler needs a minimum runway.

◆ exhausted()

template<typename Storage , bool TrailingLA = false>
constexpr bool real::basic_match_iterator< Storage, TrailingLA >::exhausted ( ) const
inlineconstexprnoexcept

Whether the walk is over, without building an end sentinel to compare against.

Prefer this in a hand-rolled loop: it == basic_match_iterator{} answers the same question but materialises a full walker (a whole heap-backed scratch state) just to test.

Returns
true once no further match will be produced.

◆ operator*()

template<typename Storage , bool TrailingLA = false>
constexpr const value_type & real::basic_match_iterator< Storage, TrailingLA >::operator* ( ) const
inlineconstexpr

Returns the current match.

Returns
A reference to the result, valid until the next increment.

◆ operator++() [1/2]

template<typename Storage , bool TrailingLA = false>
constexpr basic_match_iterator & real::basic_match_iterator< Storage, TrailingLA >::operator++ ( )
inlineconstexpr

Advances to the next match.

Returns
*this.

◆ operator++() [2/2]

template<typename Storage , bool TrailingLA = false>
constexpr basic_match_iterator real::basic_match_iterator< Storage, TrailingLA >::operator++ ( int  )
inlineconstexpr

Advances to the next match (post-increment).

Returns
A copy of the iterator at its pre-increment position.

◆ operator->()

template<typename Storage , bool TrailingLA = false>
constexpr const value_type * real::basic_match_iterator< Storage, TrailingLA >::operator-> ( ) const
inlineconstexpr

Returns pointer to the current match.

Returns
A pointer to the result, valid until the next increment.

◆ operator==()

template<typename Storage , bool TrailingLA = false>
constexpr bool real::basic_match_iterator< Storage, TrailingLA >::operator== ( const basic_match_iterator< Storage, TrailingLA > &  other) const
inlineconstexpr

Returns true if both denote the same position in the same walk, or both are the end.

Live iterators compare offset, subject and program. Exhausted ones are equal whatever they walked: basic_match_range::end is a default-constructed sentinel carrying neither.

Parameters
[in]otherAnother iterator.
Returns
true if both are exhausted, or both are live at the same offset of the same walk.

◆ refill_batch()

template<typename Storage , bool TrailingLA = false>
constexpr bool real::basic_match_iterator< Storage, TrailingLA >::refill_batch ( )
inlineconstexprprivate

Cold half of the batched walk: refills batch_ from the engine.

Outlined: this unit sits on gcc's per-unit inline budget (docs/design.dox §10.1), and inlined it grows advance enough to charge rows that never batch.

Each branch bills real::detail::prof::tick_route under the unbatched route's identifier, once per refill: entries / matches reads 1 / batch_cap while batching works.

Warning
Read docs/MEASUREMENT.md §3.2 before adding a branch here: one more branch moves unrelated rows even with every filler byte-identical.
Returns
true if at least one span was buffered.

Member Data Documentation

◆ batch_cap

template<typename Storage , bool TrailingLA = false>
constexpr std::size_t real::basic_match_iterator< Storage, TrailingLA >::batch_cap {4}
staticconstexprprivate

Buffered spans for the batched routes — see batch_eligible_.

Not wider: this array is part of every iterator, so a wider buffer charges walks that never batch (outlining the refill does not recover it).

◆ batch_fixed_

template<typename Storage , bool TrailingLA = false>
bool real::basic_match_iterator< Storage, TrailingLA >::batch_fixed_ {}
private

Batch the fixed-shape route (detail::pike_vm::fill_fixed_shape_spans).

◆ batch_single_cl_

template<typename Storage , bool TrailingLA = false>
bool real::basic_match_iterator< Storage, TrailingLA >::batch_single_cl_ {}
private

Batch the bare single byte-class route (real::detail::pike_vm::fill_single_class_spans).

◆ trailing_la_walk_

template<typename Storage , bool TrailingLA = false>
bool real::basic_match_iterator< Storage, TrailingLA >::trailing_la_walk_ {}
private

This walk takes the trailing-lookaround route ([a-z]+(?=[a-z])), chosen once here rather than by specialization, so basic_regex::find_iter, whose return type fixes the specialization, reaches it too.

Costs one test per match on advance's general path, which the unbatched routes pay. An enum shared with batch_eligible_ costs more: only a walk selected without a per-match test removes it.


The documentation for this class was generated from the following file: