summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2018-06-16 20:31:40 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2018-06-16 21:06:20 +0100
commit2d9d4e7a5c19059fc6cfb55a97e46582f4ae9633 (patch)
tree5da4b7d1b1c995115bf0e6d5d98d5859aa30a5b9
parentTemplate strings don't need to be extern C++17, just constexpr (diff)
downloadlibadhocutil-2d9d4e7a5c19059fc6cfb55a97e46582f4ae9633.tar.bz2
libadhocutil-2d9d4e7a5c19059fc6cfb55a97e46582f4ae9633.tar.xz
libadhocutil-2d9d4e7a5c19059fc6cfb55a97e46582f4ae9633.zip
Add template string utils
-rw-r--r--libadhocutil/compileTimeFormatter.h27
-rw-r--r--libadhocutil/unittests/testCompileTimeFormatter.cpp37
-rw-r--r--libadhocutil/uriParse.cpp2
3 files changed, 65 insertions, 1 deletions
diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h
index 6e85f8e..d55012e 100644
--- a/libadhocutil/compileTimeFormatter.h
+++ b/libadhocutil/compileTimeFormatter.h
@@ -7,6 +7,33 @@
#include "unique.h"
namespace AdHoc {
+ // Template string utils
+ template<const auto & S>
+ static constexpr auto strlen()
+ {
+ auto off = 0;
+ while (S[off]) { ++off; }
+ return off;
+ }
+
+ template<const auto & S, auto n, auto start = 0, auto L = strlen<S>()>
+ static constexpr int strchr()
+ {
+ static_assert(start <= L);
+ decltype(start) off = start;
+ while (off < L && S[off] != n) { ++off; }
+ if (off == L) return -1;
+ return off;
+ }
+
+ template<const auto & S, auto n, auto start = 0, auto L = strlen<S>()>
+ static constexpr decltype(L) strchrnul()
+ {
+ decltype(start) off = start;
+ while (off < L && S[off] != n) { ++off; }
+ return off;
+ }
+
/// @cond
inline constexpr int WRAP_AT = 120;
diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp
index cb49bd2..59d63d0 100644
--- a/libadhocutil/unittests/testCompileTimeFormatter.cpp
+++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp
@@ -73,6 +73,43 @@ namespace AdHoc {
};
}
+// Compile string util assertions
+static_assert(strlen<formatEdgeCaseEmpty>() == 0);
+static_assert(strlen<formatEdgeCaseSingle>() == 1);
+static_assert(strlen<formatEdgeCaseFormatLonely>() == 2);
+static_assert(strlen<formatStringLiteral>() == 7);
+static_assert(strlen<formatStringLong>() == 246);
+
+static_assert(strchr<formatEdgeCaseEmpty, 't'>() == -1);
+static_assert(strchr<formatEdgeCaseSingle, 't'>() == -1);
+static_assert(strchr<formatEdgeCaseSingle, '1'>() == 0);
+static_assert(strchr<formatEdgeCaseFormatLonely, '%'>() == 0);
+static_assert(strchr<formatEdgeCaseFormatLonely, '?'>() == 1);
+static_assert(strchr<formatStringLiteral, 'e'>() == 3);
+static_assert(strchr<formatStringLiteral, 'f'>() == -1);
+static_assert(strchr<formatStringLiteral, 'e', 3>() == 3);
+static_assert(strchr<formatStringLiteral, 'e', 4>() == -1);
+static_assert(strchr<formatStringLiteral, 'f', 3>() == -1);
+
+static_assert(strchrnul<formatEdgeCaseEmpty, 't'>() == 0);
+static_assert(strchrnul<formatEdgeCaseSingle, 't'>() == 1);
+static_assert(strchrnul<formatEdgeCaseSingle, '1'>() == 0);
+static_assert(strchrnul<formatEdgeCaseFormatLonely, '%'>() == 0);
+static_assert(strchrnul<formatEdgeCaseFormatLonely, '?'>() == 1);
+static_assert(strchrnul<formatStringLiteral, 'e'>() == 3);
+static_assert(strchrnul<formatStringLiteral, 'f'>() == 7);
+static_assert(strchrnul<formatStringLiteral, 'e', 3>() == 3);
+static_assert(strchrnul<formatStringLiteral, 'e', 4>() == 7);
+static_assert(strchrnul<formatStringLiteral, 'f', 3>() == 7);
+
+static_assert(strchrnul<formatEdgeCaseEmpty, 't'>() == 0);
+static_assert(strchrnul<formatEdgeCaseSingle, 't'>() == 1);
+static_assert(strchrnul<formatEdgeCaseSingle, '1'>() == 0);
+static_assert(strchrnul<formatEdgeCaseFormatLonely, '%'>() == 0);
+static_assert(strchrnul<formatEdgeCaseFormatLonely, '?'>() == 1);
+static_assert(strchrnul<formatStringLiteral, 'e'>() == 3);
+static_assert(strchrnul<formatStringLiteral, 'f'>() == 7);
+
BOOST_FIXTURE_TEST_SUITE( TestStreamWrite, std::stringstream )
BOOST_AUTO_TEST_CASE ( empty )
diff --git a/libadhocutil/uriParse.cpp b/libadhocutil/uriParse.cpp
index 4d41937..c42f133 100644
--- a/libadhocutil/uriParse.cpp
+++ b/libadhocutil/uriParse.cpp
@@ -19,7 +19,7 @@ namespace AdHoc {
curstr = uri.c_str();
- const char * tmpstr = strchr(curstr, ':');
+ const char * tmpstr = ::strchr(curstr, ':');
if (!tmpstr) {
throw InvalidUri("Schema marker not found", uri);
}