Regex: make RegexIterator iterable and able to iter backwards
This commit is contained in:
parent
413f880e9e
commit
b34bb6b794
36
src/regex.hh
36
src/regex.hh
|
@ -139,7 +139,7 @@ bool regex_search(It begin, It end, MatchResults<It>& res, const Regex& re,
|
|||
String option_to_string(const Regex& re);
|
||||
void option_from_string(StringView str, Regex& re);
|
||||
|
||||
template<typename Iterator>
|
||||
template<typename Iterator, MatchDirection direction = MatchDirection::Forward>
|
||||
struct RegexIterator
|
||||
{
|
||||
using ValueType = MatchResults<Iterator>;
|
||||
|
@ -147,7 +147,8 @@ struct RegexIterator
|
|||
RegexIterator() = default;
|
||||
RegexIterator(Iterator begin, Iterator end, const Regex& re,
|
||||
RegexExecFlags flags = RegexExecFlags::None)
|
||||
: m_regex{&re}, m_next_begin{begin}, m_begin{begin}, m_end{end}, m_flags{flags}
|
||||
: m_regex{&re}, m_next_pos{direction == MatchDirection::Forward ? begin : end},
|
||||
m_begin{begin}, m_end{end}, m_flags{flags}
|
||||
{
|
||||
next();
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ struct RegexIterator
|
|||
return true;
|
||||
|
||||
return lhs.m_regex == rhs.m_regex and
|
||||
lhs.m_next_begin == rhs.m_next_begin and
|
||||
lhs.m_next_pos == rhs.m_next_pos and
|
||||
lhs.m_end == rhs.m_end and
|
||||
lhs.m_flags == rhs.m_flags and
|
||||
lhs.m_results == rhs.m_results;
|
||||
|
@ -178,6 +179,9 @@ struct RegexIterator
|
|||
return not (lhs == rhs);
|
||||
}
|
||||
|
||||
RegexIterator begin() { return *this; }
|
||||
RegexIterator end() { return {}; }
|
||||
|
||||
private:
|
||||
void next()
|
||||
{
|
||||
|
@ -186,19 +190,31 @@ private:
|
|||
RegexExecFlags additional_flags{};
|
||||
if (m_results.size() and m_results[0].first == m_results[0].second)
|
||||
additional_flags |= RegexExecFlags::NotInitialNull;
|
||||
if (m_begin != m_next_begin)
|
||||
additional_flags |= RegexExecFlags::NotBeginOfSubject | RegexExecFlags::PrevAvailable;
|
||||
|
||||
if (not regex_search(m_next_begin, m_end, m_results, *m_regex,
|
||||
m_flags | additional_flags))
|
||||
m_regex = nullptr;
|
||||
if (direction == MatchDirection::Forward)
|
||||
{
|
||||
if (m_begin != m_next_pos)
|
||||
additional_flags |= RegexExecFlags::NotBeginOfSubject | RegexExecFlags::PrevAvailable;
|
||||
|
||||
if (not regex_search(m_next_pos, m_end, m_results, *m_regex,
|
||||
m_flags | additional_flags))
|
||||
m_regex = nullptr;
|
||||
else
|
||||
m_next_pos = m_results[0].second;
|
||||
}
|
||||
else
|
||||
m_next_begin = m_results[0].second;
|
||||
{
|
||||
if (not regex_search<Iterator, MatchDirection::Backward>(m_begin, m_next_pos, m_results, *m_regex,
|
||||
m_flags | additional_flags))
|
||||
m_regex = nullptr;
|
||||
else
|
||||
m_next_pos = m_results[0].first;
|
||||
}
|
||||
}
|
||||
|
||||
const Regex* m_regex = nullptr;
|
||||
MatchResults<Iterator> m_results;
|
||||
Iterator m_next_begin{};
|
||||
Iterator m_next_pos{};
|
||||
const Iterator m_begin{};
|
||||
const Iterator m_end{};
|
||||
const RegexExecFlags m_flags = RegexExecFlags::None;
|
||||
|
|
Loading…
Reference in New Issue
Block a user