diff --git a/fmt/format.h b/fmt/format.h index 29c1f8f9..c1e6d5e1 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -45,6 +45,19 @@ // The fmt library version in the form major * 10000 + minor * 100 + patch. #define FMT_VERSION 40001 +#if defined(__has_include) +# define FMT_HAS_INCLUDE(x) __has_include(x) +#else +# define FMT_HAS_INCLUDE(x) 0 +#endif + +#if FMT_HAS_INCLUDE() && __cplusplus > 201402L +# include +# define FMT_HAS_STRING_VIEW 1 +#else +# define FMT_HAS_STRING_VIEW 0 +#endif + #if defined _SECURE_SCL && _SECURE_SCL # define FMT_SECURE_SCL _SECURE_SCL #else @@ -521,6 +534,26 @@ class BasicStringRef { const std::basic_string, Allocator> &s) : data_(s.c_str()), size_(s.size()) {} +#if FMT_HAS_STRING_VIEW + /** + \rst + Constructs a string reference from a ``std::basic_string_view`` object. + \endrst + */ + BasicStringRef( + const std::basic_string_view> &s) + : data_(s.data()), size_(s.size()) {} + + /** + \rst + Converts a string reference to an ``std::string_view`` object. + \endrst + */ + explicit operator std::basic_string_view() const FMT_NOEXCEPT { + return std::basic_string_view(data_, size_); + } +#endif + /** \rst Converts a string reference to an ``std::string`` object. @@ -1299,6 +1332,9 @@ class MakeValue : public Arg { MakeValue(typename WCharHelper::Unsupported); MakeValue(typename WCharHelper::Unsupported); MakeValue(typename WCharHelper::Unsupported); +#if FMT_HAS_STRING_VIEW + MakeValue(typename WCharHelper::Unsupported); +#endif MakeValue(typename WCharHelper::Unsupported); void set_string(StringRef str) { @@ -1386,6 +1422,9 @@ class MakeValue : public Arg { FMT_MAKE_VALUE(unsigned char *, ustring.value, CSTRING) FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) FMT_MAKE_STR_VALUE(const std::string &, STRING) +#if FMT_HAS_STRING_VIEW + FMT_MAKE_STR_VALUE(const std::string_view &, STRING) +#endif FMT_MAKE_STR_VALUE(StringRef, STRING) FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str()) @@ -1398,6 +1437,9 @@ class MakeValue : public Arg { FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING) FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING) FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING) +#if FMT_HAS_STRING_VIEW + FMT_MAKE_WSTR_VALUE(const std::wstring_view &, WSTRING) +#endif FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING) FMT_MAKE_VALUE(void *, pointer, POINTER) diff --git a/test/format-test.cc b/test/format-test.cc index 6388d5a5..3fb2a78b 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -151,16 +151,31 @@ TEST(StringRefTest, Ctor) { EXPECT_STREQ("defg", StringRef(std::string("defg")).data()); EXPECT_EQ(4u, StringRef(std::string("defg")).size()); + +#if FMT_HAS_STRING_VIEW + EXPECT_STREQ("hijk", StringRef(std::string_view("hijk")).data()); + EXPECT_EQ(4u, StringRef(std::string_view("hijk")).size()); +#endif } TEST(StringRefTest, ConvertToString) { std::string s = StringRef("abc").to_string(); EXPECT_EQ("abc", s); + +#if FMT_HAS_STRING_VIEW + StringRef str_ref("defg"); + std::string_view sv = static_cast(str_ref); + EXPECT_EQ("defg", sv); +#endif } TEST(CStringRefTest, Ctor) { EXPECT_STREQ("abc", CStringRef("abc").c_str()); EXPECT_STREQ("defg", CStringRef(std::string("defg")).c_str()); + +#if FMT_HAS_STRING_VIEW + EXPECT_STREQ("hijk", CStringRef(std::string_view("hijk")).c_str()); +#endif } #if FMT_USE_TYPE_TRAITS @@ -1378,6 +1393,12 @@ TEST(FormatterTest, FormatCStringRef) { EXPECT_EQ("test", format("{0}", CStringRef("test"))); } +#if FMT_HAS_STRING_VIEW +TEST(FormatterTest, FormatStringView) { + EXPECT_EQ("test", format("{0}", std::string_view("test"))); +} +#endif + void format_arg(fmt::BasicFormatter &f, const char *, const Date &d) { f.writer() << d.year() << '-' << d.month() << '-' << d.day(); }