You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@trafficserver.apache.org by "grahamsedman (via GitHub)" <gi...@apache.org> on 2026/05/21 14:58:01 UTC
[PR] PR Replacement #13185: Fix 32-bit compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
grahamsedman opened a new pull request, #13187:
URL: https://github.com/apache/trafficserver/pull/13187
**Note:** This PR replaces #13185. The branch has been renamed to `fix/lib-swoc-textview-constructors` to maintain consistent local branch organisation for my own folk.
This PR fixes build failures occurring on 32-bit architectures (specifically `arm-linux-gnueabihf`).
### Problem
On 32-bit systems, `size_t` is defined as `unsigned int` and `ssize_t` is defined as `int`. The `TextView` class currently defines distinct constructor overloads for `size_t`, `unsigned`, `ssize_t`, and `int`.
This results in duplicate function signatures on 32-bit builds, causing the compiler to throw `constructor cannot be redeclared` errors.
**Errors observed:**
```text
error: constructor cannot be redeclared
constexpr TextView(char const *ptr, unsigned n) noexcept;
^
note: previous declaration is here
constexpr TextView(char const *ptr, size_t n) noexcept;
```
### Solution
To resolve this ambiguity, this PR refactors the constructor overloads to rely only on `size_t` and `int`.
* **Removed:** `TextView(char const *ptr, unsigned n)`
* **Removed:** `TextView(char const *ptr, ssize_t n)`
* **Retained:** `TextView(char const *ptr, size_t n)` (Covers `unsigned` on 32-bit and `size_t` on 64-bit)
* **Retained:** `TextView(char const *ptr, int n)` (Covers `ssize_t` on 32-bit and `int` on 64-bit)
The logic within the retained constructors (specifically handling `n < 0` for `int`) remains unchanged, ensuring functional parity across architectures.
### Changes
* lib/swoc/include/swoc/TextView.h: Revised includes headers and removed ambiguous constructor declarations and definitions.
* lib/swoc/include/swoc/TextView.cc: Revised includes headers to match those used in the header file.
* Updated includes as requested.
* Formatting: Applied clang-format, yapf, and cmake-format to both files to ensure code style compliance. (missing on PR #13185).
**Checklist:**
- [x] Code compiles on 32-bit ARM
- [x] Code compiles on 64-bit x86_64
- [x] Constructor logic preserved
- [x] Includes reorganized
- [x] Commits are GPG verified (missing on PR #13185)
### Compilation Errors Observed
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:122:13: error: constructor cannot be redeclared
122 | constexpr TextView(char const *ptr, unsigned n) noexcept;
| ^
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:115:13: note: previous declaration is here
115 | constexpr TextView(char const *ptr, size_t n) noexcept;
| ^
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:142:13: error: constructor cannot be redeclared
142 | constexpr TextView(char const *ptr, int n) noexcept;
| ^
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:132:13: note: previous declaration is here
132 | constexpr TextView(char const *ptr, ssize_t n) noexcept;
| ^
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:1128:28: error: redefinition of 'TextView'
1128 | inline constexpr TextView::TextView(const char *ptr, unsigned n) noexcept : super_type(ptr, size_t(n)) {}
| ^
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:1126:28: note: previous definition is here
1126 | inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
| ^
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:1131:28: error: redefinition of 'TextView'
1131 | inline constexpr TextView::TextView(const char *ptr, int n) noexcept
| ^
/home/grahamsedman/Projects/trafficserver/lib/swoc/include/swoc/TextView.h:1129:28: note: previous definition is here
1129 | inline constexpr TextView::TextView(const char *ptr, ssize_t n) noexcept
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4553862702
Hi Everyone,
Thank you for your review. I appreciate you flagging the formatting concern, and I acknowledge I should not have mixed clang-format changes with the functional fix in this PR.
You're absolutely right that libswoc, as an external library, maintains its own formatting style and should be excluded from ATS formatting rules. I will revert all formatting changes from this PR and retain only the minimal functional fix that resolves the compile error.
However, your point about the code existing in **multiple locations** is critical. My investigation confirms the confusion:
- **Original repository**: [[SolidWallOfCode/libswoc](https://github.com/SolidWallOfCode/libswoc)](https://github.com/SolidWallOfCode/libswoc) (stale, 3+ years)
- **Apache’s actively maintained external repository**: [[apache/trafficserver-libswoc](https://github.com/apache/trafficserver-libswoc)](https://github.com/apache/trafficserver-libswoc) (last commit: Mar 9, 2026)
- **Vendored copy within ATS**: [[lib/swoc](https://github.com/apache/trafficserver/tree/master/lib/swoc)] (cloned from the external repository, but now out of sync).
**The core issue**: The compile fix I’m proposing affects code duplicated across these repositories. To properly address this:
1. **Immediate action**: I will update this PR to contain *only* the functional fix (no formatting changes) for the ATS vendored copy at `lib/swoc/`.
2. **Longer-term solution**: I propose we either:
- **Option A**: Convert `lib/swoc/` into a proper Git submodule linked to `apache/trafficserver-libswoc`, ensuring changes flow through the external repository first.
- **Option B**: If libswoc is now considered part of ATS, remove the external repository dependency and apply ATS formatting rules consistently.
The current state—with code duplicated across repositories—creates exactly the confusion we’re seeing. I’d be happy to create a separate issue to track this synchronisation problem.
Would you prefer I proceed with **Option A** or **Option B** for the longer-term fix? For this PR, I’ll focus solely on the minimal compile fix without any formatting changes.
Best regards,
**Graham**
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "JosiahWI (via GitHub)" <gi...@apache.org>.
JosiahWI commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4662355576
@grahamsedman The Jenkins logs have unfortunately not been retained. We could rerun CI to get new logs, but I think the Copilot comments are actionable now without CI logs. Could you address the Copilot comments (if any comments are incorrect or not applicable, please comment to explain why and resolve them).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-5060017822
Hi,
Before I go ahead and split this PR, I wanted to point out something I noticed. It looks like lib/swoc is a downstream copy of the upstream trafficserver-libswoc repo (currently at v1.5.15 here, while upstream is at v1.5.17).
Since this bug is in the core TextView constructors, should I be opening a PR against the upstream trafficserver-libswoc repository first to fix the root cause there?
If I fix it upstream, the 'fix' for this ATS PR would simply be updating the lib/swoc submodule pointer to include the upstream patch (along with the unit test) as two pull requests on non-functional and one functional.
I'm happy to do whichever workflow you prefer! Just wanted to make sure we aren't fixing something here that will get overwritten when ATS updates to a newer version of libswoc.
Thanks
Graham
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4670119391
Hi @JosiahWI,
Thanks for the clarification.
Before doing any further work on this PR, I think we need to resolve some uncertainty around the ownership and maintenance location of `libswoc`.
My investigation found that the code currently exists in multiple places:
* Original `libswoc` repository (largely inactive for several years)
* Apache's actively maintained external `trafficserver-libswoc` repository
* The vendored copy under `ATS/lib/swoc`, which appears to have diverged from the external repository
Because of that, I'd prefer not to make additional changes directly against the vendored copy until we understand which repository is intended to be the authoritative source for this code and how updates are expected to flow between them.
I'll review the Copilot comments, but some of the requested changes may be better addressed in the actively maintained external `trafficserver-libswoc` repository and then synced into ATS, rather than making further ad hoc modifications in the vendored copy.
Could we first confirm the expected maintenance path for `libswoc` before I proceed with additional changes.
Looking to know if `libswoc` the vendored copy should be a sub-module to the external `trafficserver-libswoc`.
When I know this I will follow this for this change.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#discussion_r3337466228
##########
lib/swoc/include/swoc/TextView.h:
##########
@@ -32,2082 +38,2201 @@
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
-namespace swoc { inline namespace SWOC_VERSION_NS {
+namespace swoc
+{
+inline namespace SWOC_VERSION_NS
+{
+
+ class TextView;
+
+ /** A set of characters.
+ *
+ */
+ class CharSet
+ {
+ using self_type = CharSet;
+
+ public:
+ /** Construct from character sequence.
+ *
+ * @param chars Character sequence.
+ *
+ * The charset becomes @c true for every character in the sequence.
+ */
+ constexpr CharSet(TextView const &chars);
+
+ /** Check if character is in the charset.
+ *
+ * @param c Character to check.
+ * @return @c true if @a c is in the charset, @c false if not.
+ */
+ bool operator()(unsigned char c) const;
+
+ /** Check if character is in the charset.
+ *
+ * @param c Character to check.
+ * @return @c true if @a c is in the charset, @c false if not.
+ */
+ bool operator()(char c) const;
+
+ protected:
+ std::bitset<std::numeric_limits<unsigned char>::max() + 1> _chars;
+ };
-class TextView;
+ /** A read only view of a contiguous piece of memory.
+
+ A @c TextView does not own the memory to which it refers, it is simply a view of part of some
+ (presumably) larger memory object. The purpose is to allow working in a read only way a specific
+ part of the memory. A classic example for ATS is working with HTTP header fields and values
+ which need to be accessed independently but preferably without copying. A @c TextView supports
+ this style.
+
+ @note To simplify the interface there is no constructor taking only a character pointer.
+ Constructors require either a literal string or an explicit length. This avoid ambiguities which
+ are much more annoying that explicitly calling @c strlen on a character pointer.
+
+ @internal For construction, assignment operator, and @c assign method, there are a lot of overloads
+ because users would like to be able to use the same sort of arguments for all of these. This includes
+ - self / parent type
+ - @c std::string
+ - literal string
+ - C-string pointer
+ - pointer and count
+ - begin/end style pointers.
+ - character containers that have the STL standard @c size and @c data methods.
+ */
+ class TextView : public std::string_view
+ {
+ using self_type = TextView; ///< Self reference type.
+ using super_type = std::string_view; ///< Parent type.
+
+ public:
+ /// Default constructor (empty buffer).
+ constexpr TextView() noexcept = default;
+
+ /// Construct from a @c std::string_view or @c TextView
+ /// @note This provides an user defined conversion from @c std::string_view to @c TextView. The
+ /// reverse conversion is implicit in @c TextView being a subclass of @c std::string_view.
+ constexpr TextView(super_type const &that) noexcept;
+
+ /** Construct from pointer and size.
+ *
+ * @param ptr Pointer to first character.
+ * @param n Number of characters.
+ *
+ * If @a n is @c npos then @c ptr is presumed to be a C string and checked for length. If @c ptr
+ * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
+ */
+ constexpr TextView(char const *ptr, size_t n) noexcept;
+
+ /** Construct from pointer and size.
+ *
+ * @param ptr Pointer to first character.
+ * @param n Number of characters.
+ *
+ * If @a n is negative then @c ptr is presumed to be a C string and checked for length. If @c ptr
+ * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
+ */
+ constexpr TextView(char const *ptr, int n) noexcept;
Review Comment:
`lib/swoc` is a vendored copy of the upstream libswoc project (see `lib/CMakeLists.txt:68-75`, which also supports `EXTERNAL_LIBSWOC` to use a system install). Patching the vendored copy in-place creates divergence: subsequent upstream re-syncs will silently revert this fix, and downstream users who set `EXTERNAL_LIBSWOC=ON` will still hit the original compile error. This change should be submitted to the upstream libswoc repository first and then pulled in as a refresh of the vendored sources, rather than as a local hand-edit.
##########
lib/swoc/src/TextView.cc:
##########
@@ -10,233 +10,240 @@
*/
#include "swoc/TextView.h"
-#include <cctype>
-#include <sstream>
using namespace swoc::literals;
-namespace swoc { inline namespace SWOC_VERSION_NS {
-
-/// @cond INTERNAL_DETAIL
-const int8_t svtoi_convert[256] = {
- /* [can't do this nicely because clang format won't allow exdented comments]
- 0 1 2 3 4 5 6 7 8 9 A B C D E F
- */
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 30
- -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 40
- 25, 26, 27, 28, 20, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 50
- -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 60
- 25, 26, 27, 28, 20, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 70
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 90
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // A0
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // B0
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // C0
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // D0
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // E0
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // F0
-};
-/// @endcond
-
-intmax_t
-svtoi(TextView src, TextView *out, int base) {
- static constexpr uintmax_t ABS_MAX = std::numeric_limits<intmax_t>::max();
- static constexpr uintmax_t ABS_MIN = uintmax_t(std::numeric_limits<intmax_t>::min());
- intmax_t zret = 0;
-
- if (src.ltrim_if(&isspace)) {
- TextView parsed;
- const char *start = src.data();
- bool neg = false;
- if ('-' == *src) {
- ++src;
- neg = true;
- } else if ('+' == *src) {
- ++src;
- }
- auto n = svtou(src, &parsed, base);
- if (!parsed.empty()) {
- if (out) {
- out->assign(start, parsed.data_end());
+namespace swoc
+{
+inline namespace SWOC_VERSION_NS
+{
Review Comment:
The non-functional reformatting of `TextView.cc` (and the bulk of `TextView.h`) is bundled with the substantive fix, which makes the actual change very hard to review and will create large, painful merge conflicts the next time the vendored libswoc is re-synced from upstream. Please split this PR into (a) the minimal constructor/header-include fix and (b) any style-only reformatting (ideally done upstream first), so that the behavioural change can be reviewed and bisected independently of clang-format churn.
##########
lib/swoc/include/swoc/TextView.h:
##########
@@ -32,2082 +38,2201 @@
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
-namespace swoc { inline namespace SWOC_VERSION_NS {
+namespace swoc
+{
+inline namespace SWOC_VERSION_NS
+{
+
+ class TextView;
+
+ /** A set of characters.
+ *
+ */
+ class CharSet
+ {
+ using self_type = CharSet;
+
+ public:
+ /** Construct from character sequence.
+ *
+ * @param chars Character sequence.
+ *
+ * The charset becomes @c true for every character in the sequence.
+ */
+ constexpr CharSet(TextView const &chars);
+
+ /** Check if character is in the charset.
+ *
+ * @param c Character to check.
+ * @return @c true if @a c is in the charset, @c false if not.
+ */
+ bool operator()(unsigned char c) const;
+
+ /** Check if character is in the charset.
+ *
+ * @param c Character to check.
+ * @return @c true if @a c is in the charset, @c false if not.
+ */
+ bool operator()(char c) const;
+
+ protected:
+ std::bitset<std::numeric_limits<unsigned char>::max() + 1> _chars;
+ };
-class TextView;
+ /** A read only view of a contiguous piece of memory.
+
+ A @c TextView does not own the memory to which it refers, it is simply a view of part of some
+ (presumably) larger memory object. The purpose is to allow working in a read only way a specific
+ part of the memory. A classic example for ATS is working with HTTP header fields and values
+ which need to be accessed independently but preferably without copying. A @c TextView supports
+ this style.
+
+ @note To simplify the interface there is no constructor taking only a character pointer.
+ Constructors require either a literal string or an explicit length. This avoid ambiguities which
+ are much more annoying that explicitly calling @c strlen on a character pointer.
+
+ @internal For construction, assignment operator, and @c assign method, there are a lot of overloads
+ because users would like to be able to use the same sort of arguments for all of these. This includes
+ - self / parent type
+ - @c std::string
+ - literal string
+ - C-string pointer
+ - pointer and count
+ - begin/end style pointers.
+ - character containers that have the STL standard @c size and @c data methods.
+ */
+ class TextView : public std::string_view
+ {
+ using self_type = TextView; ///< Self reference type.
+ using super_type = std::string_view; ///< Parent type.
+
+ public:
+ /// Default constructor (empty buffer).
+ constexpr TextView() noexcept = default;
+
+ /// Construct from a @c std::string_view or @c TextView
+ /// @note This provides an user defined conversion from @c std::string_view to @c TextView. The
+ /// reverse conversion is implicit in @c TextView being a subclass of @c std::string_view.
+ constexpr TextView(super_type const &that) noexcept;
+
+ /** Construct from pointer and size.
+ *
+ * @param ptr Pointer to first character.
+ * @param n Number of characters.
+ *
+ * If @a n is @c npos then @c ptr is presumed to be a C string and checked for length. If @c ptr
+ * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
+ */
+ constexpr TextView(char const *ptr, size_t n) noexcept;
+
+ /** Construct from pointer and size.
+ *
+ * @param ptr Pointer to first character.
+ * @param n Number of characters.
+ *
+ * If @a n is negative then @c ptr is presumed to be a C string and checked for length. If @c ptr
+ * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
+ */
+ constexpr TextView(char const *ptr, int n) noexcept;
+
+ /** Construct from a half open range [first, last).
+ *
+ * @param first Start of half open range.
+ * @param last End of half open range.
+ *
+ * The character at @a first will be in the view, but the character at @a last will not.
+ *
+ * @note @c explicit to avoid interpreting a string initializer list as a view.
+ *
+ * @internal For the love of Turing, WHY DID YOU DO THIS?
+ *
+ * Well, estemed reader, because the C++ standard doesn't have a better way to support overloads
+ * that handle character pointers and literal strings differently. If the parameters were simply
+ * <tt>(char const *, char const *)</tt> then a construct like <tt>{ "really", "broken" }</tt> can
+ * be interpreted as a @c TextView because the elements implicitly convert to <tt>char const
+ * *</tt>. This makes no sense and creates some @b very annoying ambiguities for lists of strings
+ * if there are exactly two in the list. See @c Lexicon for an example.
+ *
+ * The template itself does the check to make sure it's a character @b pointer and not an array. Arrays
+ * are handled by a different constructor so this only disables constructing from two char arrays
+ * which IMHO makes no sense and should be forbidden.
+ */
+ template <typename T>
+ explicit TextView(
+ T first,
+ std::enable_if_t<!std::is_array_v<T> && std::is_pointer_v<T> && std::is_convertible_v<T, char const *>, T> last) noexcept
+ : super_type(first, last - first)
+ {
+ }
-/** A set of characters.
- *
- */
-class CharSet {
- using self_type = CharSet;
+ /** Construct from any character container following STL standards.
+ *
+ * @tparam C Container type.
+ * @param c container
+ *
+ * The container type must have the methods @c data and @c size which must return values convertible
+ * to @c char @c const @c * and @c size_t respectively.
+ */
+ template <typename C, typename = std::enable_if_t<std::is_convertible_v<decltype(std::declval<C>().data()), char const *> &&
+ std::is_convertible_v<decltype(std::declval<C>().size()), size_t>,
+ void>>
+ constexpr TextView(C const &c);
+
+ /** Construct from literal string or array.
+
+ All elements of the array are included in the view unless the last element is nul, in which case it is elided.
+ If this is inappropriate then a constructor with an explicit size should be used.
+
+ @code
+ TextView a("A literal string");
+ @endcode
+ The last character in @a a will be 'g'.
+ */
+ template <size_t N> constexpr TextView(const char (&s)[N]) noexcept;
+
+ /** Construct from a C-string.
+ *
+ * @param src A pointer to a C-string.
+ *
+ * The view does not include the terminating nul.
+ *
+ * @internal @a src a reference because it is otherwise ambiguous with the literal constructor.
+ */
+ TextView(char *&src) : super_type(src, src ? strlen(src) : 0) {}
+
+ /** Construct from a const C-string.
+ *
+ * @param src Pointer to a const C-string.
+ *
+ * The view does not include the terminating nul.
+ *
+ * @internal @a src a reference because it is otherwise ambiguous with the literal constructor.
+ */
+ TextView(char const *&src) : super_type(src, src ? strlen(src) : 0) {}
+
+ /** Construct from nullptr.
+ This implicitly makes the length 0.
+ */
+ constexpr TextView(std::nullptr_t) noexcept;
+
+ /// Construct from @c std::string, referencing the entire string contents.
+ /// @internal This can't be @c constexpr because this uses methods in @c std::string that may
+ /// not be @c constexpr.
+ TextView(std::string const &str) noexcept;
+
+ /// Assign a super class instance, @c std::string_view to @a this.
+ self_type &operator=(super_type const &that);
+
+ /// Assign a constant array to @a this.
+ /// @note If the last character of @a s is a nul byte, it is not included in the view.
+ template <size_t N> self_type &operator=(const char (&s)[N]);
+
+ /// Assign from C-string @a s.
+ self_type &operator=(char *&s);
+ /// Assign from C-string @a s.
+ self_type &operator=(char const *&s);
+
+ /// Assign from a @c std::string.
+ self_type &operator=(const std::string &s);
+
+ /** Assign a view of the @a c_str
+ *
+ * @param c_str Pointer to C string.
+ * @return @a this
+ *
+ * @note @c c_str must be a null terminated string. The null byte is not included in the view.
+ */
+ self_type &assign(char *&c_str);
+
+ /** Assign a view of the @a c_str
+ *
+ * @param c_str Pointer to C string.
+ * @return @a this
+ *
+ * @note @c c_str must be a null terminated string. The null byte is not included in the view.
+ */
+ self_type &assign(char const *&c_str);
+
+ /** Assign from a pointer and size.
+ *
+ * @param ptr Pointer to first character of the view.
+ * @param n Length of the view.
+ * @return @a this
+ *
+ * if @a n is @a npos then @c strlen is used determine the size of the view.
+ */
+ self_type &assign(char const *ptr, size_t n);
+
+ /** Assign the half open view [ @a b , @a e ) to @a this
+ *
+ * @param b First character in the view.
+ * @param e One character after the last character in the view.
+ * @return @a this
+ */
+ self_type &assign(char const *b, char const *e);
+
+ /// Explicitly set the view from a @c std::string
+ self_type &assign(std::string const &s);
+
+ /** Assign literal string or array.
+
+ * All elements of the array are included in the view unless the last element is nul, in which case it is elided.
+ * If this is inappropriate then a constructor with an explicit size should be used.
+ *
+ * @code
+ * tv.assign("A literal string");
+ * @endcode
+ * The last character in @a tv will be 'g'.
+ */
+ template <size_t N> self_type &assign(const char (&s)[N]) noexcept;
+
+ /** Assign from any character container following STL standards.
+ *
+ * @tparam C Container type.
+ * @param c container
+ *
+ * The container type must have the methods @c data and @c size which must return values convertible
+ * to @c char @c const @c * and @c size_t respectively.
+ */
+ template <typename C, typename = std::enable_if_t<std::is_convertible_v<decltype(std::declval<C>().data()), char const *> &&
+ std::is_convertible_v<decltype(std::declval<C>().size()), size_t>,
+ void>>
+ constexpr self_type &
+ assign(C const &c)
+ {
+ return this->assign(c.data(), c.size());
+ }
-public:
- /** Construct from character sequence.
- *
- * @param chars Character sequence.
- *
- * The charset becomes @c true for every character in the sequence.
- */
- constexpr CharSet(TextView const &chars);
+ /** Dereference operator.
+
+ @note This allows the view to be used as if it were a character iterator to a null terminated
+ string which is handy for several other STL interfaces.
+
+ @return The first byte in the view, or a nul character if the view is empty.
+ */
+ /// @return The first byte in the view.
+ constexpr char operator*() const;
+
+ /** Discard the first byte of the view.
+ *
+ * @return @a this.
+ */
+ self_type &operator++();
+
+ /** Discard the first byte of the view.
+ *
+ * @return The view before discarding the byte.
+ */
+ self_type operator++(int);
+
+ /** Discard the first @a n bytes of the view.
+ *
+ * Equivalent to @c remove_prefix(n).
+ * @return @a this
+ */
+ self_type &operator+=(size_t n);
+
+ /// Check for empty view.
+ /// @return @c true if the view has a nullptr @b or zero size.
+ constexpr bool operator!() const noexcept;
+
+ /// Check for non-empty view.
+ /// @return @c true if the view refers to a non-empty range of bytes.
+ explicit constexpr operator bool() const noexcept;
+
+ /// Clear the view (become an empty view).
+ self_type &clear();
+
+ /// Get the offset of the first character for which @a pred is @c true.
+ template <typename F> size_t find_if(F const &pred) const;
+ /// Get the offset of the last character for which @a pred is @c true.
+ template <typename F> size_t rfind_if(F const &pred) const;
+
+ /** Remove bytes that match @a c from the start of the view.
+ *
+ * @return @a this
+ */
+ self_type <rim(char c);
+
+ /** Remove bytes from the start of the view that are in @a delimiters.
+ *
+ * @return @a this
+ */
+ self_type <rim(CharSet const &delimiters);
+
+ /** Remove bytes from the start of the view that are in @a delimiters.
+ *
+ * @return @a this
+ */
+ self_type <rim(std::string_view const &delimiters);
+
+ /** Remove bytes from the start of the view that are in @a delimiters.
+ *
+ * @internal This is needed to avoid collisions with the templated predicate style.
+ *
+ * @return @c *this
+ */
+ self_type <rim(const char *delimiters);
+
+ /** Remove bytes from the start of the view for which @a pred is @c true.
+ @a pred must be a functor taking a @c char argument and returning @c bool.
+ @return @c *this
+ */
+ template <typename F> self_type <rim_if(F const &pred);
+
+ /** Remove bytes that match @a c from the end of the view.
+ *
+ * @return @a this
+ */
+ self_type &rtrim(char c);
+
+ /** Remove bytes from the end of the view that are in @a delimiters.
+ *
+ * @return @a this
+ */
+ self_type &rtrim(CharSet const &delimiters);
+
+ /** Remove bytes from the end of the view that are in @a delimiters.
+ * @return @a this
+ */
+ self_type &rtrim(std::string_view const &delimiters);
+
+ /** Remove bytes from the end of the view for which @a pred is @c true.
+ *
+ * @a pred must be a functor taking a @c char argument and returning @c bool.
+ *
+ * @return @c *this
+ */
+ template <typename F> self_type &rtrim_if(F const &pred);
+
+ /** Remove bytes that match @a c from the start and end of this view.
+ *
+ * @return @a this
+ */
+ self_type &trim(char c);
+
+ /** Remove bytes from the start and end of the view that are in @a delimiters.
+ * @return @a this
+ */
+ self_type &trim(CharSet const &delimiters);
+
+ /** Remove bytes from the start and end of the view that are in @a delimiters.
+ * @return @a this
+ */
+ self_type &trim(std::string_view const &delimiters);
+
+ /** Remove bytes from the start and end of the view that are in @a delimiters.
+ @internal This is needed to avoid collisions with the templated predicate style.
+ @return @c *this
+ */
+ self_type &trim(const char *delimiters);
+
+ /** Remove bytes from the start and end of the view for which @a pred is @c true.
+ @a pred must be a functor taking a @c char argument and returning @c bool.
+ @return @c *this
+ */
+ template <typename F> self_type &trim_if(F const &pred);
+
+ /** Get a view of the first @a n bytes.
+ *
+ * @param n Number of chars in the prefix.
+ * @return A view of the first @a n characters in @a this, bounded by the size of @a this.
+ */
+ constexpr self_type prefix(size_t n) const noexcept;
+
+ /** Get a view of a prefix bounded by @a c.
+ *
+ * @param c Delimiter character.
+ * @return A view of the prefix bounded by @a c, or all of @a this if @a c is not found.
+ * @note The character @a c is not included in the returned view.
+ */
+ self_type prefix_at(char c) const;
+
+ /** Get a view of a prefix bounded by a character in @a delimiters.
+ *
+ * @param delimiters A set of characters.
+ *
+ * @return A view of the prefix bounded by any character in @a delimiters, or empty if none are
+ * found.
+ *
+ * @note The delimiter character is not included in the returned view.
+ */
+ self_type prefix_at(std::string_view const &delimiters) const;
+
+ /** Get a view of a prefix bounded by a character predicate @a pred.
+ *
+ * @a pred must be a functor which takes a @c char argument and returns @c bool. Each character in
+ * @a this is tested by @a pred and the prefix is delimited by the first character for which @a
+ * pred is @c true.
+ *
+ * @param pred A character predicate.
+ *
+ * @return A view of the prefix bounded by @a pred or empty if @a pred is not @c true for any
+ * characer.
+ *
+ * @note The deliminting character is not included in the returned view.
+ */
+ template <typename F> self_type prefix_if(F const &pred) const;
+
+ /** Remove bytes from the start of the view.
+ *
+ * @param n Number of bytes to remove.
+ * @return @a this.
+ */
+ self_type &remove_prefix(size_t n);
+
+ /** Remove bytes from the end of the view.
+ *
+ * @param n Number of bytes to remove.
+ * @return @a this.
+ */
+ self_type &remove_suffix(size_t n);
+
+ /** Remove the leading characters of @a this up to and including @a c.
+ *
+ * @param c Delimiter character.
+ * @return @a this.
+ * @note The first occurrence of character @a c is removed along with all preceding characters, or
+ * the view is cleared if @a c is not found.
+ */
+ self_type &remove_prefix_at(char c);
+
+ /** Remove the leading characters of @a this up to and including the first character matching @a delimiters.
+ *
+ * @param delimiters Characters to match.
+ * @return @a this.
+ * @note The first occurrence of any character in @a delimiters is removed along with all preceding
+ * characters, or the view is cleared if none are found.
+ */
+ self_type &remove_prefix_at(std::string_view const &delimiters);
+
+ /** Remove the leading characters up to and including the character selected by @a pred.
+ *
+ * @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);
+
+ /** Remove and return a prefix of size @a n.
+ *
+ * @param n Size of the prefix.
+ * @return The first @a n bytes of @a this if @a n is in @a this, otherwise an empty view.
+ *
+ * The prefix is removed and returned if the requested prefix is no larger than @a this,
+ * otherwise @a this is not modified.
+ *
+ * @note The character at offset @a n is discarded if @a this is modified.
+ *
+ * @see @c take_prefix
+ */
+ self_type split_prefix(size_t n);
+
+ /** Remove and return a prefix bounded by the first occurrence of @a c.
+ *
+ * @param c The character to match.
+ * @return The prefix bounded by @a c if @a c is found, an empty view if not.
+ *
+ * The prefix is removed and returned if @a c is found, otherwise @a this is not modified.
+ *
+ * @note The delimiter character is discarded if @a this is modified.
+ *
+ * @see @c take_prefix
+ */
+ self_type split_prefix_at(char c);
+
+ /** Remove and return a prefix bounded by the first occurrence of any of @a delimiters.
+ *
+ * @param delimiters The characters to match.
+ * @return The prefix bounded by a delimiter if one is found, otherwise an empty view.
+ *
+ * The prefix is removed and returned if a @a delimiter is found, otherwise @a this is not modified.
+ *
+ * @note The matching character is discarded if @a this is modified.
+ *
+ * @see @c take_prefix_at
+ */
+ self_type split_prefix_at(std::string_view const &delimiters);
+
+ /** Remove and return a prefix bounded by the first character that satisfies @a pred.
+ *
+ * @tparam F Predicate functor type.
+ * @param pred A function taking @c char and returning @c bool.
+ * @return The prefix bounded by the first character satisfying @a pred.
+ *
+ * The prefix is removed and returned if a character satisfying @a pred is found, otherwise
+ * @a this is not modified.
+ *
+ * @note The matching character is discarded if @a this is modified.
+ *
+ * @see @c take_prefix_if
+ */
+ template <typename F> self_type split_prefix_if(F const &pred);
+
+ /** Remove and return the first @a n characters.
+ *
+ * @param n Size of the return prefix.
+ * @return The first @a n bytes of @a this if @a n is in @a this, otherwise all of @a this.
+ *
+ * The prefix is removed and returned if the requested prefix is no larger than @a this,
+ * otherwise all of @a this is removed and returned.
+ *
+ * @note The character at offset @a n is discarded if @a n is within the bounds of @a this.
+ *
+ * @see @c split_prefix
+ */
+ self_type take_prefix(size_t n);
+
+ /** Remove and return a prefix bounded by the first occurrence of @a c.
+ *
+ * @param c The character to match.
+ * @return The prefix bounded by @a c if @a c is found, all of @a this if not.
+ *
+ * The prefix is removed and returned if @a c is found, otherwise all of @a this is removed and
+ * returned.
+ *
+ * @note The character at offset @a n is discarded if found.
+ *
+ * @see @c split_prefix_at
+ */
+ self_type take_prefix_at(char c);
+
+ /** Remove and return a prefix bounded by the first occurrence of any of @a delimiters.
+ *
+ * @param delimiters The characters to match.
+ * @return The prefix bounded by a delimiter if one is found, otherwise all of @a this.
+ *
+ * The prefix is removed and returned if a @a delimiter is found, otherwise all of @a this is
+ * removed and returned.
+ *
+ * @note The matching character is discarded if found.
+ *
+ * @see @c split_prefix_at
+ */
+ self_type take_prefix_at(std::string_view const &delimiters);
+
+ /** Remove and return a prefix bounded by the first character that satisfies @a pred.
+ *
+ * @tparam F Predicate functor type.
+ * @param pred A function taking @c char and returning @c bool.
+ * @return The prefix bounded by the first character satisfying @a pred, or all of @a this if none
+ * is found.
+ *
+ * The prefix is removed and returned if a character satisfying @a pred is found, otherwise
+ * all of @a this is removed and returned.
+ *
+ * @note The matching character is discarded if found.
+ *
+ * @see @c split_prefix_if
+ */
+ 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.
+ *
+ * @note This is very similar to @c ltrim_if but returns the removed text instead of the modified
+ * view.
+ */
+ 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 suffix.
+ * @return A view of the last @a n characters in @a this, bounded by the size of @a this.
+ */
+ constexpr self_type suffix(size_t n) const noexcept;
+
+ /** Get a view of a suffix bounded by @a c.
+ *
+ * @param c Delimiter character.
+ * @return A view of the suffix bounded by @a c, or all of @a this if @a c is not found.
+ * @note The character @a c is not included in the returned view.
+ */
+ self_type suffix_at(char c) const;
+
+ /** Get a view of a suffix bounded by a character in @a delimiters.
+ *
+ * @param delimiters A set of characters.
+ *
+ * @return A view of the suffix bounded by any character in @a delimiters, or mepty if none are
+ * found.
+ *
+ * @note The delimiter character is not included in the returned view.
+ */
+ self_type suffix_at(std::string_view const &delimiters) const;
+
+ /** Get a view of a suffix bounded by a character predicate @a pred.
+ *
+ * @a pred must be a functor which takes a @c char argument and returns @c bool. Each character in
+ * @a this is tested by @a pred and the suffix is delimited by the last character for which @a
+ * pred is @c true.
+ *
+ * @param pred A character predicate.
+ *
+ * @return A view of the suffix bounded by @a pred or empty if @a pred is not @c true for any
+ * character.
+ *
+ * @note The delimiting character is not included in the returned view.
+ */
+ template <typename F> self_type suffix_if(F const &pred) const;
+
+ /** Remove the trailing characters of @a this up to and including @a c.
+ *
+ * @param c Delimiter character.
+ * @return @a this.
+ *
+ * @note The last occurrence of character @a c is removed along with all succeeding characters, or
+ * the view is cleared if @a c is not found.
+ */
+ self_type &remove_suffix_at(char c);
+
+ /** Remove the trailing characters of @a this up to and including the last character matching @a delimiters.
+ *
+ * @param delimiters Characters to match.
+ * @return @a this.
+ * @note The first occurrence of any character in @a delimiters is removed along with all preceding
+ * characters, or the view is cleared if none are found.
+ */
+ self_type &remove_suffix_at(std::string_view const &delimiters);
+
+ /** Remove the trailing characters up to and including the character selected by @a pred.
+ *
+ * @tparam F Predicate function type.
+ * @param pred The predicate instance.
+ * @return @a this.
+ *
+ * If predicate is never true the view is cleared.
+ */
+ template <typename F> self_type &remove_suffix_if(F const &pred);
+
+ /** Remove and return a suffix of size @a n.
+ *
+ * @param n Size of the suffix.
+ * @return The first @a n bytes of @a this if @a n is in @a this, otherwise an empty view.
+ *
+ * The prefix is removed and returned if the requested suffix is no larger than @a this,
+ * otherwise @a this is not modified.
+ *
+ * @note The character at offset @a n is discarded if @a this is modified.
+ *
+ * @see @c take_suffix
+ */
+ self_type split_suffix(size_t n);
+
+ /** Remove and return a suffix bounded by the last occurrence of @a c.
+ *
+ * @param c The character to match.
+ * @return The suffix bounded by @a c if @a c is found, an empty view if not.
+ *
+ * The suffix is removed and returned if @a c is found, otherwise @a this is not modified.
+ *
+ * @note The character at offset @a n is discarded if @a this is modified.
+ *
+ * @see @c take_suffix_at
+ */
+ self_type split_suffix_at(char c);
+
+ /** Remove and return a suffix bounded by the last occurrence of any of @a delimiters.
+ *
+ * @param delimiters The characters to match.
+ * @return The suffix bounded by a delimiter if found, an empty view if none found.
+ *
+ * The suffix is removed and returned if delimiter is found, otherwise @a this is not modified.
+ *
+ * @note The delimiter character is discarded if @a this is modified.
+ *
+ * @see @c take_suffix_at
+ */
+ self_type split_suffix_at(std::string_view const &delimiters);
+
+ /** Remove and return a suffix bounded by the last character that satisfies @a pred.
+ *
+ * @tparam F Predicate functor type.
+ * @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 @a this
+ * is not modified.
+ *
+ * The prefix is removed and returned if a character satisfying @a pred if found, otherwise
+ * @a this is not modified.
+ *
+ * @note The matching character is discarded if @a this is modified.
+ *
+ * @see @c take_suffix_if
+ */
+ template <typename F> self_type split_suffix_if(F const &pred);
+
+ /** Remove and return a suffix of size @a n.
+ *
+ * @param n Size of the suffix.
+ * @return The first @a n bytes of @a this if @a n is in @a this, otherwise all of @a this.
+ *
+ * The returned suffix is removed from @a this, along with the character at offset @a n if present.
+ *
+ * @see @c split_suffix
+ */
+ self_type take_suffix(size_t n);
+
+ /** Remove and return a suffix bounded by the last occurrence of @a c.
+ *
+ * @param c The character to match.
+ * @return The suffix bounded by @a c if @a c is found, all of @a this if not.
+ *
+ * The returned suffix is removed from @a this, along with the delimiter character if found.
+ *
+ * @see @c split_suffix_at
+ */
+ self_type take_suffix_at(char c);
+
+ /** Remove and return a suffix bounded by the last occurrence of any of @a delimiters.
+ *
+ * @param delimiters The characters to match.
+ * @return The suffix bounded by a delimiter if @a c is found, all of @a this if not.
+ *
+ * The returned suffix is removed from @a this, along with the delimiter character if found.
+ *
+ * @see @c split_suffix_at
+ */
+ self_type take_suffix_at(std::string_view const &delimiters);
+
+ /** Remove and return a suffix bounded by the last character that satisfies @a pred.
+ *
+ * @tparam F Predicate functor type.
+ * @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.
+ *
+ * @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.
+ *
+ * @note This is very similar to @c rtrim_if but returns the removed text instead of the modified
+ * view.
+ */
+ 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.
+ * @param count Number of bytes in the view.
+ * @return The view starting at @a pos for @a count bytes.
+ *
+ * The returned view is clipped by @a this - that is, it will not extend beyond the original view.
+ * @a count is reduced such that it covers only data in @a this.
+ *
+ * @note This is provided primarily for co-variance, i.e. the returned view is a @c TextView
+ * instead of a @c std::string_view.
+ */
+ constexpr self_type substr(size_type pos = 0, size_type count = npos) const noexcept;
+
+ /** Check if the view begins with a specific @a prefix.
+ *
+ * @param prefix String to check against @a this.
+ * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt>, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool starts_with(std::string_view const &prefix) const noexcept;
+
+ /** Check if the view begins with a specific @a prefix.
+ *
+ * @param prefix String to check against @a this.
+ * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt>, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool starts_with(char const *prefix) const;
+
+ /** Check if the view begins with the character @c c.
+ *
+ * @param c Character to check.
+ * @return @c true if the string is non-empty and the first character is @c c.
+ * @internal C++20 preview.
+ */
+ bool starts_with(char c) const noexcept;
+
+ /** Check if the view begins with a specific @a prefix, ignoring case.
+ *
+ * @param prefix String to check against @a this.
+ * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt> without regard to case, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool starts_with_nocase(std::string_view const &prefix) const noexcept;
+
+ /** Check if the view begins with a specific @a prefix.
+ *
+ * @param prefix String to check against @a this.
+ * @return @c true if <tt>this->prefix(prefix.size()) == prefix</tt>, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool starts_with_nocase(char const *prefix) const;
+
+ /** Check if the view begins with the character @c c, ignoring case.
+ *
+ * @param c Character to check.
+ * @return @c true if the string is non-empty and the first character is @c c.
+ * @internal C++20 preview.
+ */
+ bool starts_with_nocase(char c) const noexcept;
+
+ /** Check if the view ends with a specific @a suffix.
+ *
+ * @param suffix String to check against @a this.
+ * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt>, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool ends_with(std::string_view const &suffix) const noexcept;
+
+ /** Check if the view ends with a specific @a suffix.
+ *
+ * @param suffix String to check against @a this.
+ * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt>, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool ends_with(char const *suffix) const;
+
+ /** Check the view ends with the character @c c.
+ *
+ * @param c Character to check.
+ * @return @c true if the string is non-empty and the last character is @c c.
+ * @internal C++20 preview.
+ */
+ bool ends_with(char c) const noexcept;
+
+ /** Check if the view starts with a specific @a suffix, ignoring case.
+ *
+ * @param suffix String to check against @a this.
+ * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt> without regard to case, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool ends_with_nocase(std::string_view const &suffix) const noexcept;
+
+ /** Check if the view starts with a specific @a suffix, ignoring case.
+ *
+ * @param suffix String to check against @a this.
+ * @return @c true if <tt>this->suffix(suffix.size()) == suffix</tt> without regard to case, @c false otherwise.
+ * @internal C++20 preview.
+ */
+ bool ends_with_nocase(char const *suffix) const;
+
+ /** Check the view ends with the character @c c, ignoring case.
+ *
+ * @param c Character to check.
+ * @return @c true if the string is non-empty and the last character is @c c.
+ * @internal C++20 preview.
+ */
+ bool ends_with_nocase(char c) const noexcept;
+
+ // Functors for using this class in STL containers.
+ /// Ordering functor, lexicographic comparison.
+ struct LessThan {
+ /// @return Case sensitive ordering.
+ bool
+ operator()(self_type const &lhs, self_type const &rhs) const noexcept
+ {
+ return -1 == strcmp(lhs, rhs);
+ }
+ };
+
+ /// Ordering functor, case ignoring lexicographic comparison.
+ struct LessThanNoCase {
+ /// @return Case insensitive ordering.
+ bool
+ operator()(self_type const &lhs, self_type const &rhs) const noexcept
+ {
+ return -1 == strcasecmp(lhs, rhs);
+ }
+ };
+
+ /// Support for containers that need case insensitive comparisons between views.
+ struct CaselessEqual {
+ /// @return @c true if the view contants are equal when compared without regard to case.
+ bool
+ operator()(self_type const &lhs, self_type const &rhs) const noexcept
+ {
+ return lhs.size() == rhs.size() && 0 == strcasecmp(lhs, rhs);
+ }
+ };
+
+ /** A pointer to the first byte.
+ *
+ * @return Address of the first byte of the view.
+ *
+ * @internal This fixes an error in @c std::string_view where this method is declared to return
+ * a template parameter instead of the correct @c value_type. The effect is @c string_view::data
+ * is not considered by the compiler to return <tt>char const *</tt> which makes meta-programming
+ * painful.
+ */
+ constexpr value_type const *data() const noexcept;
+
+ /** A pointer to past the last byte.
+ *
+ * @return Address of the first byte past the end of the view.
+ *
+ * This is effectively @c std::string_view::end() except it explicit returns a pointer and not
+ * (potentially) an iterator class, to match up with @c data().
+ */
+ constexpr value_type const *data_end() const noexcept;
+
+ /// Specialized stream operator implementation.
+ /// @note Use the standard stream operator unless there is a specific need for this, which is unlikely.
+ /// @return The stream @a os.
+ /// @internal Needed because @c std::ostream::write must be used and
+ /// so alignment / fill have to be explicitly handled.
+ template <typename Stream> Stream &stream_write(Stream &os, const TextView &b) const;
+
+ /// @cond OVERLOAD
+ // These methods are all overloads of other methods, defined in order to make the API more
+ // convenient to use. Mostly these overload @c int for @c size_t so naked numbers work as expected.
+ constexpr self_type prefix(int n) const noexcept;
+ self_type take_suffix(int n);
+ self_type split_prefix(int n);
+ constexpr self_type suffix(int n) const noexcept;
+ self_type split_suffix(int n);
+ /// @endcond
+
+ protected:
+ /// Initialize a bit mask to mark which characters are in this view.
+ static void init_delimiter_set(std::string_view const &delimiters, std::bitset<256> &set);
+ };
- /** Check if character is in the charset.
- *
- * @param c Character to check.
- * @return @c true if @a c is in the charset, @c false if not.
- */
- bool operator()(unsigned char c) const;
+ /// Internal table of digit values for characters.
+ /// This is -1 for characters that are not valid digits.
+ extern const int8_t svtoi_convert[256];
- /** Check if character is in the charset.
- *
- * @param c Character to check.
- * @return @c true if @a c is in the charset, @c false if not.
- */
- bool operator()(char c) const;
+ /** Convert the text in @c TextView @a src to a signed numeric value.
-protected:
- std::bitset<std::numeric_limits<unsigned char>::max() + 1> _chars;
-};
+ If @a parsed is non-null then the part of the string actually parsed is placed there.
+ @a base sets the conversion base. If not set base 10 is used with two special cases:
-/** A read only view of a contiguous piece of memory.
-
- A @c TextView does not own the memory to which it refers, it is simply a view of part of some
- (presumably) larger memory object. The purpose is to allow working in a read only way a specific
- part of the memory. A classic example for ATS is working with HTTP header fields and values
- which need to be accessed independently but preferably without copying. A @c TextView supports
- this style.
-
- @note To simplify the interface there is no constructor taking only a character pointer.
- Constructors require either a literal string or an explicit length. This avoid ambiguities which
- are much more annoying that explicitly calling @c strlen on a character pointer.
-
- @internal For construction, assignment operator, and @c assign method, there are a lot of overloads
- because users would like to be able to use the same sort of arguments for all of these. This includes
- - self / parent type
- - @c std::string
- - literal string
- - C-string pointer
- - pointer and count
- - begin/end style pointers.
- - character containers that have the STL standard @c size and @c data methods.
- */
-class TextView : public std::string_view {
- using self_type = TextView; ///< Self reference type.
- using super_type = std::string_view; ///< Parent type.
+ - If the number starts with a literal '0' then it is treated as base 8.
+ - If the number starts with the literal characters '0x' or '0X' then it is treated as base 16.
-public:
- /// Default constructor (empty buffer).
- constexpr TextView() noexcept = default;
+ If @a base is explicitly set then any leading radix indicator is not supported.
+ */
+ intmax_t svtoi(TextView src, TextView *parsed = nullptr, int base = 0);
- /// Construct from a @c std::string_view or @c TextView
- /// @note This provides an user defined conversion from @c std::string_view to @c TextView. The
- /// reverse conversion is implicit in @c TextView being a subclass of @c std::string_view.
- constexpr TextView(super_type const &that) noexcept;
+ /** Convert the text in @c TextView @a src to an unsigned numeric value.
- /** Construct from pointer and size.
- *
- * @param ptr Pointer to first character.
- * @param n Number of characters.
- *
- * If @a n is @c npos then @c ptr is presumed to be a C string and checked for length. If @c ptr
- * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
- */
- constexpr TextView(char const *ptr, size_t n) noexcept;
+ If @a parsed is non-null then the part of the string actually parsed is placed there.
+ @a base sets the conversion base. If not set base 10 is used with two special cases:
- /** Construct from pointer and size.
- *
- * @param ptr Pointer to first character.
- * @param n Number of characters.
- */
- constexpr TextView(char const *ptr, unsigned n) noexcept;
+ - If the number starts with a literal '0' then it is treated as base 8.
+ - If the number starts with the literal characters '0x' or '0X' then it is treated as base 16.
- /** Construct from pointer and size.
- *
- * @param ptr Pointer to first character.
- * @param n Number of characters.
- *
- * If @a n is negative then @c ptr is presumed to be a C string and checked for length. If @c ptr
- * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
- */
- constexpr TextView(char const *ptr, ssize_t n) noexcept;
+ If @a base is explicitly set then any leading radix indicator is not supported.
+ */
+ uintmax_t svtou(TextView src, TextView *parsed = nullptr, int base = 0);
+
+ /** Convert the text in @c src to an unsigned numeric value.
+ *
+ * @tparam N The radix (must be 1..36)
+ * @param src The source text. Updated during parsing.
+ * @return The converted numeric value.
+ *
+ * This is a specialized function useful only where conversion performance is critical. It is used
+ * inside @c svtoi and @a svtou for the common cases of 8, 10, and 16, therefore normally this isn't much more
+ * performant in those cases than just @c svtoi. Because of this only positive values are parsed.
+ * If determining the radix from the text or signed value parsing is needed, used @c svtoi.
+ *
+ * @a src is updated in place to indicate what characters were parsed by removing them from the view
+ * Parsing stops on the first invalid digit, so any leading non-digit characters (e.g. whitespace)
+ * must already be removed. For overflow, all valid digits are consumed and the maximum value returned.
+ */
+ template <int RADIX>
+ uintmax_t
+ svto_radix(TextView &src)
+ {
+ static_assert(1 <= RADIX && RADIX <= 36, "Radix must be in the range 2..36");
+ static constexpr auto MAX = std::numeric_limits<uintmax_t>::max();
+ static constexpr auto OVERFLOW_LIMIT = MAX / RADIX;
+ uintmax_t zret = 0;
+ uintmax_t v;
+ while (src.size() && ((v = swoc::svtoi_convert[uint8_t(*src)]) < RADIX)) {
+ // Tweaked for performance - need to check range after @a RADIX multiply.
+ ++src; // Update view iff the character is parsed.
+ if (zret <= OVERFLOW_LIMIT && v <= (MAX - (zret *= RADIX))) {
+ zret += v;
+ } else {
+ zret = MAX; // clamp to max - once set will always hit this case for subsequent input.
+ }
+ }
+ return zret;
+ }
- /** Construct from pointer and size.
- *
- * @param ptr Pointer to first character.
- * @param n Number of characters.
- *
- * If @a n is negative then @c ptr is presumed to be a C string and checked for length. If @c ptr
- * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
- */
- constexpr TextView(char const *ptr, int n) noexcept;
+ /// Convenience overload.
+ /// @see svto_radix(swoc::TextView &src)
+ template <int N>
+ uintmax_t
+ svto_radix(TextView &&src)
+ {
+ return svto_radix<N>(src);
+ }
- /** Construct from a half open range [first, last).
+ /** Parse @a text as a floating point number.
*
- * @param first Start of half open range.
- * @param last End of half open range.
+ * @param text The input text.
+ * @param parsed Parsed text [out]
+ * @return The floating point value, or 0.0 if invalid input.
*
- * The character at @a first will be in the view, but the character at @a last will not.
+ * If @a parsed is not @a nullptr then the span of characters parsed is put there. This can be
+ * used to check if the parse was scuccesful - on a failed parse, it will be empty.
*
- * @note @c explicit to avoid interpreting a string initializer list as a view.
- *
- * @internal For the love of Turing, WHY DID YOU DO THIS?
- *
- * Well, estemed reader, because the C++ standard doesn't have a better way to support overloads
- * that handle character pointers and literal strings differently. If the parameters were simply
- * <tt>(char const *, char const *)</tt> then a construct like <tt>{ "really", "broken" }</tt> can
- * be interpreted as a @c TextView because the elements implicitly convert to <tt>char const
- * *</tt>. This makes no sense and creates some @b very annoying ambiguities for lists of strings
- * if there are exactly two in the list. See @c Lexicon for an example.
- *
- * The template itself does the check to make sure it's a character @b pointer and not an array. Arrays
- * are handled by a different constructor so this only disables constructing from two char arrays
- * which IMHO makes no sense and should be forbidden.
+ * @note This should be within 1 epsilon of correct, although it doesn't guarantee picking
+ * the closest epsilon. It's more than sufficient for use in configurations, but possibly
+ * not for high precision work.
*/
- template <typename T>
- explicit TextView(
- T first,
- std::enable_if_t<!std::is_array_v<T> && std::is_pointer_v<T> && std::is_convertible_v<T, char const *>, T> last) noexcept
- : super_type(first, last - first) {}
+ double svtod(TextView text, TextView *parsed = nullptr);
+ // ----------------------------------------------------------
+ // Inline implementations.
+ // Note: Why, you may ask, do I use @c TextView::self_type for return type instead of the
+ // simpler plain @c TextView ? Because otherwise Doxygen can't match up the declaration and
+ // definition and the reference documentation is messed up. Sigh.
- /** Construct from any character container following STL standards.
- *
- * @tparam C Container type.
- * @param c container
- *
- * The container type must have the methods @c data and @c size which must return values convertible
- * to @c char @c const @c * and @c size_t respectively.
- */
- template <typename C, typename = std::enable_if_t<std::is_convertible_v<decltype(std::declval<C>().data()), char const *> &&
- std::is_convertible_v<decltype(std::declval<C>().size()), size_t>,
- void>>
- constexpr TextView(C const &c);
+ inline constexpr CharSet::CharSet(TextView const &chars)
+ {
+ for (auto c : chars) {
+ _chars[uint8_t(c)] = true;
+ }
+ }
- /** Construct from literal string or array.
+ inline bool
+ CharSet::operator()(unsigned char c) const
+ {
+ return _chars[c];
+ }
- All elements of the array are included in the view unless the last element is nul, in which case it is elided.
- If this is inappropriate then a constructor with an explicit size should be used.
+ inline bool
+ CharSet::operator()(char c) const
+ {
+ return _chars[uint8_t(c)];
+ }
- @code
- TextView a("A literal string");
- @endcode
- The last character in @a a will be 'g'.
- */
- template <size_t N> constexpr TextView(const char (&s)[N]) noexcept;
+ // === TextView Implementation ===
+ /// @cond TextView_INTERNAL
+ // Doxygen doesn't match these up well due to various type and template issues.
+ // @internal If there is more than one overload for numeric types, it's easy to get ambiguity. The only
+ // fix, unfortunately, is lots of overloads to cover the ambiguous cases.
+ inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
+ : super_type(ptr, n == npos ? (ptr ? ::strlen(ptr) : 0) : n)
+ {
+ }
+ inline constexpr TextView::TextView(const char *ptr, int n) noexcept
+ : super_type(ptr, n < 0 ? (ptr ? ::strlen(ptr) : 0) : size_t(n))
+ {
+ }
Review Comment:
In addition to introducing ambiguity, removing the `unsigned` overload silently changes runtime semantics for callers that pass an `unsigned` value on platforms where the call now binds to `TextView(char const*, int)`. The removed `unsigned` overload unconditionally used `size_t(n)` (no sentinel check), whereas the surviving `int` overload treats negative values as a request to `strlen()` the pointer. Any `unsigned` value with the high bit set will now be converted to a negative `int` and trigger a `strlen()` over `ptr`, which is a behavioral change (and a likely out-of-bounds read if `ptr` is not a C string). The same concern applies to the removed `ssize_t` overload on platforms where calls re-bind to the `int` overload via narrowing. Please preserve the previous semantics — e.g., by keeping the dedicated `unsigned`/`ssize_t` overloads behind a SFINAE/`if constexpr` guard that only enables them when they don't collide with `size_t`/`int`.
##########
lib/swoc/include/swoc/TextView.h:
##########
@@ -32,2082 +38,2201 @@
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
-namespace swoc { inline namespace SWOC_VERSION_NS {
+namespace swoc
+{
+inline namespace SWOC_VERSION_NS
+{
+
+ class TextView;
+
+ /** A set of characters.
+ *
+ */
+ class CharSet
+ {
+ using self_type = CharSet;
+
+ public:
+ /** Construct from character sequence.
+ *
+ * @param chars Character sequence.
+ *
+ * The charset becomes @c true for every character in the sequence.
+ */
+ constexpr CharSet(TextView const &chars);
+
+ /** Check if character is in the charset.
+ *
+ * @param c Character to check.
+ * @return @c true if @a c is in the charset, @c false if not.
+ */
+ bool operator()(unsigned char c) const;
+
+ /** Check if character is in the charset.
+ *
+ * @param c Character to check.
+ * @return @c true if @a c is in the charset, @c false if not.
+ */
+ bool operator()(char c) const;
+
+ protected:
+ std::bitset<std::numeric_limits<unsigned char>::max() + 1> _chars;
+ };
-class TextView;
+ /** A read only view of a contiguous piece of memory.
+
+ A @c TextView does not own the memory to which it refers, it is simply a view of part of some
+ (presumably) larger memory object. The purpose is to allow working in a read only way a specific
+ part of the memory. A classic example for ATS is working with HTTP header fields and values
+ which need to be accessed independently but preferably without copying. A @c TextView supports
+ this style.
+
+ @note To simplify the interface there is no constructor taking only a character pointer.
+ Constructors require either a literal string or an explicit length. This avoid ambiguities which
+ are much more annoying that explicitly calling @c strlen on a character pointer.
+
+ @internal For construction, assignment operator, and @c assign method, there are a lot of overloads
+ because users would like to be able to use the same sort of arguments for all of these. This includes
+ - self / parent type
+ - @c std::string
+ - literal string
+ - C-string pointer
+ - pointer and count
+ - begin/end style pointers.
+ - character containers that have the STL standard @c size and @c data methods.
+ */
+ class TextView : public std::string_view
+ {
+ using self_type = TextView; ///< Self reference type.
+ using super_type = std::string_view; ///< Parent type.
+
+ public:
+ /// Default constructor (empty buffer).
+ constexpr TextView() noexcept = default;
+
+ /// Construct from a @c std::string_view or @c TextView
+ /// @note This provides an user defined conversion from @c std::string_view to @c TextView. The
+ /// reverse conversion is implicit in @c TextView being a subclass of @c std::string_view.
+ constexpr TextView(super_type const &that) noexcept;
+
+ /** Construct from pointer and size.
+ *
+ * @param ptr Pointer to first character.
+ * @param n Number of characters.
+ *
+ * If @a n is @c npos then @c ptr is presumed to be a C string and checked for length. If @c ptr
+ * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
+ */
+ constexpr TextView(char const *ptr, size_t n) noexcept;
+
+ /** Construct from pointer and size.
+ *
+ * @param ptr Pointer to first character.
+ * @param n Number of characters.
+ *
+ * If @a n is negative then @c ptr is presumed to be a C string and checked for length. If @c ptr
+ * is @c nullptr the length is 0. Otherwise @c strlen is used to calculate the length.
+ */
+ constexpr TextView(char const *ptr, int n) noexcept;
Review Comment:
Reducing the overload set to only `(char const*, size_t)` and `(char const*, int)` fixes the 32-bit redeclaration error, but it newly introduces overload ambiguity on 64-bit platforms for any caller that passes a length argument whose type is neither exactly `int` nor exactly `size_t`. On LP64 (the common 64-bit Linux/macOS ABI):
- `size_t` is `unsigned long`, `int` is `int`.
- A `long` (which is the typedef for `ssize_t`) → either overload requires an integer conversion of equal rank → ambiguous call.
- An `unsigned` → either overload requires an integer conversion of equal rank → ambiguous call.
- A `long long`, `unsigned long long`, etc. → same ambiguity.
So callers that previously compiled by binding to the dedicated `ssize_t` or `unsigned` overload will now fail to compile on 64-bit, trading one build break for another. The original four-overload design was deliberate exactly to avoid this (see the `@internal` note retained at lines 1129–1130). A safer fix is to keep the four overloads but disambiguate the duplicates on 32-bit using a single template / `std::conditional_t` / `if constexpr` based on whether `size_t` and `unsigned` (and `int` and `ssize_t`) are the same type, e.g. via `std::enable_if_t<!std::is_same_v<unsigned, size_t>>` SFINAE on the `unsigned` and `ssize_t` overloads. That preserves the existing public API on both 32- and 64-bit while resolving the redeclaration.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "JosiahWI (via GitHub)" <gi...@apache.org>.
JosiahWI commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-5060150059
Yes, please make the changes against the upstream repo to simplify dependency management.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4661843381
This PR has been open for about three weeks. Is there anything I can address to help move the review forward? The remaining concern seems to be around the AuTest portion. May be investigate further where in Jenkins why this PR has not passed ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-5060229006
Hi Josiah,
Thanks for letting me know what the next steps are to follow now I know that the fix will not impact on the downstream.
Thanks
Graham
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "brbzull0 (via GitHub)" <gi...@apache.org>.
brbzull0 commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4548755789
>The reason for the 2k code changes is due to I formatted the file with clang format and it has been committed not been well formatted, so I fixed it.
I'd definitelly not have both in the same PR. Formatting is different because that it is/was originally an external library: [libswoc](https://github.com/SolidWallOfCode/libswoc)
It's excluded from the Format AFAIK, so it has his own formating style.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "bneradt (via GitHub)" <gi...@apache.org>.
bneradt commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4545209907
Note, we see this in the CI failures:
```
FAILED: lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_MemArena.cc.o
/usr/sbin/ccache /usr/sbin/c++ -DDEBUG -DOPENSSL_API_COMPAT=10002 -DOPENSSL_IS_OPENSSL3 -DPACKAGE_NAME="\"Apache Traffic Server\"" -DPACKAGE_VERSION=\"11.0.0\" -D_DEBUG -Dlinux -I/home/jenkins/workspace/Github_Builds/autest/src/include -I/home/jenkins/workspace/Github_Builds/autest/src/build/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/swoc/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/Catch2/src/catch2/.. -I/home/jenkins/workspace/Github_Builds/autest/src/build/lib/Catch2/generated-includes -pthread -g -std=c++17 -DENABLE_SYSTEMTAP_PROBES -Wno-invalid-offsetof -Wno-shadow -Wall -Wextra -Werror -Wno-unused-parameter -Wno-format-truncation -Wno-unused-variable -Wno-error=parentheses -Werror -MD -MT lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_MemArena.cc.o -MF lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_MemArena.cc.o.d -o lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_MemArena.cc.o -c /home/jenkins/workspace/Github_Builds/au
test/src/lib/swoc/unit_tests/test_MemArena.cc
../lib/swoc/unit_tests/test_MemArena.cc: In function 'void CATCH2_INTERNAL_TEST_12()':
../lib/swoc/unit_tests/test_MemArena.cc:334:15: error: conversion from '<brace-enclosed initializer list>' to 'const swoc::_1_5_15::TextView' is ambiguous
334 | localize(*arena, {buffer, n});
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
../lib/swoc/unit_tests/test_MemArena.cc:334:15: note: there are 2 candidates
In file included from ../lib/swoc/include/swoc/MemArena.h:23,
from ../lib/swoc/unit_tests/test_MemArena.cc:29:
../lib/swoc/include/swoc/TextView.h:1135:20: note: candidate 1: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, int)'
1135 | inline constexpr TextView::TextView(const char *ptr, int n) noexcept
| ^~~~~~~~
../lib/swoc/include/swoc/TextView.h:1131:20: note: candidate 2: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, size_t)'
1131 | inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
| ^~~~~~~~
../lib/swoc/unit_tests/test_MemArena.cc:46:43: note: initializing argument 2 of 'swoc::_1_5_15::TextView {anonymous}::localize(swoc::_1_5_15::MemArena&, const swoc::_1_5_15::TextView&)'
46 | localize(MemArena &arena, TextView const &view) {
| ~~~~~~~~~~~~~~~~^~~~
../lib/swoc/unit_tests/test_MemArena.cc:350:15: error: conversion from '<brace-enclosed initializer list>' to 'const swoc::_1_5_15::TextView' is ambiguous
350 | localize(*arena, {buffer, n});
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
../lib/swoc/unit_tests/test_MemArena.cc:350:15: note: there are 2 candidates
../lib/swoc/include/swoc/TextView.h:1135:20: note: candidate 1: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, int)'
1135 | inline constexpr TextView::TextView(const char *ptr, int n) noexcept
| ^~~~~~~~
../lib/swoc/include/swoc/TextView.h:1131:20: note: candidate 2: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, size_t)'
1131 | inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
| ^~~~~~~~
../lib/swoc/unit_tests/test_MemArena.cc:46:43: note: initializing argument 2 of 'swoc::_1_5_15::TextView {anonymous}::localize(swoc::_1_5_15::MemArena&, const swoc::_1_5_15::TextView&)'
46 | localize(MemArena &arena, TextView const &view) {
| ~~~~~~~~~~~~~~~~^~~~
../lib/swoc/unit_tests/test_MemArena.cc:365:15: error: conversion from '<brace-enclosed initializer list>' to 'const swoc::_1_5_15::TextView' is ambiguous
365 | localize(*arena, {buffer, n});
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
../lib/swoc/unit_tests/test_MemArena.cc:365:15: note: there are 2 candidates
../lib/swoc/include/swoc/TextView.h:1135:20: note: candidate 1: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, int)'
1135 | inline constexpr TextView::TextView(const char *ptr, int n) noexcept
| ^~~~~~~~
../lib/swoc/include/swoc/TextView.h:1131:20: note: candidate 2: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, size_t)'
1131 | inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
| ^~~~~~~~
../lib/swoc/unit_tests/test_MemArena.cc:46:43: note: initializing argument 2 of 'swoc::_1_5_15::TextView {anonymous}::localize(swoc::_1_5_15::MemArena&, const swoc::_1_5_15::TextView&)'
46 | localize(MemArena &arena, TextView const &view) {
| ~~~~~~~~~~~~~~~~^~~~
../lib/swoc/unit_tests/test_MemArena.cc: At global scope:
../lib/swoc/unit_tests/test_MemArena.cc:46:1: error: 'swoc::_1_5_15::TextView {anonymous}::localize(swoc::_1_5_15::MemArena&, const swoc::_1_5_15::TextView&)' defined but not used [-Werror=unused-function]
46 | localize(MemArena &arena, TextView const &view) {
| ^~~~~~~~
cc1plus: all warnings being treated as errors
[646/1599] /usr/sbin/ccache /usr/sbin/c++ -DDEBUG -DOPENSSL_API_COMPAT=10002 -DOPENSSL_IS_OPENSSL3 -DPACKAGE_NAME="\"Apache Traffic Server\"" -DPACKAGE_VERSION=\"11.0.0\" -D_DEBUG -Dlinux -I/home/jenkins/workspace/Github_Builds/autest/src/include -I/home/jenkins/workspace/Github_Builds/autest/src/build/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/swoc/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/Catch2/src/catch2/.. -I/home/jenkins/workspace/Github_Builds/autest/src/build/lib/Catch2/generated-includes -pthread -g -std=c++17 -DENABLE_SYSTEMTAP_PROBES -Wno-invalid-offsetof -Wno-shadow -Wall -Wextra -Werror -Wno-unused-parameter -Wno-format-truncation -Wno-unused-variable -Wno-error=parentheses -Werror -MD -MT lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_TextView.cc.o -MF lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_TextView.cc.o.d -o lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_TextView.cc.o -c /home/jenkins/workspace/Githu
b_Builds/autest/src/lib/swoc/unit_tests/test_TextView.cc
FAILED: lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_TextView.cc.o
/usr/sbin/ccache /usr/sbin/c++ -DDEBUG -DOPENSSL_API_COMPAT=10002 -DOPENSSL_IS_OPENSSL3 -DPACKAGE_NAME="\"Apache Traffic Server\"" -DPACKAGE_VERSION=\"11.0.0\" -D_DEBUG -Dlinux -I/home/jenkins/workspace/Github_Builds/autest/src/include -I/home/jenkins/workspace/Github_Builds/autest/src/build/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/swoc/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/Catch2/src/catch2/.. -I/home/jenkins/workspace/Github_Builds/autest/src/build/lib/Catch2/generated-includes -pthread -g -std=c++17 -DENABLE_SYSTEMTAP_PROBES -Wno-invalid-offsetof -Wno-shadow -Wall -Wextra -Werror -Wno-unused-parameter -Wno-format-truncation -Wno-unused-variable -Wno-error=parentheses -Werror -MD -MT lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_TextView.cc.o -MF lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_TextView.cc.o.d -o lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/test_TextView.cc.o -c /home/jenkins/workspace/Github_Builds/au
test/src/lib/swoc/unit_tests/test_TextView.cc
../lib/swoc/unit_tests/test_TextView.cc: In function 'void CATCH2_INTERNAL_TEST_0()':
../lib/swoc/unit_tests/test_TextView.cc:31:29: error: call of overloaded 'TextView(<brace-enclosed initializer list>)' is ambiguous
31 | TextView u{base.data(), ux};
| ^
../lib/swoc/unit_tests/test_TextView.cc:31:29: note: there are 2 candidates
In file included from ../lib/swoc/unit_tests/test_TextView.cc:16:
../lib/swoc/include/swoc/TextView.h:1135:20: note: candidate 1: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, int)'
1135 | inline constexpr TextView::TextView(const char *ptr, int n) noexcept
| ^~~~~~~~
../lib/swoc/include/swoc/TextView.h:1131:20: note: candidate 2: 'constexpr swoc::_1_5_15::TextView::TextView(const char*, size_t)'
1131 | inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
| ^~~~~~~~
[647/1599] /usr/sbin/ccache /usr/sbin/c++ -DDEBUG -DOPENSSL_API_COMPAT=10002 -DOPENSSL_IS_OPENSSL3 -DPACKAGE_NAME="\"Apache Traffic Server\"" -DPACKAGE_VERSION=\"11.0.0\" -D_DEBUG -Dlinux -Dtsapi_EXPORTS -I/home/jenkins/workspace/Github_Builds/autest/src/include -I/home/jenkins/workspace/Github_Builds/autest/src/build/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/swoc/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/yamlcpp/include -isystem /opt/openssl-quic/include -pthread -g -std=c++20 -fPIC -DENABLE_SYSTEMTAP_PROBES -Wno-invalid-offsetof -pipe -Wall -Wextra -Wno-noexcept-type -Wsuggest-override -Wno-vla-extension -fno-strict-aliasing -Wno-format-truncation -Werror -MD -MT src/api/CMakeFiles/tsapi.dir/InkAPITest.cc.o -MF src/api/CMakeFiles/tsapi.dir/InkAPITest.cc.o.d -o src/api/CMakeFiles/tsapi.dir/InkAPITest.cc.o -c /home/jenkins/workspace/Github_Builds/autest/src/src/api/InkAPITest.cc
[648/1599] /usr/sbin/ccache /usr/sbin/c++ -DDEBUG -DOPENSSL_API_COMPAT=10002 -DOPENSSL_IS_OPENSSL3 -DPACKAGE_NAME="\"Apache Traffic Server\"" -DPACKAGE_VERSION=\"11.0.0\" -D_DEBUG -Dlinux -I/home/jenkins/workspace/Github_Builds/autest/src/include -I/home/jenkins/workspace/Github_Builds/autest/src/build/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/swoc/include -I/home/jenkins/workspace/Github_Builds/autest/src/lib/Catch2/src/catch2/.. -I/home/jenkins/workspace/Github_Builds/autest/src/build/lib/Catch2/generated-includes -pthread -g -std=c++17 -DENABLE_SYSTEMTAP_PROBES -Wno-invalid-offsetof -Wno-shadow -Wall -Wextra -Werror -Wno-unused-parameter -Wno-format-truncation -Wno-unused-variable -Wno-error=parentheses -Werror -MD -MT lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/ex_bw_format.cc.o -MF lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/ex_bw_format.cc.o.d -o lib/swoc/unit_tests/CMakeFiles/test_libswoc.dir/ex_bw_format.cc.o -c /home/jenkins/workspace/Github_B
uilds/autest/src/lib/swoc/unit_tests/ex_bw_format.cc
ninja: build stopped: subcommand failed.
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4534519037
Hi everyone,
I noticed this PR is failing the Jenkins AuTest stages. I investigated the failure, and it is not related to my code changes.
The `tests/prepare_proxy_verifier.sh` script has a hardcoded SHA1 hash on line 44:
`expected_sha1="e11b5867a56c5ffd496b18c901f1273e9c120a47"`
The tarball hosted at `https://ci.trafficserver.apache.org/bintray/proxy-verifier-v3.1.2.tar.gz` has apparently been repackaged. I downloaded the tarball locally, and the new correct SHA1 hash is:**
`0a60c646cbc9326abb2fbc397cb9efa8c08a807a`
Could a maintainer please update line 44 in `prepare_proxy_verifier.sh` on the master branch with this new hash? Once that is fixed, I believe this PR will pass CI.
Thank you!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "bneradt (via GitHub)" <gi...@apache.org>.
bneradt commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4544381518
[approve ci]
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "JosiahWI (via GitHub)" <gi...@apache.org>.
JosiahWI commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-5060393496
I apologize for the slow feedback; you asked about the upstream vs downstream repo already months ago. It has been a busy season for ATS, and I personally am unfamiliar with how libswoc changes are managed. I did not do a good job at communicating on this in a timely manner. Thank you for your forbearing attitude.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4547635059
Hi,
The reason for the 2k code changes is due to I formatted the file with clang format and it has been committed not been well formatted, so I fixed it.
The constructor code block section near the top of the file is the place to look and the current version on github look at this code block starting at line 1121.
```
// === TextView Implementation ===
/// @cond TextView_INTERNAL
// Doxygen doesn't match these up well due to various type and template issues.
// @internal If there is more than one overload for numeric types, it's easy to get ambiguity. The only
// fix, unfortunately, is lots of overloads to cover the ambiguous cases.
inline constexpr TextView::TextView(const char *ptr, size_t n) noexcept
: super_type(ptr, n == npos ? (ptr ? ::strlen(ptr) : 0) : n) {}
inline constexpr TextView::TextView(const char *ptr, unsigned n) noexcept : super_type(ptr, size_t(n)) {}
inline constexpr TextView::TextView(const char *ptr, ssize_t n) noexcept
: super_type(ptr, n < 0 ? (ptr ? ::strlen(ptr) : 0) : size_t(n)) {}
inline constexpr TextView::TextView(const char *ptr, int n) noexcept
: super_type(ptr, n < 0 ? (ptr ? ::strlen(ptr) : 0) : size_t(n)) {}
inline constexpr TextView::TextView(std::nullptr_t) noexcept : super_type(nullptr, 0) {}
inline TextView::TextView(std::string const &str) noexcept : super_type(str) {}
inline constexpr TextView::TextView(super_type const &that) noexcept : super_type(that) {}
template <size_t N> constexpr TextView::TextView(const char (&s)[N]) noexcept : super_type(s, s[N - 1] ? N : N - 1) {}
template <typename C, typename> constexpr TextView::TextView(C const &c) : super_type(c.data(), c.size()) {}
```
As explained I removed some code to make it compile and it does after fixing this issue. Clangd lints this error too.
Regards
Graham
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "zwoop (via GitHub)" <gi...@apache.org>.
zwoop commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4578828327
[approve ci autest 2]
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-5060548244
Hi Josiah,
No worries, it's tricky to figure it out as the commit history between both makes it hard to figure out what is going on. You have to look in the CMakeList.txt to see the version in use between both.
Regards
Graham
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-5058648979
Hi,
Makes perfect sense, thank you for the feedback! I will split this into two separate PRs: one for the non-functional changes, and I will update this current PR to contain only the compilation fix alongside the unit test. I'll work on this as my next task
Thanks
Graham
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "grahamsedman (via GitHub)" <gi...@apache.org>.
grahamsedman commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-5058167877
Hi,
The CI failure has been addressed and the latest changes are ready for review.
Over the past few days, I investigated the root cause of the failure based on the details from the original PR description. To narrow down the issue, I added a dedicated unit test at https://github.com/grahamsedman/trafficserver/blob/fix/lib-swoc-textview-constructors/lib/swoc/unit_tests/test_TextViewConstructors.cc covering the relevant constructor edge cases.
The follow-up commits fix the underlying issue, and the new test now passes cleanly. The implementation is ready for review whenever you have a chance.
Thanks,
Graham
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] PR Replacement #13185: refactor : Fix compilation errors in TextView.h by removing ambiguous constructor overloads and revised TextView.cc header includes [trafficserver]
Posted by "zwoop (via GitHub)" <gi...@apache.org>.
zwoop commented on PR #13187:
URL: https://github.com/apache/trafficserver/pull/13187#issuecomment-4633044872
[approve ci]
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: github-unsubscribe@trafficserver.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org