This is an automated email from the ASF dual-hosted git repository. bneradt pushed a commit to branch dev-1-2-13 in repository https://gitbox.apache.org/repos/asf/trafficserver-libswoc.git
commit dc659e5d04fa9d79fccf0331fd949bdd669ce8b1 Author: Alan M. Carroll <[email protected]> AuthorDate: Fri Oct 30 14:32:14 2020 -0500 TextView: add "clip_prefix_of" and "clip_suffix_of". --- code/include/swoc/TextView.h | 48 +++++++++++++++++++++++++++++++++++++++++--- doc/code/TextView.en.rst | 8 ++++++++ unit_tests/ex_UnitParser.cc | 6 ++++-- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/code/include/swoc/TextView.h b/code/include/swoc/TextView.h index e40a9a8..78aded2 100644 --- a/code/include/swoc/TextView.h +++ b/code/include/swoc/TextView.h @@ -367,6 +367,8 @@ public: * @tparam F Predicate function type. * @param pred The predicate instance. * @return @a this. + * + * Characters are removed until @a pred returns @c true. The matching character is also removed. */ template <typename F> self_type &remove_prefix_if(F const &pred); @@ -483,6 +485,17 @@ public: */ template <typename F> self_type take_prefix_if(F const &pred); + /** Remove and return a prefix of characters satisfying @a pred + * + * @tparam F Predicate functor type. + * @param pred A function taking @c char and returning @c bool. + * @return The prefix of characters that satisfy @a pred. + * + * The returned prefix is removed from @a this. That prefix may be empty if the first character + * does not satisfy @a pred. + */ + template <typename F> self_type clip_prefix_of(F const &pred); + /** Get a view of the last @a n bytes. * * @param n Number of chars in the prefix. @@ -646,14 +659,23 @@ public: * @param pred A function taking @c char and returning @c bool. * @return The suffix bounded by the first character satisfying @a pred if found, otherwise all of @a this. * - * The returned suffix is removed the character satisfying @a pred if found. - * - * @note The matching character is discarded if @a this is modified. + * @note The matching character is discarded if found. * * @see @c split_suffix_if */ template <typename F> self_type take_suffix_if(F const &pred); + /** Remove and return a suffix of characters satisfying @a pred + * + * @tparam F Predicate functor type. + * @param pred A function taking @c char and returning @c bool. + * @return The suffix of characters that satisfy @a pred. + * + * The returned suffix is removed from @a this. That suffix may be empty if the last character + * does not satisfy @a pred. + */ + template <typename F> self_type clip_suffix_of(F const &pred); + /** Get a view of part of this view. * * @param pos Offset of first byte in the new view. @@ -1404,6 +1426,26 @@ TextView::stream_write(Stream &os, const TextView &b) const { return os; } +template<typename F> +TextView::self_type TextView::clip_prefix_of(F const& pred) { + size_t idx = 0; + for (auto spot = this->data(), limit = spot + this->size() ; spot < limit && pred(*spot); ++spot, ++idx ) + ; // empty + TextView token = this->prefix(idx); + this->remove_prefix(idx); + return token; +} + +template<typename F> +TextView::self_type TextView::clip_suffix_of(F const& pred) { + size_t idx = this->size() - 1; + for (auto spot = this->data() + idx, limit = this->data() ; spot >= limit && pred(*spot); --spot, --idx ) + ; // empty + TextView token = this->suffix(idx); + this->remove_suffix(idx); + return token; +} + // Provide an instantiation for @c std::ostream as it's likely this is the only one ever used. extern template std::ostream &TextView::stream_write(std::ostream &, const TextView &) const; diff --git a/doc/code/TextView.en.rst b/doc/code/TextView.en.rst index 2030aff..f3abaf3 100644 --- a/doc/code/TextView.en.rst +++ b/doc/code/TextView.en.rst @@ -167,6 +167,10 @@ A secondary distinction is what is done to the view by the methods. is discarded and not left in either the returned view nor the source view. If the selected character is not in the view, the entire view is returned and the source view is cleared. +* The "clip..." methods remove the corresponding part of the view and return it. Only those characters + are removed - in contrast to "split..." and "take...". If no characters match, the view is not modified + and an empty view is returned. + .. _`std::string_view::remove_prefix`: https://en.cppreference.com/w/cpp/string/basic_string_view/remove_prefix .. _`std::string_view::remove_suffix`: https://en.cppreference.com/w/cpp/string/basic_string_view/remove_suffix @@ -209,6 +213,8 @@ if the size specified is larger than the contents of the view. | | | | :libswoc:`TextView::split_prefix_at` | | | + +------------------------------------------+ | | | | :libswoc:`TextView::split_prefix_if` | +| | + +------------------------------------------+ +| | | | :libswoc:`TextView::clip_prefix_of` | | | +---------+------------------------------------------+ | | | No | :libswoc:`TextView::take_prefix` | | | + +------------------------------------------+ @@ -221,6 +227,8 @@ if the size specified is larger than the contents of the view. | | | | :libswoc:`TextView::split_suffix_at` | | | + +------------------------------------------+ | | | | :libswoc:`TextView::split_suffix_if` | +| | + +------------------------------------------+ +| | | | :libswoc:`TextView::clip_suffix_of` | | | +---------+------------------------------------------+ | | | No | :libswoc:`TextView::take_suffix` | | | + +------------------------------------------+ diff --git a/unit_tests/ex_UnitParser.cc b/unit_tests/ex_UnitParser.cc index 0417c6e..60ab3d1 100644 --- a/unit_tests/ex_UnitParser.cc +++ b/unit_tests/ex_UnitParser.cc @@ -24,6 +24,7 @@ template < typename ... Args > Errata Error(TextView const& fmt, Args && ... arg return Errata{}.note_v(swoc::Severity::ERROR, fmt, std::forward_as_tuple(args...)); } +# if 0 /** Extract and remove the next token. * * @tparam PRED Predicate function type - @c bool(char) @@ -41,6 +42,7 @@ template < typename PRED > inline TextView take_token_if(TextView &src, PRED con src.remove_prefix(idx); return token; } +# endif } // namespace @@ -106,7 +108,7 @@ auto UnitParser::operator()(swoc::TextView const& src) const noexcept -> Rv<valu while (text.ltrim_if(&isspace)) { // Get a count first. auto ptr = text.data(); // save for error reporting. - auto count = take_token_if(text, &isdigit); + auto count = text.clip_prefix_of(&isdigit); if (count.empty()) { return { 0 , Error("Required count not found at offset {}", ptr - src.data()) }; } @@ -116,7 +118,7 @@ auto UnitParser::operator()(swoc::TextView const& src) const noexcept -> Rv<valu // Next, the unit. ptr = text.ltrim_if(&isspace).data(); // save for error reporting. // Everything up to the next digit or whitespace. - auto unit = take_token_if(text, [](char c) { return !(isspace(c) || isdigit(c)); } ); + auto unit = text.clip_prefix_of([](char c) { return !(isspace(c) || isdigit(c)); } ); if (unit.empty()) { if (_unit_required_p) { return { 0, Error("Required unit not found at offset {}", ptr - src.data()) };
