From 5eb8e3eac010c322a23c3f351f90177639f0df5a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 22 Mar 2020 11:19:08 +0000 Subject: Wrap Formatter with as FormatterDetail Fixes some signedness issues around searching strings. --- libadhocutil/compileTimeFormatter.h | 36 ++++++++++++++-------- .../unittests/testCompileTimeFormatter.cpp | 26 ++++++++-------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h index 09fdb6a..0a86946 100644 --- a/libadhocutil/compileTimeFormatter.h +++ b/libadhocutil/compileTimeFormatter.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include "unique.h" @@ -26,24 +27,32 @@ namespace AdHoc { template static constexpr auto strlen() { - auto off = 0; + auto off = 0U; while (S[off]) { ++off; } return off; } - template()> - static constexpr auto strchr() + template + static constexpr auto strlen(const char_type * S) + { + auto off = 0U; + while (S[off]) { ++off; } + return off; + } + + template()> + static constexpr std::optional strchr() { static_assert(start <= L); decltype(start) off = start; while (off < L && S[off] != n) { ++off; } if (off == L) { - return -1; + return {}; } return off; } - template()> + template()> static constexpr decltype(L) strchrnul() { decltype(start) off = start; @@ -51,7 +60,7 @@ namespace AdHoc { return off; } - template())> class Formatter; + template class FormatterDetail; /// Template used to apply parameters to a stream. template @@ -71,7 +80,7 @@ namespace AdHoc { template static inline void next(stream & s, const Pn & ... pn) { - Formatter::template Parser::run(s, pn...); + FormatterDetail::template Parser::run(s, pn...); } }; @@ -121,8 +130,8 @@ namespace AdHoc { * Compile time string formatter. * @param S the format string. */ - template ()) L = strlen()> - class Formatter { + template + class FormatterDetail { private: using strlen_t = decltype(strlen()); template friend struct StreamWriterBase; @@ -161,7 +170,7 @@ namespace AdHoc { template static inline stream & write(stream & s, const Pn & ... pn) { - return Parser::run(s, pn...); + return Parser::run(s, pn...); } /** * Write the result of formatting to the given stream. @@ -193,7 +202,7 @@ namespace AdHoc { } return s; } - template + template static inline void packAndWrite(stream & s, const Pn & ... pn) { if constexpr (ph + off == L || sizeof...(Pck) == 32) { @@ -220,12 +229,15 @@ namespace AdHoc { }; template inline auto operator""_fmt() noexcept { - return AdHoc::Formatter::__FMT, sizeof...(t)>(); + return AdHoc::FormatterDetail::__FMT, sizeof...(t)>(); } #ifdef __clang__ #pragma clang diagnostic pop #endif } + + template ()) L = strlen()> + class Formatter : public FormatterDetail { }; } #define AdHocFormatterTypedef(name, str, id) \ diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp index a19e588..ba8a46f 100644 --- a/libadhocutil/unittests/testCompileTimeFormatter.cpp +++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp @@ -84,16 +84,16 @@ static_assert(strlen() == 2); static_assert(strlen() == 7); static_assert(strlen() == 246); -static_assert(strchr() == -1); -static_assert(strchr() == -1); -static_assert(strchr() == 0); -static_assert(strchr() == 0); -static_assert(strchr() == 1); -static_assert(strchr() == 3); -static_assert(strchr() == -1); -static_assert(strchr() == 3); -static_assert(strchr() == -1); -static_assert(strchr() == -1); +static_assert(!strchr()); +static_assert(!strchr()); +static_assert(*strchr() == 0); +static_assert(*strchr() == 0); +static_assert(*strchr() == 1); +static_assert(*strchr() == 3); +static_assert(!strchr()); +static_assert(*strchr() == 3); +static_assert(!strchr()); +static_assert(!strchr()); static_assert(strchrnul() == 0); static_assert(strchrnul() == 1); @@ -102,9 +102,9 @@ static_assert(strchrnul() == 0); static_assert(strchrnul() == 1); static_assert(strchrnul() == 3); static_assert(strchrnul() == 7); -static_assert(strchrnul() == 3); -static_assert(strchrnul() == 7); -static_assert(strchrnul() == 7); +static_assert(strchrnul() == 3); +static_assert(strchrnul() == 7); +static_assert(strchrnul() == 7); static_assert(strchrnul() == 0); static_assert(strchrnul() == 1); -- cgit v1.2.3