diff --git a/format.h b/format.h index a3088ab5..3ca653d0 100644 --- a/format.h +++ b/format.h @@ -530,7 +530,9 @@ class BasicWriter { template void FormatDouble(T value, const FormatSpec &spec, int precision); - CharPtr FormatString(const char *s, std::size_t size, const FormatSpec &spec); + template + CharPtr FormatString(const StringChar *s, + std::size_t size, const FormatSpec &spec); public: /** @@ -833,8 +835,9 @@ void BasicWriter::FormatDouble( } template +template typename BasicWriter::CharPtr BasicWriter::FormatString( - const char *s, std::size_t size, const FormatSpec &spec) { + const StringChar *s, std::size_t size, const FormatSpec &spec) { CharPtr out = CharPtr(); if (spec.width() > size) { out = GrowBuffer(spec.width()); @@ -1000,7 +1003,7 @@ class BasicFormatter { long double long_double_value; const void *pointer_value; struct { - const char *value; + const Char *value; std::size_t size; } string; struct { @@ -1022,12 +1025,12 @@ class BasicFormatter { : type(LONG_DOUBLE), long_double_value(value), formatter(0) {} Arg(char value) : type(CHAR), int_value(value), formatter(0) {} - Arg(const char *value) : type(STRING), formatter(0) { + Arg(const Char *value) : type(STRING), formatter(0) { string.value = value; string.size = 0; } - Arg(char *value) : type(STRING), formatter(0) { + Arg(Char *value) : type(STRING), formatter(0) { string.value = value; string.size = 0; } @@ -1604,13 +1607,13 @@ void BasicFormatter::DoFormat() { case STRING: { if (spec.type_ && spec.type_ != 's') internal::ReportUnknownType(spec.type_, "string"); - const char *str = arg.string.value; + const Char *str = arg.string.value; std::size_t size = arg.string.size; if (size == 0) { if (!str) throw FormatError("string pointer is null"); if (*str) - size = std::strlen(str); + size = std::char_traits::length(str); } writer.FormatString(str, size, spec); break; diff --git a/format_test.cc b/format_test.cc index 2c82be97..4c62c7b2 100644 --- a/format_test.cc +++ b/format_test.cc @@ -1030,6 +1030,8 @@ TEST(FormatterTest, CustomFormat) { TEST(FormatterTest, WideFormatString) { EXPECT_EQ(L"42", str(Format(L"{}") << 42)); + EXPECT_EQ(L"4.2", str(Format(L"{}") << 4.2)); + EXPECT_EQ(L"abc", str(Format(L"{}") << L"abc")); } TEST(FormatterTest, FormatStringFromSpeedTest) { @@ -1104,7 +1106,7 @@ struct CountCalls { } }; -TEST(TempFormatterTest, Action) { +TEST(FormatterTest, Action) { int num_calls = 0; { fmt::Formatter af("test", CountCalls(num_calls)); @@ -1113,7 +1115,7 @@ TEST(TempFormatterTest, Action) { EXPECT_EQ(1, num_calls); } -TEST(TempFormatterTest, ActionNotCalledOnError) { +TEST(FormatterTest, ActionNotCalledOnError) { int num_calls = 0; { typedef fmt::Formatter TestFormatter; @@ -1126,19 +1128,18 @@ TEST(TempFormatterTest, ActionNotCalledOnError) { // require an accessible copy constructor when binding a temporary to // a const reference. #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 -TEST(TempFormatterTest, ArgLifetime) { +TEST(FormatterTest, ArgLifetime) { // The following code is for testing purposes only. It is a definite abuse // of the API and shouldn't be used in real applications. const fmt::Formatter<> &af = fmt::Format("{0}"); const_cast&>(af) << std::string("test"); - // String object passed as an argument to TempFormatter has - // been destroyed, but ArgInserter dtor hasn't been called yet. - // But that's OK since the Arg's dtor takes care of this and - // calls Format. + // String object passed as an argument to Formatter has been destroyed, + // but Formatter's dtor hasn't been called yet. That's OK since the Arg's + // dtor takes care of this and calls Format. } #endif -TEST(TempFormatterTest, ConvertToStringRef) { +TEST(FormatterTest, ConvertToStringRef) { EXPECT_STREQ("abc", StringRef(Format("a{0}c") << 'b').c_str()); EXPECT_EQ(3u, StringRef(Format("a{0}c") << 'b').size()); } @@ -1153,7 +1154,7 @@ fmt::Formatter ReportError(const char *format) { return fmt::Formatter(format); } -TEST(TempFormatterTest, Examples) { +TEST(FormatterTest, Examples) { EXPECT_EQ("First, thou shalt count to three", str(Format("First, thou shalt count to {0}") << "three")); EXPECT_EQ("Bring me a shrubbery",