From 3e75d3e0015976fa62b093bf5c9e42ad6a0e9756 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 2 Sep 2017 07:08:19 -0700 Subject: [PATCH] Fix handling of types convertible to int --- fmt/format.h | 16 ++++++++-------- fmt/ostream.h | 6 ++++-- test/ostream-test.cc | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index 37a4c24f..e93371e9 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -1171,17 +1171,17 @@ T &get(); Yes &convert(fmt::ULongLong); No &convert(...); -template +template struct ConvertToIntImpl { enum { value = ENABLE_CONVERSION }; }; -template +template struct ConvertToIntImpl2 { enum { value = false }; }; -template +template struct ConvertToIntImpl2 { enum { // Don't convert numeric types. @@ -1189,7 +1189,7 @@ struct ConvertToIntImpl2 { }; }; -template +template struct ConvertToInt { enum { enable_conversion = sizeof(fmt::internal::convert(get())) == sizeof(Yes) @@ -1206,16 +1206,16 @@ FMT_DISABLE_CONVERSION_TO_INT(float); FMT_DISABLE_CONVERSION_TO_INT(double); FMT_DISABLE_CONVERSION_TO_INT(long double); -template +template struct EnableIf {}; -template +template struct EnableIf { typedef T type; }; -template +template struct Conditional { typedef T type; }; -template +template struct Conditional { typedef F type; }; // For bcc32 which doesn't understand ! in template arguments. diff --git a/fmt/ostream.h b/fmt/ostream.h index 84a02d17..ef5e2efe 100644 --- a/fmt/ostream.h +++ b/fmt/ostream.h @@ -52,13 +52,15 @@ Yes &convert(std::ostream &); struct DummyStream : std::ostream { DummyStream(); // Suppress a bogus warning in MSVC. + // Hide all operator<< overloads from std::ostream. - void operator<<(Null<>); + template + typename EnableIf::type operator<<(const T &); }; No &operator<<(std::ostream &, int); -template +template struct ConvertToIntImpl { // Convert to int only if T doesn't have an overloaded operator<<. enum { diff --git a/test/ostream-test.cc b/test/ostream-test.cc index 4081b43f..486981bc 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -172,3 +172,18 @@ TEST(OStreamTest, WriteToOStreamMaxSize) { } while (size != 0); fmt::internal::write(os, w); } + +struct ConvertibleToInt { + template + operator ValueType() const { + return 0; + } + + friend std::ostream &operator<<(std::ostream &o, ConvertibleToInt) { + return o << "foo"; + } +}; + +TEST(FormatTest, FormatConvertibleToInt) { + EXPECT_EQ("foo", fmt::format("{}", ConvertibleToInt())); +}