diff --git a/include/fmt/core.h b/include/fmt/core.h index 32647c1b..3c08d0f1 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -139,6 +139,13 @@ # endif #endif +#if FMT_HAS_FEATURE(__cpp_deduction_guides) || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1914) +# define FMT_HAS_CTAD 1 +#else +# define FMT_HAS_CTAD 0 +#endif + #ifndef FMT_BEGIN_NAMESPACE # if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \ FMT_MSC_VER >= 1900 @@ -434,6 +441,18 @@ class basic_string_view { typedef basic_string_view string_view; typedef basic_string_view wstring_view; +#if FMT_HAS_CTAD +template +basic_string_view(const Char *, size_t) -> basic_string_view; +template +basic_string_view(const Char *) -> basic_string_view; +template +basic_string_view(const std::basic_string &) -> basic_string_view; +#ifdef FMT_STRING_VIEW +template +basic_string_view(FMT_STRING_VIEW) -> basic_string_view; +#endif +#endif // 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("{}"), 42). diff --git a/test/core-test.cc b/test/core-test.cc index fed78c3b..e6ae896b 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -32,6 +32,7 @@ using fmt::basic_format_arg; using fmt::internal::basic_buffer; using fmt::internal::value; using fmt::string_view; +using fmt::wstring_view; using testing::_; using testing::StrictMock; @@ -437,6 +438,31 @@ TEST(StringViewTest, Compare) { check_op(); } +#if FMT_HAS_CTAD + +TEST(BasicStringViewTest, ClassTemplateArgumentDeduction) { + // Test that basic_string_view is correctly deduced + char str[] = "some string"; + const std::size_t slen = strlen(str); + const string_view sv(str); + EXPECT_EQ(sv, fmt::basic_string_view(str)); + EXPECT_EQ(sv, fmt::basic_string_view(str, slen)); + EXPECT_EQ(sv, fmt::basic_string_view(std::string(str))); +#ifdef FMT_STRING_VIEW + EXPECT_EQ(sv, fmt::basic_string_view(FMT_STRING_VIEW(str))); +#endif + + // wide character types + const wchar_t *wstr = L"some string"; + EXPECT_EQ(wstring_view(wstr), fmt::basic_string_view(wstr)); + const char16_t *c16str = u"some string"; + EXPECT_EQ(fmt::basic_string_view(c16str), fmt::basic_string_view(c16str)); + const char32_t *c32str = U"some string"; + EXPECT_EQ(fmt::basic_string_view(c32str), fmt::basic_string_view(c32str)); +} + +#endif + enum basic_enum {}; TEST(CoreTest, ConvertToInt) {