From d7ad1807216331e25f931bc46aa3a35e8b76cecc Mon Sep 17 00:00:00 2001 From: tastytea Date: Sun, 30 May 2021 13:31:59 +0200 Subject: [PATCH] Use iterators in search::context() and don't return extra whitespace Should be easier to understand now. --- src/search.cpp | 66 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index b96002c..a7efda4 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -181,49 +182,70 @@ match_context context(const boost::match_results &match, return {}; } - const auto &prefix{match.prefix().str()}; - const auto &suffix{match.suffix().str()}; - size_t pos_before{prefix.length()}; - size_t pos_after{}; - ++words; + const auto &rbegin_before{std::reverse_iterator(match.prefix().end())}; + const auto &rend_before{std::reverse_iterator(match.prefix().begin())}; + + const auto &begin_after{match.suffix().begin()}; + const auto &end_after{match.suffix().end()}; + + auto pos_before{rbegin_before}; + auto pos_after{begin_after}; + + const std::array whitespace{' ', '\n', '\r', '\t'}; + auto is_whitespace{ + [&whitespace](char check) + { + return std::any_of(whitespace.begin(), whitespace.end(), + [&check](const char ws) { return check == ws; }); + }}; + while (words != 0) { - if (pos_before != 0) + if (pos_before != rend_before) { - pos_before = prefix.rfind(' ', pos_before); - if (pos_before != string::npos) + pos_before = std::find_first_of(pos_before, rend_before, + whitespace.begin(), + whitespace.end()); + if (pos_before != rend_before) { - --pos_before; - } - else - { - pos_before = 0; + while (is_whitespace(*pos_before)) + { + ++pos_before; + } } } - if (pos_after != string::npos) + if (pos_after != end_after) { - pos_after = suffix.find(' ', pos_after); - if (pos_after != string::npos) + pos_after = std::find_first_of(pos_after, end_after, + whitespace.begin(), + whitespace.end()); + if (pos_after != end_after) { - ++pos_after; + while (is_whitespace(*pos_after)) + { + ++pos_after; + } } } words -= 1; } - if (pos_before != 0) + const std::string prefix_reversed(rbegin_before, pos_before); + string prefix(prefix_reversed.rbegin(), prefix_reversed.rend()); + std::string suffix(begin_after, pos_after); + while (is_whitespace(*prefix.begin())) { - pos_before += 2; + prefix.erase(0, 1); } - if (pos_after != string::npos) + while (is_whitespace(*suffix.rbegin())) { - pos_after -= 1; + suffix.erase(suffix.size() - 1); } - return {prefix.substr(pos_before), suffix.substr(0, pos_after)}; + return {prefix, suffix}; } string headline(const std::string_view prefix)