summaryrefslogtreecommitdiff
path: root/src/regex.hh
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-12-20 23:07:50 +1100
committerMaxime Coste <mawww@kakoune.org>2019-01-20 22:59:28 +1100
commit8c2603ab3ca58e24ca227bd42e0550adb74fa95f (patch)
tree11c870a9a08bae944a1495965f87e25336013ef5 /src/regex.hh
parent30897fd820df7bb572b7599abeb84715128e4117 (diff)
Support re-using the same ThreadedRegexVM for multiple iterations
This should reduce the number of allocations as the memory allocated for the thread stack and the saves can be re-used between runs instead of being cleared every time.
Diffstat (limited to 'src/regex.hh')
-rw-r--r--src/regex.hh24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/regex.hh b/src/regex.hh
index 4aa916c9..c0a1fea0 100644
--- a/src/regex.hh
+++ b/src/regex.hh
@@ -164,7 +164,8 @@ bool backward_regex_search(It begin, It end, It subject_begin, It subject_end,
String option_to_string(const Regex& re);
Regex option_from_string(Meta::Type<Regex>, StringView str);
-template<typename Iterator, MatchDirection direction = MatchDirection::Forward>
+template<typename Iterator, MatchDirection direction = MatchDirection::Forward,
+ typename VmArg = const Regex>
struct RegexIterator
{
using ValueType = MatchResults<Iterator>;
@@ -177,25 +178,24 @@ struct RegexIterator
const ValueType* operator->() const { kak_assert(m_valid); return &m_base.m_results; }
It& operator++() { m_valid = m_base.next(); return *this; }
+ bool operator==(Sentinel) const { return not m_valid; }
+ bool operator!=(Sentinel) const { return m_valid; }
RegexIterator& m_base;
bool m_valid;
};
- friend bool operator==(const It& lhs, Sentinel) { return not lhs.m_valid; }
- friend bool operator!=(const It& lhs, Sentinel) { return lhs.m_valid; }
-
RegexIterator(Iterator begin, Iterator end,
Iterator subject_begin, Iterator subject_end,
- const Regex& re, RegexExecFlags flags = RegexExecFlags::None)
- : m_vm{*re.impl()}, m_next_pos{direction == MatchDirection::Forward ? begin : end},
+ VmArg& vm_arg, RegexExecFlags flags = RegexExecFlags::None)
+ : m_vm{make_vm(vm_arg)}, m_next_pos{direction == MatchDirection::Forward ? begin : end},
m_begin{std::move(begin)}, m_end{std::move(end)},
m_subject_begin{std::move(subject_begin)}, m_subject_end{std::move(subject_end)},
m_flags{flags} {}
- RegexIterator(const Iterator& begin, const Iterator& end, const Regex& re,
- RegexExecFlags flags = RegexExecFlags::None)
- : RegexIterator{begin, end, begin, end, re, flags} {}
+ RegexIterator(const Iterator& begin, const Iterator& end,
+ VmArg& vm_arg, RegexExecFlags flags = RegexExecFlags::None)
+ : RegexIterator{begin, end, begin, end, vm_arg, flags} {}
It begin() { return {*this}; }
Sentinel end() const { return {}; }
@@ -219,7 +219,11 @@ private:
return true;
}
- ThreadedRegexVM<Iterator, direction> m_vm;
+ using RegexVM = ThreadedRegexVM<Iterator, direction>;
+ static RegexVM& make_vm(RegexVM& vm) { return vm; }
+ static RegexVM make_vm(const Regex& regex) { return {*regex.impl()}; }
+
+ decltype(make_vm(std::declval<VmArg&>())) m_vm;
MatchResults<Iterator> m_results;
Iterator m_next_pos{};
const Iterator m_begin{};