diff options
Diffstat (limited to 'absl')
-rw-r--r-- | absl/strings/internal/str_format/arg.cc | 11 | ||||
-rw-r--r-- | absl/strings/internal/str_format/arg.h | 9 | ||||
-rw-r--r-- | absl/strings/str_format_test.cc | 7 |
3 files changed, 25 insertions, 2 deletions
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index b0e06bfb..967fe9ca 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc @@ -344,7 +344,7 @@ bool ConvertIntArg(T v, FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return ConvertFloatImpl(static_cast<double>(v), conv, sink); default: - ABSL_ASSUME(false); + ABSL_ASSUME(false); } if (conv.is_basic()) { @@ -376,6 +376,15 @@ inline bool ConvertStringArg(string_view v, const FormatConversionSpecImpl conv, } // namespace +bool ConvertBoolArg(bool v, FormatSinkImpl *sink) { + if (v) { + sink->Append("true"); + } else { + sink->Append("false"); + } + return true; +} + // ==================== Strings ==================== StringConvertResult FormatConvertImpl(const std::string &v, const FormatConversionSpecImpl conv, diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index 3c2bb3e6..2dfbf728 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -186,6 +186,8 @@ using CharConvertResult = ArgConvertResult<FormatConversionCharSetUnion( FormatConversionCharSetInternal::kNumeric, FormatConversionCharSetInternal::kStar)>; +bool ConvertBoolArg(bool v, FormatSinkImpl* sink); + // Floats. FloatingConvertResult FormatConvertImpl(float v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); @@ -234,9 +236,16 @@ IntegralConvertResult FormatConvertImpl(int128 v, FormatConversionSpecImpl conv, IntegralConvertResult FormatConvertImpl(uint128 v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); + +// This function needs to be a template due to ambiguity regarding type +// conversions. template <typename T, enable_if_t<std::is_same<T, bool>::value, int> = 0> IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink) { + if (conv.conversion_char() == FormatConversionCharInternal::v) { + return {ConvertBoolArg(v, sink)}; + } + return FormatConvertImpl(static_cast<int>(v), conv, sink); } diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index 2774cfed..4b778056 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc @@ -265,7 +265,7 @@ TEST_F(FormatEntryPointTest, Stream) { std::ostringstream oss; oss << StreamFormat(*parsed, 123, 3, 49, "multistreaming!!!", 1.01, 1.01); int fmt_result = snprintf(&*buf.begin(), buf.size(), fmt.c_str(), // - 123, 3, 49, "multistreaming!!!", 1.01, 1.01); + 123, 3, 49, "multistreaming!!!", 1.01, 1.01); ASSERT_TRUE(oss) << fmt; ASSERT_TRUE(fmt_result >= 0 && static_cast<size_t>(fmt_result) < buf.size()) << fmt_result; @@ -644,6 +644,11 @@ TEST(StrFormat, BehavesAsDocumented) { EXPECT_EQ(StrFormat("%zd", int{1}), "1"); EXPECT_EQ(StrFormat("%td", int{1}), "1"); EXPECT_EQ(StrFormat("%qd", int{1}), "1"); + + // Bool is handled correctly depending on whether %v is used + EXPECT_EQ(StrFormat("%v", true), "true"); + EXPECT_EQ(StrFormat("%v", false), "false"); + EXPECT_EQ(StrFormat("%d", true), "1"); } using str_format_internal::ExtendedParsedFormat; |