From 419db8baa1a8102eb333c5a7aa269efd198e1977 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 22 Jan 2020 18:03:34 -0800 Subject: [PATCH] Fix length computation of constexpr C strings --- include/fmt/format.h | 9 ++++++++- test/format-test.cc | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index cc9e5b4e..cd3bb03f 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3449,6 +3449,13 @@ template struct udl_arg { } }; +// A constexpr version of strlen. +template FMT_CONSTEXPR size_t compute_length(const Char* s) { + size_t len = 0; + while (*s++) ++len; + return len; +} + } // namespace internal inline namespace literals { @@ -3512,7 +3519,7 @@ FMT_END_NAMESPACE using char_type = fmt::remove_cvref_t; \ __VA_ARGS__ FMT_CONSTEXPR \ operator fmt::basic_string_view() const { \ - return {s, sizeof(s) / sizeof(char_type) - 1}; \ + return {s, fmt::internal::compute_length(s)}; \ } \ }; \ return FMT_STRING(); \ diff --git a/test/format-test.cc b/test/format-test.cc index 8bce69be..f479ceb6 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1849,7 +1849,10 @@ TEST(FormatTest, UnpackedArgs) { struct string_like {}; fmt::string_view to_string_view(string_like) { return "foo"; } +FMT_CONSTEXPR_DECL const char* format_str_ptr = "0123456789"; + TEST(FormatTest, CompileTimeString) { + EXPECT_EQ(format_str_ptr, fmt::format(FMT_STRING(format_str_ptr))); EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42)); EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42)); EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like()));