From 506230ba5d5efb85c7bc679f3af1fa279ca24f56 Mon Sep 17 00:00:00 2001 From: Alexey Ochapov Date: Wed, 2 Dec 2020 01:14:58 +0300 Subject: [PATCH 1/6] add _cf literal as replacement for FMT_COMPILE --- include/fmt/compile.h | 34 ++++++++++++++++++++++++++++++++++ test/compile-test.cc | 8 ++++++++ 2 files changed, 42 insertions(+) diff --git a/include/fmt/compile.h b/include/fmt/compile.h index affd793e343a..e0933754b91d 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -37,6 +37,28 @@ struct is_compiled_string : std::is_base_of {}; */ #define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string) +#if defined(__cpp_nontype_template_parameter_class) && \ + (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) +template struct fixed_string { + constexpr fixed_string(const Char (&str)[N + 1]) { + copy_str(static_cast(str), str + N, + data); + } + Char data[N]{}; +}; + +template +fixed_string(const Char (&str)[N]) -> fixed_string; + +template Str> +struct udl_compiled_string : compiled_string { + using char_type = Char; + constexpr operator basic_string_view() const { + return {Str.data, N}; + } +}; +#endif + template const T& first(const T& value, const Tail&...) { return value; @@ -698,6 +720,18 @@ size_t formatted_size(const CompiledFormat& cf, const Args&... args) { return format_to(detail::counting_iterator(), cf, args...).count(); } +#if defined(__cpp_nontype_template_parameter_class) && \ + (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) +inline namespace literals { +template +constexpr detail::udl_compiled_string, + sizeof(Str.data), Str> +operator""_cf() { + return {}; +} +} // namespace literals +#endif + FMT_END_NAMESPACE #endif // FMT_COMPILE_H_ diff --git a/test/compile-test.cc b/test/compile-test.cc index 7ae28772038a..ffd2fdf0f8b9 100644 --- a/test/compile-test.cc +++ b/test/compile-test.cc @@ -179,6 +179,14 @@ TEST(CompileTest, Empty) { } #endif +#if defined(__cpp_nontype_template_parameter_class) && \ + (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) +TEST(CompileTest, CompileFormatStringLiteral) { + using namespace fmt::literals; + EXPECT_EQ("42", fmt::format("{}"_cf, 42)); +} +#endif + #if __cplusplus >= 202002L template struct test_string { template constexpr bool operator==(const T& rhs) const noexcept { From 8c8b1cc74fe7e028cadd127296abda1ef7b4f513 Mon Sep 17 00:00:00 2001 From: Alexey Ochapov Date: Wed, 2 Dec 2020 21:11:53 +0300 Subject: [PATCH 2/6] apply requested changes * `FMT_USE_NONTYPE_TEMPLATE_PARAMETERS` define added * `std::size_t` changed to `size_t` --- include/fmt/compile.h | 18 +++++++++++------- test/compile-test.cc | 3 +-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/fmt/compile.h b/include/fmt/compile.h index e0933754b91d..ea0007a469c8 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -13,6 +13,12 @@ #include "format.h" +#if !defined(FMT_USE_NONTYPE_TEMPLATE_PARAMETERS) && \ + defined(__cpp_nontype_template_parameter_class) && \ + (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) +# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#endif + FMT_BEGIN_NAMESPACE namespace detail { @@ -37,9 +43,8 @@ struct is_compiled_string : std::is_base_of {}; */ #define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string) -#if defined(__cpp_nontype_template_parameter_class) && \ - (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) -template struct fixed_string { +#ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +template struct fixed_string { constexpr fixed_string(const Char (&str)[N + 1]) { copy_str(static_cast(str), str + N, data); @@ -47,10 +52,10 @@ template struct fixed_string { Char data[N]{}; }; -template +template fixed_string(const Char (&str)[N]) -> fixed_string; -template Str> +template Str> struct udl_compiled_string : compiled_string { using char_type = Char; constexpr operator basic_string_view() const { @@ -720,8 +725,7 @@ size_t formatted_size(const CompiledFormat& cf, const Args&... args) { return format_to(detail::counting_iterator(), cf, args...).count(); } -#if defined(__cpp_nontype_template_parameter_class) && \ - (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) +#ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS inline namespace literals { template constexpr detail::udl_compiled_string, diff --git a/test/compile-test.cc b/test/compile-test.cc index ffd2fdf0f8b9..30bb7fc72f87 100644 --- a/test/compile-test.cc +++ b/test/compile-test.cc @@ -179,8 +179,7 @@ TEST(CompileTest, Empty) { } #endif -#if defined(__cpp_nontype_template_parameter_class) && \ - (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) +#ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS TEST(CompileTest, CompileFormatStringLiteral) { using namespace fmt::literals; EXPECT_EQ("42", fmt::format("{}"_cf, 42)); From 855e4887b3fdfbf6d8adbb0865a2942508d0410f Mon Sep 17 00:00:00 2001 From: Alexey Ochapov Date: Wed, 2 Dec 2020 21:15:48 +0300 Subject: [PATCH 3/6] add empty format string into CompileTest::CompileFormatStringLiteral --- test/compile-test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/compile-test.cc b/test/compile-test.cc index 30bb7fc72f87..1e6292b7235c 100644 --- a/test/compile-test.cc +++ b/test/compile-test.cc @@ -182,6 +182,7 @@ TEST(CompileTest, Empty) { #ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS TEST(CompileTest, CompileFormatStringLiteral) { using namespace fmt::literals; + EXPECT_EQ("", fmt::format(""_cf)); EXPECT_EQ("42", fmt::format("{}"_cf, 42)); } #endif From 6ea2ca8ff42a24d9c7803a60221e0de67f6d76df Mon Sep 17 00:00:00 2001 From: Alexey Ochapov Date: Wed, 2 Dec 2020 21:35:40 +0300 Subject: [PATCH 4/6] fix for empty format string --- include/fmt/compile.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fmt/compile.h b/include/fmt/compile.h index ea0007a469c8..8b1e3719af20 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -45,7 +45,7 @@ struct is_compiled_string : std::is_base_of {}; #ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS template struct fixed_string { - constexpr fixed_string(const Char (&str)[N + 1]) { + constexpr fixed_string(const Char (&str)[N]) { copy_str(static_cast(str), str + N, data); } @@ -53,13 +53,13 @@ template struct fixed_string { }; template -fixed_string(const Char (&str)[N]) -> fixed_string; +fixed_string(const Char (&str)[N]) -> fixed_string; template Str> struct udl_compiled_string : compiled_string { using char_type = Char; constexpr operator basic_string_view() const { - return {Str.data, N}; + return {Str.data, N - 1}; } }; #endif From b81bf00c9bd34da0c2eefb0a9371155f68740589 Mon Sep 17 00:00:00 2001 From: Alexey Ochapov Date: Mon, 7 Dec 2020 22:35:54 +0300 Subject: [PATCH 5/6] update FMT_USE_NONTYPE_TEMPLATE_PARAMETERS --- include/fmt/compile.h | 15 +++++++++------ test/compile-test.cc | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/fmt/compile.h b/include/fmt/compile.h index 8b1e3719af20..1332eb2121cd 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -13,10 +13,13 @@ #include "format.h" -#if !defined(FMT_USE_NONTYPE_TEMPLATE_PARAMETERS) && \ - defined(__cpp_nontype_template_parameter_class) && \ - (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) -# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#ifndef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +# if defined(__cpp_nontype_template_parameter_class) && \ + (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 903) +# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 1 +# else +# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 0 +# endif #endif FMT_BEGIN_NAMESPACE @@ -43,7 +46,7 @@ struct is_compiled_string : std::is_base_of {}; */ #define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string) -#ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS template struct fixed_string { constexpr fixed_string(const Char (&str)[N]) { copy_str(static_cast(str), str + N, @@ -725,7 +728,7 @@ size_t formatted_size(const CompiledFormat& cf, const Args&... args) { return format_to(detail::counting_iterator(), cf, args...).count(); } -#ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS inline namespace literals { template constexpr detail::udl_compiled_string, diff --git a/test/compile-test.cc b/test/compile-test.cc index 1e6292b7235c..d328077e2285 100644 --- a/test/compile-test.cc +++ b/test/compile-test.cc @@ -179,7 +179,7 @@ TEST(CompileTest, Empty) { } #endif -#ifdef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS TEST(CompileTest, CompileFormatStringLiteral) { using namespace fmt::literals; EXPECT_EQ("", fmt::format(""_cf)); From e7d035d55d3914b29b1a51d765953dd0165877fd Mon Sep 17 00:00:00 2001 From: Alexey Ochapov Date: Mon, 7 Dec 2020 23:36:21 +0300 Subject: [PATCH 6/6] remove deduction guide for `fixed_string` --- include/fmt/compile.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/fmt/compile.h b/include/fmt/compile.h index 1332eb2121cd..65aeb4457e8c 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -55,9 +55,6 @@ template struct fixed_string { Char data[N]{}; }; -template -fixed_string(const Char (&str)[N]) -> fixed_string; - template Str> struct udl_compiled_string : compiled_string { using char_type = Char;