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()) };

Reply via email to