Macro core::str::iter::generate_pattern_iterators
source · macro_rules! generate_pattern_iterators { { // Forward iterator forward: $(#[$forward_iterator_attribute:meta])* struct $forward_iterator:ident; // Reverse iterator reverse: $(#[$reverse_iterator_attribute:meta])* struct $reverse_iterator:ident; // Stability of all generated items stability: $(#[$common_stability_attribute:meta])* // Internal almost-iterator that is being delegated to internal: $internal_iterator:ident yielding ($iterty:ty); // Kind of delegation - either single ended or double ended delegate $($t:tt)* } => { ... }; { double ended; with $(#[$common_stability_attribute:meta])*, $forward_iterator:ident, $reverse_iterator:ident, $iterty:ty } => { ... }; { single ended; with $(#[$common_stability_attribute:meta])*, $forward_iterator:ident, $reverse_iterator:ident, $iterty:ty } => { ... }; }
Expand description
This macro generates two public iterator structs
wrapping a private internal one that makes use of the Pattern
API.
For all patterns P: Pattern<'a>
the following items will be
generated (generics omitted):
struct $forward_iterator($internal_iterator); struct $reverse_iterator($internal_iterator);
impl Iterator for $forward_iterator { /* internal ends up calling Searcher::next_match() */ }
impl DoubleEndedIterator for $forward_iterator where P::Searcher: DoubleEndedSearcher { /* internal ends up calling Searcher::next_match_back() */ }
impl Iterator for $reverse_iterator where P::Searcher: ReverseSearcher { /* internal ends up calling Searcher::next_match_back() */ }
impl DoubleEndedIterator for $reverse_iterator where P::Searcher: DoubleEndedSearcher { /* internal ends up calling Searcher::next_match() */ }
The internal one is defined outside the macro, and has almost the same
semantic as a DoubleEndedIterator by delegating to pattern::Searcher
and
pattern::ReverseSearcher
for both forward and reverse iteration.
“Almost”, because a Searcher
and a ReverseSearcher
for a given
Pattern
might not return the same elements, so actually implementing
DoubleEndedIterator
for it would be incorrect.
(See the docs in str::pattern
for more details)
However, the internal struct still represents a single ended iterator from
either end, and depending on pattern is also a valid double ended iterator,
so the two wrapper structs implement Iterator
and DoubleEndedIterator
depending on the concrete pattern type, leading
to the complex impls seen above.