diff --git a/include/fmt/color.h b/include/fmt/color.h index 49407e3c..9e1bc536 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -483,7 +483,7 @@ template > void vprint(std::FILE* f, const text_style& ts, const S& format, basic_format_args>> args) { basic_memory_buffer buf; - detail::vformat_to(buf, ts, to_string_view(format), args); + detail::vformat_to(buf, ts, detail::to_string_view(format), args); if (detail::is_utf8()) { detail::print(f, basic_string_view(buf.begin(), buf.size())); } else { @@ -533,7 +533,7 @@ inline std::basic_string vformat( const text_style& ts, const S& format_str, basic_format_args>> args) { basic_memory_buffer buf; - detail::vformat_to(buf, ts, to_string_view(format_str), args); + detail::vformat_to(buf, ts, detail::to_string_view(format_str), args); return fmt::to_string(buf); } @@ -552,7 +552,7 @@ inline std::basic_string vformat( template > inline std::basic_string format(const text_style& ts, const S& format_str, const Args&... args) { - return fmt::vformat(ts, to_string_view(format_str), + return fmt::vformat(ts, detail::to_string_view(format_str), fmt::make_format_args>(args...)); } @@ -587,7 +587,7 @@ template typename std::enable_if::type { - return vformat_to(out, ts, to_string_view(format_str), + return vformat_to(out, ts, detail::to_string_view(format_str), fmt::make_format_args>>(args...)); } diff --git a/include/fmt/core.h b/include/fmt/core.h index 762155c4..c62ffdf6 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -493,6 +493,15 @@ using string_view = basic_string_view; template struct is_char : std::false_type {}; template <> struct is_char : std::true_type {}; +// A base class for compile-time strings. It is defined in the fmt namespace to +// make formatting functions visible via ADL, e.g. format(FMT_STRING("{}"), 42). +struct compile_string {}; + +template +struct is_compile_string : std::is_base_of {}; + +FMT_BEGIN_DETAIL_NAMESPACE + // Returns a string view of `s`. template ::value)> FMT_INLINE auto to_string_view(const Char* s) -> basic_string_view { @@ -509,29 +518,17 @@ constexpr auto to_string_view(basic_string_view s) return s; } template >::value)> -inline auto to_string_view(detail::std_string_view s) + FMT_ENABLE_IF(!std::is_empty>::value)> +inline auto to_string_view(std_string_view s) -> basic_string_view { return s; } - -// A base class for compile-time strings. It is defined in the fmt namespace to -// make formatting functions visible via ADL, e.g. format(FMT_STRING("{}"), 42). -struct compile_string {}; - -template -struct is_compile_string : std::is_base_of {}; - template ::value)> constexpr auto to_string_view(const S& s) -> basic_string_view { return basic_string_view(s); } - -FMT_BEGIN_DETAIL_NAMESPACE - void to_string_view(...); -using fmt::to_string_view; // Specifies whether S is a string type convertible to fmt::basic_string_view. // It should be a constexpr function but MSVC 2017 fails to compile it in diff --git a/include/fmt/printf.h b/include/fmt/printf.h index abb67ed0..70a592dc 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -560,7 +560,7 @@ inline auto vsprintf( basic_format_args>> args) -> std::basic_string { basic_memory_buffer buffer; - vprintf(buffer, to_string_view(fmt), args); + vprintf(buffer, detail::to_string_view(fmt), args); return to_string(buffer); } @@ -577,7 +577,8 @@ template ::value, char_t>> inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string { using context = basic_printf_context_t; - return vsprintf(to_string_view(fmt), fmt::make_format_args(args...)); + return vsprintf(detail::to_string_view(fmt), + fmt::make_format_args(args...)); } template > @@ -586,7 +587,7 @@ inline auto vfprintf( basic_format_args>> args) -> int { basic_memory_buffer buffer; - vprintf(buffer, to_string_view(fmt), args); + vprintf(buffer, detail::to_string_view(fmt), args); size_t size = buffer.size(); return std::fwrite(buffer.data(), sizeof(Char), size, f) < size ? -1 @@ -605,7 +606,7 @@ inline auto vfprintf( template > inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int { using context = basic_printf_context_t; - return vfprintf(f, to_string_view(fmt), + return vfprintf(f, detail::to_string_view(fmt), fmt::make_format_args(args...)); } @@ -614,7 +615,7 @@ inline auto vprintf( const S& fmt, basic_format_args>> args) -> int { - return vfprintf(stdout, to_string_view(fmt), args); + return vfprintf(stdout, detail::to_string_view(fmt), args); } /** @@ -629,7 +630,7 @@ inline auto vprintf( template ::value)> inline auto printf(const S& fmt, const T&... args) -> int { return vprintf( - to_string_view(fmt), + detail::to_string_view(fmt), fmt::make_format_args>>(args...)); } diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index 6e3e76de..ea34917f 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -92,7 +92,7 @@ auto vformat(basic_string_view format_str, template , FMT_ENABLE_IF(!std::is_same::value)> auto format(const S& format_str, Args&&... args) -> std::basic_string { - return vformat(to_string_view(format_str), + return vformat(detail::to_string_view(format_str), fmt::make_format_args>(args...)); } @@ -103,7 +103,7 @@ inline auto vformat( const Locale& loc, const S& format_str, basic_format_args>> args) -> std::basic_string { - return detail::vformat(loc, to_string_view(format_str), args); + return detail::vformat(loc, detail::to_string_view(format_str), args); } template ::value)> inline auto format(const Locale& loc, const S& format_str, Args&&... args) -> std::basic_string { - return detail::vformat(loc, to_string_view(format_str), + return detail::vformat(loc, detail::to_string_view(format_str), fmt::make_format_args>(args...)); } @@ -123,7 +123,7 @@ auto vformat_to(OutputIt out, const S& format_str, basic_format_args>> args) -> OutputIt { auto&& buf = detail::get_buffer(out); - detail::vformat_to(buf, to_string_view(format_str), args); + detail::vformat_to(buf, detail::to_string_view(format_str), args); return detail::get_iterator(buf); } @@ -132,7 +132,7 @@ template ::value&& detail::is_exotic_char::value)> inline auto format_to(OutputIt out, const S& fmt, Args&&... args) -> OutputIt { - return vformat_to(out, to_string_view(fmt), + return vformat_to(out, detail::to_string_view(fmt), fmt::make_format_args>(args...)); } @@ -145,7 +145,8 @@ inline auto vformat_to( OutputIt out, const Locale& loc, const S& format_str, basic_format_args>> args) -> OutputIt { auto&& buf = detail::get_buffer(out); - vformat_to(buf, to_string_view(format_str), args, detail::locale_ref(loc)); + vformat_to(buf, detail::to_string_view(format_str), args, + detail::locale_ref(loc)); return detail::get_iterator(buf); } @@ -180,7 +181,7 @@ template ::value)> inline auto format_to_n(OutputIt out, size_t n, const S& fmt, const Args&... args) -> format_to_n_result { - return vformat_to_n(out, n, to_string_view(fmt), + return vformat_to_n(out, n, detail::to_string_view(fmt), fmt::make_format_args>(args...)); } @@ -188,7 +189,7 @@ template , FMT_ENABLE_IF(detail::is_exotic_char::value)> inline auto formatted_size(const S& fmt, Args&&... args) -> size_t { detail::counting_buffer buf; - detail::vformat_to(buf, to_string_view(fmt), + detail::vformat_to(buf, detail::to_string_view(fmt), fmt::make_format_args>(args...)); return buf.count(); } diff --git a/test/xchar-test.cc b/test/xchar-test.cc index 7db35913..498ff651 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -240,28 +240,6 @@ TEST(xchar_test, sign_not_truncated) { EXPECT_THROW(fmt::format(format_str, 42), fmt::format_error); } -namespace fake_qt { -class QString { - public: - QString(const wchar_t* s) : s_(s) {} - const wchar_t* utf16() const noexcept { return s_.data(); } - int size() const noexcept { return static_cast(s_.size()); } - - private: - std::wstring s_; -}; - -fmt::basic_string_view to_string_view(const QString& s) noexcept { - return {s.utf16(), static_cast(s.size())}; -} -} // namespace fake_qt - -TEST(format_test, format_foreign_strings) { - using fake_qt::QString; - EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42"); - EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42"); -} - TEST(xchar_test, chrono) { auto tm = std::tm(); tm.tm_year = 116;