diff --git a/include/fmt/core.h b/include/fmt/core.h index 4c41f92d..4dc83ddf 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1016,7 +1016,11 @@ struct fallback_formatter { // Specifies if T has an enabled fallback_formatter specialization. template using has_fallback_formatter = +#ifdef FMT_DEPRECATED_OSTREAM std::is_constructible>; +#else + std::false_type; +#endif struct view {}; diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index 7acc3299..4634bcf9 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -105,6 +105,9 @@ struct fallback_formatter::value>> }; } // namespace detail +template +using ostream_formatter = detail::fallback_formatter; + FMT_MODULE_EXPORT template void vprint(std::basic_ostream& os, basic_string_view format_str, diff --git a/test/ostream-test.cc b/test/ostream-test.cc index bae7ad18..2f9c4383 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -53,6 +53,17 @@ std::ostream& operator<<(std::ostream& os, streamable_enum) { enum unstreamable_enum {}; +struct empty_test {}; +std::ostream& operator<<(std::ostream& os, empty_test) { return os << ""; } + +namespace fmt { +template <> struct formatter : ostream_formatter {}; +template <> struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> struct formatter : ostream_formatter {}; +} // namespace fmt + TEST(ostream_test, enum) { EXPECT_EQ("streamable_enum", fmt::format("{}", streamable_enum())); EXPECT_EQ("0", fmt::format("{}", unstreamable_enum())); @@ -86,9 +97,6 @@ TEST(ostream_test, format_specs) { EXPECT_EQ("te", fmt::format("{0:.{1}}", test_string("test"), 2)); } -struct empty_test {}; -std::ostream& operator<<(std::ostream& os, empty_test) { return os << ""; } - TEST(ostream_test, empty_custom_output) { EXPECT_EQ("", fmt::format("{}", empty_test())); } @@ -184,6 +192,9 @@ template struct formatter> : formatter { return formatter::format(2, ctx); } }; + +template <> +struct formatter : ostream_formatter {}; } // namespace fmt TEST(ostream_test, template) { @@ -214,41 +225,6 @@ TEST(ostream_test, disable_builtin_ostream_operators) { EXPECT_EQ("foo", fmt::format("{}", convertible("foo"))); } -struct explicitly_convertible_to_string_like { - template ::value>::type> - explicit operator String() const { - return String("foo", 3u); - } -}; - -std::ostream& operator<<(std::ostream& os, - explicitly_convertible_to_string_like) { - return os << "bar"; -} - -TEST(ostream_test, format_explicitly_convertible_to_string_like) { - EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); -} - -#ifdef FMT_USE_STRING_VIEW -struct explicitly_convertible_to_std_string_view { - explicit operator fmt::detail::std_string_view() const { - return {"foo", 3u}; - } -}; - -std::ostream& operator<<(std::ostream& os, - explicitly_convertible_to_std_string_view) { - return os << "bar"; -} - -TEST(ostream_test, format_explicitly_convertible_to_std_string_view) { - EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); -} -#endif // FMT_USE_STRING_VIEW - struct streamable_and_convertible_to_bool { operator bool() const { return true; } }; @@ -285,6 +261,10 @@ std::ostream& operator<<(std::ostream& os, copyfmt_test) { return os << "foo"; } +namespace fmt { +template <> struct formatter : ostream_formatter {}; +} // namespace fmt + TEST(ostream_test, copyfmt) { EXPECT_EQ("foo", fmt::format("{}", copyfmt_test())); } @@ -306,6 +286,10 @@ struct abstract { } }; +namespace fmt { +template <> struct formatter : ostream_formatter {}; +} // namespace fmt + void format_abstract_compiles(const abstract& a) { fmt::format(FMT_COMPILE("{}"), a); } diff --git a/test/printf-test.cc b/test/printf-test.cc index 0bb9ccda..91869c2f 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -11,7 +11,6 @@ #include #include -#include "fmt/ostream.h" #include "fmt/xchar.h" #include "gtest-extra.h" #include "util.h" @@ -533,10 +532,6 @@ TEST(printf_test, wide_string) { EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc")); } -TEST(printf_test, printf_custom) { - EXPECT_EQ("abc", test_sprintf("%s", test_string("abc"))); -} - TEST(printf_test, vprintf) { fmt::format_arg_store as{42}; fmt::basic_format_args args(as); diff --git a/test/xchar-test.cc b/test/xchar-test.cc index b07e8e26..2d7dfa85 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -220,6 +220,12 @@ std::wostream& operator<<(std::wostream& os, streamable_enum) { return os << L"streamable_enum"; } +namespace fmt { +template <> +struct formatter + : ostream_formatter {}; +} // namespace fmt + enum unstreamable_enum {}; TEST(xchar_test, enum) {