This is an automated email from the ASF dual-hosted git repository.

bneradt pushed a commit to branch charset
in repository https://gitbox.apache.org/repos/asf/trafficserver-libswoc.git

commit 7592cb629f6a5886a3364c868de9c96378e6ae8a
Author: Alan M. Carroll <[email protected]>
AuthorDate: Mon Nov 27 13:38:52 2023 -0600

    Errata: fix is_ok
---
 code/include/swoc/Errata.h    | 12 +++----
 code/include/swoc/swoc_meta.h | 58 ++++++++++++++++++++++++++++++
 doc/code/TextView.en.rst      | 31 +++++++++++++---
 doc/index.rst                 | 13 +++++--
 tools/ats-drop.sh             | 82 -------------------------------------------
 unit_tests/test_Errata.cc     | 11 ++++++
 unit_tests/test_meta.cc       | 24 +++++++++++++
 7 files changed, 136 insertions(+), 95 deletions(-)

diff --git a/code/include/swoc/Errata.h b/code/include/swoc/Errata.h
index 944129d..d765ef7 100644
--- a/code/include/swoc/Errata.h
+++ b/code/include/swoc/Errata.h
@@ -504,10 +504,7 @@ public:
   bool is_ok() const;
 
   /// @return If there is top level severity.
-  bool
-  has_severity() const {
-    return _data && _data->_severity.has_value();
-  }
+  bool has_severity() const;
 
   /// @return Top level severity.
   Severity severity() const;
@@ -1124,9 +1121,12 @@ Errata::assign(code_type code) -> self_type & {
   return *this;
 }
 
+inline bool Errata::has_severity() const {
+  return _data && _data->_severity.has_value();
+}
 inline auto
 Errata::severity() const -> Severity {
-  return _data ? _data->_severity.value() : DEFAULT_SEVERITY;
+  return this->has_severity() ? _data->_severity.value() : DEFAULT_SEVERITY;
 }
 
 inline auto
@@ -1142,7 +1142,7 @@ Errata::length() const {
 
 inline bool
 Errata::is_ok() const {
-  return this->empty() || _data->_severity < FAILURE_SEVERITY;
+  return nullptr == _data || this->severity() < FAILURE_SEVERITY;
 }
 
 inline const Errata::Annotation &
diff --git a/code/include/swoc/swoc_meta.h b/code/include/swoc/swoc_meta.h
index 0d987b2..5c3855e 100644
--- a/code/include/swoc/swoc_meta.h
+++ b/code/include/swoc/swoc_meta.h
@@ -237,4 +237,62 @@ template <typename... Types> struct type_list {
   template <typename T> static constexpr bool contains = is_any_of<T, 
Types...>::value;
 };
 
+/** Scoped value change.
+ *
+ * The purpose of this class is to change the value of a variable in a scope 
and then change it
+ * back when the scope is exited. The old value will be moved to a cache 
variable and then moved
+ * back when the instance is destructed. This is very useful to temporarily 
tweak global variables
+ * which having to know what the current value is.
+ *
+ * @code
+ * {
+ *   let save(var, value);
+ *   // var now has value.
+ * }
+ * // var now has original value.
+ * @endcode
+ *
+ * @tparam T Type of variable to scope.
+ */
+template <typename T> struct let {
+  using self_type = let;
+
+  let(self_type const& that) = delete;
+  self_type & operator = (self_type const&) = delete;
+
+  T &_var;  ///< Reference to scoped variable.
+  T _value; ///< Original value.
+
+  /** Construct a scope.
+   *
+   * @param var Variable to scope.
+   * @param value temporary value to assign.
+   */
+  let(T &var, T const &value);
+
+  /** Construct a scope.
+   *
+   * @param var Variable to scope.
+   * @param value temporary value to assign.
+   */
+  let(T &var, T &&value);
+
+  ~let();
+};
+
+template <typename T> let<T>::let(T &var, T const &value) : _var(var), 
_value(std::move(var))
+{
+  _var = value;
+}
+template <typename T> let<T>::let(T &var, T &&value) : _var(var), 
_value(std::move(var))
+{
+  _var = std::move(value);
+}
+
+template <typename T> let<T>::~let()
+{
+  _var = std::move(_value);
+}
+
+
 }}} // namespace swoc::SWOC_VERSION_NS::meta
diff --git a/doc/code/TextView.en.rst b/doc/code/TextView.en.rst
index 740f85d..c2ede1b 100644
--- a/doc/code/TextView.en.rst
+++ b/doc/code/TextView.en.rst
@@ -86,6 +86,18 @@ E.g. the code to write a simple hash function [#]_ could be
       return hash;
    }
 
+Although alternatively, this can be done in a non-modifying way.
+
+.. code-block:: cpp
+
+   void hasher(TextView v) {
+      size_t hash = 0;
+      for ( auto c : v) {
+         hash = hash * 13 + c;
+      }
+      return hash;
+   }
+
 Because |TV| inherits from :code:`std::string_view` it can also be used as a 
container for range
 :code:`for` loops.
 
@@ -97,10 +109,21 @@ Because |TV| inherits from :code:`std::string_view` it can 
also be used as a con
       return hash;
    }
 
+The first approach enables dropping out of the loop on some condition with the 
view updated to
+no longer contain processed characters, making restart or other processing 
simple.
+
 The standard functions :code:`strcmp`, :code:`memcmp`, code:`memcpy`, and 
:code:`strcasecmp` are
 overloaded for |TV| so that a |TV| can be used as if it were a C-style string. 
The size is is taken
 from the |TV| and doesn't need to be passed in explicitly.
 
+.. class:: CharSet
+
+   :libswoc:`Reference documentation <swoc::CharSet>`.
+
+This is a simple class that contains a set of characters. This is intended 
primarily to make
+parsing faster and simpler. Rather than checking a list of delimiters the 
character can be checked
+with a single `std::bitset` lookup.
+
 Basic Operations
 ================
 
@@ -130,7 +153,7 @@ Searching
 ---------
 
 Because |TV| is a subclass of :code:`std::string_view` all of its search 
method work on a |TV|. The
-only search methods provided beyond those are :libswoc:`TextView::find_if` and
+only search methods provided beyond those in :code:`std::string` are 
:libswoc:`TextView::find_if` and
 :libswoc:`TextView::rfind_if` which search the view by a predicate. The 
predicate takes a single
 :code:`char` argument and returns a :code:`bool`. The search terminates on the 
first character for
 which the predicate returns :code:`true`.
@@ -281,12 +304,12 @@ developing |TV| parsing.
 
 The first was to minimize the need to allocate memory to hold intermediate 
results. For this reason, the normal
 style of use is a streaming / incremental one, where tokens are extracted from 
a source one by one
-and placed in |TV| instances, with the orignal source |TV| being reduced by 
each extraction until
+and placed in |TV| instances, with the original source |TV| being reduced by 
each extraction until
 it is empty.
 
 The second was to minimize cut and paste coding. Typical C or C++ parsing 
logic consists mostly of
 very generic code to handle pointer and size updates. The point of |TV| is to 
automate all of that
-so the resulting code is focused entirely on the parsing logic, not boiler 
plate string or view manipulation.
+yielding code focused entirely on the parsing logic, not boiler plate string 
or view manipulation.
 It is a common occurrence to not get such code exactly correct leading to hard 
to track bugs. Use
 of |TV| eliminates those problems.
 
@@ -313,7 +336,7 @@ are very cheap to copy. This is essentially the same as 
having a current pointer
 and checking for :code:`current >= end` except :code:`TextView` does all the 
work, leading to
 simpler and less buggy code.
 
-White space is dropped because of the calls to :code:`ltrim_if` and 
`rtrim_if`. By calling in the
+White space is dropped because of the calls to :code:`ltrim_if` and 
:code:`rtrim_if`. By calling in the
 loop condition, the loop exits if the remaining text is only whitespace and no 
token is processed.
 Alternatively :code:`trim_if` could be used after extraction. The performance 
will be *slightly*
 better because although :code:`trim_if` calls :code:`ltrim_if` and 
:code:`rtrim_if`, a final
diff --git a/doc/index.rst b/doc/index.rst
index b6f573e..f63bb30 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -18,9 +18,16 @@ Solid Wall of C++
 *****************
 
 The Solid Wall of C++ library is a collection of C++ classes and utilities. 
This code evolved out of
-infrastructure used in `Apache Traffic Server 
<https://trafficserver.apache.org>`__. The utilities
-had become useful enough there were requests to be able to use them in ATS 
plugins and other,
-unrelated projects. Hence this library. I hope you find it as useful as I have.
+infrastructure used in `Apache Traffic Server 
<https://trafficserver.apache.org>`__ as I strove to combine
+functionality, ease of use, and performance.
+The utilities had become useful enough there were requests to be able to use 
them in ATS plugins and other,
+unrelated projects. Hence this library. After much production use, this 
library has been imported back
+in to Traffic Server and can be used there in the core or any plugin.
+I hope you find it as useful as I have.
+
+Most of the library is dedicated to convenience, such as :class:`TextView` 
which provides Python like
+string manipulation on top of :code:`std::string_view`, and performance, such 
as :class:`IPSpace` which
+enables very fast IP address range storage.
 
 .. toctree::
    :maxdepth: 1
diff --git a/tools/ats-drop.sh b/tools/ats-drop.sh
index 839a07f..0048b29 100644
--- a/tools/ats-drop.sh
+++ b/tools/ats-drop.sh
@@ -23,9 +23,6 @@ else
   mkdir -p ${TARGET_SRC_DIR}
 fi
 
-cp code/CMakeLists.txt ${TARGET_BASE_DIR}/swoc
-(cd ${ATS}/${BASE_PATH}/swoc ; sed -i -e '/^if (LIBSWOC_INSTALL)/,/^endif/d' 
CMakeLists.txt ; git add CMakeLists.txt)
-
 cp code/src/*.cc ${TARGET_SRC_DIR}
 (cd ${ATS}; git add ${BASE_PATH}/swoc/CMakeLists.txt ; git add 
${SRC_PATH}/*.cc)
 
@@ -48,82 +45,3 @@ cp code/include/swoc/*.h ${TARGET_INC_DIR}
 cp code/include/swoc/ext/*.h ${TARGET_INC_DIR}/ext
 cp code/include/swoc/ext/HashFNV.h ${TARGET_INC_DIR}
 (cd ${ATS}; git add ${INC_PATH}/*.h ; git add ${INC_PATH}/ext/*.h)
-
-# Build the source
-cat <<'TEXT' > ${ATS}/${BASE_PATH}/swoc/Makefile.am
-# swoc Makefile.am
-#
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-lib_LTLIBRARIES = libtsswoc.la
-
-library_includedir=$(includedir)/swoc
-
-AM_CPPFLAGS += @SWOC_INCLUDES@
-
-libtsswoc_la_LDFLAGS = @AM_LDFLAGS@ -no-undefined -release 1.5.8
-libtsswoc_la_SOURCES = \
-       src/ArenaWriter.cc  src/bw_format.cc  src/bw_ip_format.cc  
src/Errata.cc  src/MemArena.cc  src/RBTree.cc  src/swoc_file.cc  src/swoc_ip.cc 
 src/TextView.cc src/string_view_util.cc
-
-if EXPORT_SWOC_HEADERS
-library_include_HEADERS = \
-        include/swoc/ArenaWriter.h \
-        include/swoc/BufferWriter.h \
-        include/swoc/bwf_base.h \
-        include/swoc/bwf_ex.h \
-        include/swoc/bwf_fwd.h \
-        include/swoc/bwf_ip.h \
-        include/swoc/bwf_std.h \
-        include/swoc/DiscreteRange.h \
-        include/swoc/Errata.h \
-        include/swoc/IntrusiveDList.h \
-        include/swoc/IntrusiveHashMap.h \
-        include/swoc/IPAddr.h \
-        include/swoc/IPEndpoint.h \
-        include/swoc/IPRange.h \
-        include/swoc/IPSrv.h \
-        include/swoc/Lexicon.h \
-        include/swoc/MemArena.h \
-        include/swoc/MemSpan.h \
-        include/swoc/RBTree.h \
-        include/swoc/Scalar.h \
-        include/swoc/swoc_file.h \
-        include/swoc/swoc_ip.h \
-        include/swoc/swoc_meta.h \
-        include/swoc/swoc_version.h\
-        include/swoc/string_view_util.h \
-        include/swoc/TextView.h \
-        include/swoc/Vectray.h \
-        include/swoc/HashFNV.h
-endif
-
-clean-local:
-
-clang-tidy-local: $(DIST_SOURCES)
-       $(CXX_Clang_Tidy)
-TEXT
-(cd ${ATS} ; git add ${BASE_PATH}/swoc/Makefile.am)
-
-if ! grep -q swoc ${ATS}/configure.ac ; then
-  sed -i -e 's!lib/yamlcpp/Makefile!lib/swoc/Makefile\n  &!' 
${ATS}/configure.ac
-  (cd ${ATS} ; git add configure.ac)
-fi
-
-if ! grep -q swoc ${ATS}/${BASE_PATH}/Makefile.am ; then
-  sed -i -e '/SUBDIRS =/s!$! swoc!' ${ATS}/${BASE_PATH}/Makefile.am
-  (cd ${ATS} ; git add ${BASE_PATH}/Makefile.am)
-fi
diff --git a/unit_tests/test_Errata.cc b/unit_tests/test_Errata.cc
index 8ce82a5..e46bd07 100644
--- a/unit_tests/test_Errata.cc
+++ b/unit_tests/test_Errata.cc
@@ -414,4 +414,15 @@ TEST_CASE("Errata Autotext", "[libswoc][errata]") {
   REQUIRE(b.front().text() == "Bravo [2]");
   Errata c{ecode(ECode::ALPHA), ERRATA_ERROR, Errata::AUTO};
   REQUIRE(c.front().text() == "Error: Alpha [1]");
+
+  Errata d{ERRATA_ERROR};
+  REQUIRE_FALSE(d.is_ok());
+  Errata e{ERRATA_INFO};
+  REQUIRE(e.is_ok());
+  Errata f{ecode(ECode::BRAVO)};
+  REQUIRE_FALSE(f.is_ok());
+  // Change properties but need to restore them for other tests.
+  swoc::meta::let g1(Errata::DEFAULT_SEVERITY, ERRATA_WARN);
+  swoc::meta::let g2(Errata::FAILURE_SEVERITY, ERRATA_ERROR);
+  REQUIRE(f.is_ok());
 }
diff --git a/unit_tests/test_meta.cc b/unit_tests/test_meta.cc
index 55c9c3e..782bae4 100644
--- a/unit_tests/test_meta.cc
+++ b/unit_tests/test_meta.cc
@@ -93,3 +93,27 @@ TEST_CASE("Meta vary", "[meta][vary]") {
   v = "956"_tv;
   REQUIRE(std::visit(visitor, v) == 956);
 }
+
+TEST_CASE("Meta let", "[meta][let]") {
+  using swoc::meta::let;
+
+  unsigned x = 56;
+  {
+    REQUIRE(x == 56);
+    let guard(x, unsigned(3136));
+    REQUIRE(x == 3136);
+    // auto bogus = guard; // should not compile.
+  }
+  REQUIRE(x == 56);
+
+  // Checking move semantics - avoid reallocating the original string.
+  std::string s{"Evil Dave Rulz With An Iron Keyboard"}; // force allocation.
+  auto sptr = s.data();
+  {
+    char const * text = "Twas brillig and the slithy toves";
+    let guard(s, std::string(text));
+    REQUIRE(s == text);
+    REQUIRE(s.data() != sptr);
+  }
+  REQUIRE(s.data() == sptr);
+}

Reply via email to