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