From 91721caa42a7d509974d9938fc76a29adf9101a6 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 17 Feb 2018 09:03:43 +0000 Subject: [PATCH] Add detection of wostream operator<< (#650) --- include/fmt/core.h | 12 ++++++------ include/fmt/ostream.h | 11 ++++++----- test/ostream-test.cc | 2 +- test/util-test.cc | 8 ++++---- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 27bce7a9dc79..bda0e078af54 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -413,7 +413,7 @@ FMT_CONSTEXPR bool is_arithmetic(type t) { return t > internal::none_type && t <= internal::last_numeric_type; } -template +template struct convert_to_int { enum { value = !std::is_arithmetic::value && std::is_convertible::value @@ -421,8 +421,8 @@ struct convert_to_int { }; #define FMT_DISABLE_CONVERSION_TO_INT(Type) \ - template <> \ - struct convert_to_int { enum { value = 0 }; } + template \ + struct convert_to_int { enum { value = 0 }; } // Silence warnings about convering float to int. FMT_DISABLE_CONVERSION_TO_INT(float); @@ -589,13 +589,13 @@ void make_value(const T *p) { template inline typename std::enable_if< - convert_to_int::value && std::is_enum::value, + convert_to_int::value && std::is_enum::value, typed_value>::type make_value(const T &val) { return static_cast(val); } template -inline typename std::enable_if< - !convert_to_int::value, typed_value>::type +inline typename std::enable_if::value, typed_value>::type make_value(const T &val) { return val; } template diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index 922be7544730..16d490b2f2cc 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -46,21 +46,22 @@ class FormatBuf : public std::basic_streambuf { } }; -struct test_stream : std::ostream { +template +struct test_stream : std::basic_ostream { private: struct null; - // Hide all operator<< from std::ostream. + // Hide all operator<< from std::basic_ostream. void operator<<(null); }; // Disable conversion to int if T has an overloaded operator<< which is a free // function (not a member of std::ostream). -template -class convert_to_int { +template +class convert_to_int { private: template static decltype( - std::declval() << std::declval(), std::true_type()) + std::declval&>() << std::declval(), std::true_type()) test(int); template diff --git a/test/ostream-test.cc b/test/ostream-test.cc index e42f33444efb..41f6539627bf 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -53,7 +53,7 @@ std::ostream &operator<<(std::ostream &os, TestEnum) { enum TestEnum2 {A}; TEST(OStreamTest, Enum) { - EXPECT_FALSE(fmt::internal::convert_to_int::value); + EXPECT_FALSE((fmt::internal::convert_to_int::value)); EXPECT_EQ("TestEnum", fmt::format("{}", TestEnum())); EXPECT_EQ("0", fmt::format("{}", A)); } diff --git a/test/util-test.cc b/test/util-test.cc index 5ada007b36ec..6a16096b2949 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -843,15 +843,15 @@ TEST(UtilTest, ReportWindowsError) { enum TestEnum2 {}; TEST(UtilTest, ConvertToInt) { - EXPECT_FALSE(fmt::internal::convert_to_int::value); - EXPECT_FALSE(fmt::internal::convert_to_int::value); - EXPECT_TRUE(fmt::internal::convert_to_int::value); + EXPECT_FALSE((fmt::internal::convert_to_int::value)); + EXPECT_FALSE((fmt::internal::convert_to_int::value)); + EXPECT_TRUE((fmt::internal::convert_to_int::value)); } #if FMT_USE_ENUM_BASE enum TestEnum : char {TestValue}; TEST(UtilTest, IsEnumConvertibleToInt) { - EXPECT_TRUE(fmt::internal::convert_to_int::value); + EXPECT_TRUE((fmt::internal::convert_to_int::value)); } #endif