From a79d1a6d7434125529e2f17e382791c5617183b7 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 22 Mar 2020 12:56:22 +0000 Subject: C++ fixed string literal CTF --- libadhocutil/compileTimeFormatter.h | 50 +++++++++++++++++++++- libadhocutil/unittests/Jamfile.jam | 15 +++++++ .../unittests/testCompileTimeFormatter.cpp | 2 + 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h index 0a86946..c3837fe 100644 --- a/libadhocutil/compileTimeFormatter.h +++ b/libadhocutil/compileTimeFormatter.h @@ -6,10 +6,17 @@ #include #include #include -#include "unique.h" namespace AdHoc { +#ifdef __cpp_nontype_template_parameter_class +#define USE_FIXED_STRING +#endif + +#ifdef USE_FIXED_STRING +#define CtfString const auto +#else #define CtfString const auto & +#endif // Template char utils template constexpr bool isdigit(const char_type & ch) @@ -236,9 +243,45 @@ namespace AdHoc { #endif } +#ifdef USE_FIXED_STRING + // New C++20 implementation + namespace support { + template + class basic_fixed_string : public std::array { + public: + constexpr basic_fixed_string(const CharT (&str)[N + 1]) + { + for (decltype(N) x = 0; x < N; x++) { + this->at(x) = str[x]; + } + } + constexpr basic_fixed_string(const CharT * str, decltype(N) len) + { + for (decltype(N) x = 0; x < len; x++) { + this->at(x) = str[x]; + } + } + }; + + template + basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string; + } + + template + class LiteralFormatter : public FormatterDetail { }; + + template + class Formatter : public FormatterDetail::type, L>(S, L), L> { }; + +#define AdHocFormatter(name, str) \ + using name = LiteralFormatter + +#else + // Classic pre-C++20 implementation +#include "unique.h" template ()) L = strlen()> class Formatter : public FormatterDetail { }; -} #define AdHocFormatterTypedef(name, str, id) \ inline constexpr auto id = str; \ @@ -247,4 +290,7 @@ namespace AdHoc { AdHocFormatterTypedef(name, str, MAKE_UNIQUE(name)) #endif +} + +#endif diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam index d62f6da..e2b1f7c 100644 --- a/libadhocutil/unittests/Jamfile.jam +++ b/libadhocutil/unittests/Jamfile.jam @@ -38,6 +38,21 @@ run lorem-ipsum ; +run + testCompileTimeFormatter.cpp + : : : + ROOT=\"$(me)\" + BOOST_TEST_DYN_LINK + ..//adhocutil + stdc++fs + boost_utf + -17 + 2a + lorem-ipsum + : + testCompileTimeFormatter20 + ; + run testUriParse.cpp : : : diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp index ba8a46f..369b804 100644 --- a/libadhocutil/unittests/testCompileTimeFormatter.cpp +++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp @@ -77,6 +77,7 @@ namespace AdHoc { }; } +#ifndef __cpp_nontype_template_parameter_class // Compile string util assertions static_assert(strlen() == 0); static_assert(strlen() == 1); @@ -113,6 +114,7 @@ static_assert(strchrnul() == 0); static_assert(strchrnul() == 1); static_assert(strchrnul() == 3); static_assert(strchrnul() == 7); +#endif BOOST_FIXTURE_TEST_SUITE( TestStreamWrite, std::stringstream ) -- cgit v1.2.3