diff --git a/doc/api.rst b/doc/api.rst index 654d26fb..4d221195 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -9,7 +9,8 @@ The {fmt} library API consists of the following parts: * :ref:`fmt/core.h `: the core API providing argument handling facilities and a lightweight subset of formatting functions * :ref:`fmt/format.h `: the full format API providing compile-time - format string checks, output iterator and user-defined type support + format string checks, wide string, output iterator and user-defined type + support * :ref:`fmt/ranges.h `: additional formatting support for ranges and tuples * :ref:`fmt/chrono.h `: date and time formatting @@ -104,7 +105,7 @@ Format API ========== ``fmt/format.h`` defines the full format API providing compile-time format -string checks, output iterator and user-defined type support. +string checks, wide string, output iterator and user-defined type support. Compile-time Format String Checks --------------------------------- diff --git a/src/format.cc b/src/format.cc index e1f42a2e..680e6714 100644 --- a/src/format.cc +++ b/src/format.cc @@ -211,7 +211,4 @@ template FMT_API wchar_t internal::decimal_point_impl(locale_ref); template FMT_API void internal::buffer::append(const wchar_t*, const wchar_t*); - -template FMT_API std::wstring internal::vformat( - wstring_view, basic_format_args); FMT_END_NAMESPACE diff --git a/test/core-test.cc b/test/core-test.cc index 63955d98..adda8943 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -600,23 +600,6 @@ inline fmt::basic_string_view to_string_view(const my_string& s) struct non_string {}; } // namespace my_ns -namespace FakeQt { -class QString { - public: - QString(const wchar_t* s) : s_(std::make_shared(s)) {} - const wchar_t* utf16() const FMT_NOEXCEPT { return s_->data(); } - int size() const FMT_NOEXCEPT { return static_cast(s_->size()); } - - private: - std::shared_ptr s_; -}; - -inline fmt::basic_string_view to_string_view(const QString& s) - FMT_NOEXCEPT { - return {s.utf16(), static_cast(s.size())}; -} -} // namespace FakeQt - template class IsStringTest : public testing::Test {}; typedef ::testing::Types StringCharTypes; @@ -642,7 +625,6 @@ TYPED_TEST(IsStringTest, IsString) { fmt::internal::is_string::value); EXPECT_TRUE(fmt::internal::is_string>::value); EXPECT_FALSE(fmt::internal::is_string::value); - EXPECT_TRUE(fmt::internal::is_string::value); } TEST(CoreTest, Format) { @@ -665,33 +647,16 @@ TEST(CoreTest, FormatTo) { TEST(CoreTest, ToStringViewForeignStrings) { using namespace my_ns; - using namespace FakeQt; EXPECT_EQ(to_string_view(my_string("42")), "42"); - EXPECT_EQ(to_string_view(my_string(L"42")), L"42"); - EXPECT_EQ(to_string_view(QString(L"42")), L"42"); fmt::internal::type type = fmt::internal::mapped_type_constant, fmt::format_context>::value; EXPECT_EQ(type, fmt::internal::type::string_type); - type = fmt::internal::mapped_type_constant, - fmt::wformat_context>::value; - EXPECT_EQ(type, fmt::internal::type::string_type); - type = - fmt::internal::mapped_type_constant::value; - EXPECT_EQ(type, fmt::internal::type::string_type); - // Does not compile: only wide format contexts are compatible with QString! - // type = fmt::internal::mapped_type_constant::value; } TEST(CoreTest, FormatForeignStrings) { using namespace my_ns; - using namespace FakeQt; EXPECT_EQ(fmt::format(my_string("{}"), 42), "42"); - EXPECT_EQ(fmt::format(my_string(L"{}"), 42), L"42"); - EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42"); - EXPECT_EQ(fmt::format(QString(L"{}"), my_string(L"42")), L"42"); - EXPECT_EQ(fmt::format(my_string(L"{}"), QString(L"42")), L"42"); } struct implicitly_convertible_to_string { @@ -726,15 +691,6 @@ TEST(FormatterTest, FormatExplicitlyConvertibleToStdStringView) { fmt::format("{}", explicitly_convertible_to_std_string_view())); } # endif - -struct explicitly_convertible_to_wstring_view { - explicit operator fmt::wstring_view() const { return L"foo"; } -}; - -TEST(FormatterTest, FormatExplicitlyConvertibleToWStringView) { - EXPECT_EQ(L"foo", - fmt::format(L"{}", explicitly_convertible_to_wstring_view())); -} #endif struct disabled_rvalue_conversion { diff --git a/test/format-test.cc b/test/format-test.cc index 8caf9ecf..7332a5ad 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1609,6 +1609,40 @@ TEST(FormatterTest, FormatExplicitlyConvertibleToStdStringView) { } #endif +// std::is_constructible is broken in MSVC until version 2015. +#if !FMT_MSC_VER || FMT_MSC_VER >= 1900 +struct explicitly_convertible_to_wstring_view { + explicit operator fmt::wstring_view() const { return L"foo"; } +}; + +TEST(FormatTest, FormatExplicitlyConvertibleToWStringView) { + EXPECT_EQ(L"foo", + fmt::format(L"{}", explicitly_convertible_to_wstring_view())); +} +#endif + +namespace fake_qt { +class QString { + public: + QString(const wchar_t* s) : s_(std::make_shared(s)) {} + const wchar_t* utf16() const FMT_NOEXCEPT { return s_->data(); } + int size() const FMT_NOEXCEPT { return static_cast(s_->size()); } + + private: + std::shared_ptr s_; +}; + +fmt::basic_string_view to_string_view(const QString& s) FMT_NOEXCEPT { + return {s.utf16(), static_cast(s.size())}; +} +} // namespace fake_qt + +TEST(FormatTest, FormatForeignStrings) { + using fake_qt::QString; + EXPECT_EQ(fmt::format(QString(L"{}"), 42), L"42"); + EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42"); +} + FMT_BEGIN_NAMESPACE template <> struct formatter { template