diff options
| -rw-r--r-- | libadhocutil/compileTimeFormatter.h | 50 | ||||
| -rw-r--r-- | libadhocutil/unittests/Jamfile.jam | 15 | ||||
| -rw-r--r-- | libadhocutil/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 <optional>  #include <array>  #include <boost/preprocessor/variadic/size.hpp> -#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<typename char_type>  	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<typename CharT, std::size_t N> +		class basic_fixed_string : public std::array<CharT, N> { +			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<typename CharT, std::size_t N> +		basic_fixed_string(const CharT (&str)[N]) -> basic_fixed_string<CharT, N - 1>; +	} + +	template<const support::basic_fixed_string Str> +	class LiteralFormatter : public FormatterDetail<Str, Str.size()> { }; + +	template <const auto & S, decltype(strlen(S)) L = strlen(S)> +	class Formatter : public FormatterDetail<support::basic_fixed_string< +										typename std::decay<decltype(S[0])>::type, L>(S, L), L> { }; + +#define AdHocFormatter(name, str) \ +	using name = LiteralFormatter<str> + +#else +	// Classic pre-C++20 implementation +#include "unique.h"  	template <const auto & S, decltype(strlen<S>()) L = strlen<S>()>  	class Formatter : public FormatterDetail<S, L> { }; -}  #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 @@ -39,6 +39,21 @@ run  	;  run +	testCompileTimeFormatter.cpp +	: : : +	<define>ROOT=\"$(me)\" +	<define>BOOST_TEST_DYN_LINK +	<library>..//adhocutil +	<library>stdc++fs +	<library>boost_utf +	-<cxxstd>17 +	<cxxstd>2a +	<implicit-dependency>lorem-ipsum +	: +	testCompileTimeFormatter20 +	; + +run  	testUriParse.cpp  	: : :  	<define>ROOT=\"$(me)\" 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<formatEdgeCaseEmpty>() == 0);  static_assert(strlen<formatEdgeCaseSingle>() == 1); @@ -113,6 +114,7 @@ static_assert(strchrnul<formatEdgeCaseFormatLonely, '%'>() == 0);  static_assert(strchrnul<formatEdgeCaseFormatLonely, '?'>() == 1);  static_assert(strchrnul<formatStringLiteral, 'e'>() == 3);  static_assert(strchrnul<formatStringLiteral, 'f'>() == 7); +#endif  BOOST_FIXTURE_TEST_SUITE( TestStreamWrite, std::stringstream )  | 
