Fix length computation of constexpr C strings

This commit is contained in:
Victor Zverovich
2020-01-22 18:03:34 -08:00
parent 9fc4161f5e
commit 419db8baa1
2 changed files with 11 additions and 1 deletions

View File

@@ -3449,6 +3449,13 @@ template <typename Char> struct udl_arg {
} }
}; };
// A constexpr version of strlen.
template <typename Char> FMT_CONSTEXPR size_t compute_length(const Char* s) {
size_t len = 0;
while (*s++) ++len;
return len;
}
} // namespace internal } // namespace internal
inline namespace literals { inline namespace literals {
@@ -3512,7 +3519,7 @@ FMT_END_NAMESPACE
using char_type = fmt::remove_cvref_t<decltype(*s)>; \ using char_type = fmt::remove_cvref_t<decltype(*s)>; \
__VA_ARGS__ FMT_CONSTEXPR \ __VA_ARGS__ FMT_CONSTEXPR \
operator fmt::basic_string_view<char_type>() const { \ operator fmt::basic_string_view<char_type>() const { \
return {s, sizeof(s) / sizeof(char_type) - 1}; \ return {s, fmt::internal::compute_length(s)}; \
} \ } \
}; \ }; \
return FMT_STRING(); \ return FMT_STRING(); \

View File

@@ -1849,7 +1849,10 @@ TEST(FormatTest, UnpackedArgs) {
struct string_like {}; struct string_like {};
fmt::string_view to_string_view(string_like) { return "foo"; } fmt::string_view to_string_view(string_like) { return "foo"; }
FMT_CONSTEXPR_DECL const char* format_str_ptr = "0123456789";
TEST(FormatTest, CompileTimeString) { 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("42", fmt::format(FMT_STRING("{}"), 42));
EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42)); EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42));
EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like())); EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like()));