From 5705bf1c714e51e8cccbe447f1edd62202e1788f Mon Sep 17 00:00:00 2001 From: Virgilio Alexandre Fornazin Date: Sat, 16 Dec 2017 15:03:11 -0200 Subject: [PATCH] Added support for pre-c++17 experimental string_view (#607) Added support for pre-c++17 experimental string_view --- fmt/format.h | 36 ++++++++++++++++++++++++++++++++++++ test/CMakeLists.txt | 6 ++++++ test/format-test.cc | 21 +++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/fmt/format.h b/fmt/format.h index bd99746a..e13a08b9 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -55,8 +55,15 @@ (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) # include # define FMT_HAS_STRING_VIEW 1 +# define FMT_HAS_EXPERIMENTAL_STRING_VIEW 0 #else # define FMT_HAS_STRING_VIEW 0 +# if (FMT_HAS_INCLUDE() && __cplusplus > 201402L) +# include +# define FMT_HAS_EXPERIMENTAL_STRING_VIEW 1 +# else +# define FMT_HAS_EXPERIMENTAL_STRING_VIEW 0 +# endif #endif #if defined _SECURE_SCL && _SECURE_SCL @@ -582,6 +589,26 @@ class BasicStringRef { } #endif +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW + /** + \rst + Constructs a string reference from a ``std::experimental::basic_string_view`` object. + \endrst + */ + BasicStringRef( + const std::experimental::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::experimental::basic_string_view() const FMT_NOEXCEPT { + return std::experimental::basic_string_view(data_, size_); + } +#endif + /** \rst Converts a string reference to an ``std::string`` object. @@ -1367,6 +1394,9 @@ class MakeValue : public Arg { MakeValue(typename WCharHelper::Unsupported); #if FMT_HAS_STRING_VIEW MakeValue(typename WCharHelper::Unsupported); +#endif +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW + MakeValue(typename WCharHelper::Unsupported); #endif MakeValue(typename WCharHelper::Unsupported); @@ -1471,6 +1501,9 @@ class MakeValue : public Arg { FMT_MAKE_STR_VALUE(const std::string &, STRING) #if FMT_HAS_STRING_VIEW FMT_MAKE_STR_VALUE(const std::string_view &, STRING) +#endif +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW + FMT_MAKE_STR_VALUE(const std::experimental::string_view &, STRING) #endif FMT_MAKE_STR_VALUE(StringRef, STRING) FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str()) @@ -1486,6 +1519,9 @@ class MakeValue : public Arg { FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING) #if FMT_HAS_STRING_VIEW FMT_MAKE_WSTR_VALUE(const std::wstring_view &, WSTRING) +#endif +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW + FMT_MAKE_WSTR_VALUE(const std::experimental::wstring_view &, WSTRING) #endif FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 31a418de..1b25948b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,6 +11,12 @@ target_compile_options(gmock PUBLIC ${CPP11_FLAG}) target_compile_definitions(gmock PUBLIC GTEST_HAS_STD_WSTRING=1) target_include_directories(gmock PUBLIC .) +# Workaround for Cygwin to make google-tests compile and run because the macro +# _POSIX_C_SOURCE must be defined to allow fileno(), strdup(), fdopen() calls. +if (CYGWIN) + target_compile_definitions(gmock PUBLIC _POSIX_C_SOURCE=200809) +endif () + find_package(Threads) if (Threads_FOUND) target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT}) diff --git a/test/format-test.cc b/test/format-test.cc index f512ef48..3f2ac042 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -156,6 +156,11 @@ TEST(StringRefTest, Ctor) { EXPECT_STREQ("hijk", StringRef(std::string_view("hijk")).data()); EXPECT_EQ(4u, StringRef(std::string_view("hijk")).size()); #endif + +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW + EXPECT_STREQ("hijk", StringRef(std::experimental::string_view("hijk")).data()); + EXPECT_EQ(4u, StringRef(std::experimental::string_view("hijk")).size()); +#endif } TEST(StringRefTest, ConvertToString) { @@ -167,6 +172,12 @@ TEST(StringRefTest, ConvertToString) { std::string_view sv = static_cast(str_ref); EXPECT_EQ("defg", sv); #endif + +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW + StringRef str_ref("defg"); + std::experimental::string_view sv = static_cast(str_ref); + EXPECT_EQ("defg", sv); +#endif } TEST(CStringRefTest, Ctor) { @@ -176,6 +187,10 @@ TEST(CStringRefTest, Ctor) { #if FMT_HAS_STRING_VIEW EXPECT_STREQ("hijk", CStringRef(std::string_view("hijk")).c_str()); #endif + +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW + EXPECT_STREQ("hijk", CStringRef(std::experimental::string_view("hijk")).c_str()); +#endif } #if FMT_USE_TYPE_TRAITS @@ -1399,6 +1414,12 @@ TEST(FormatterTest, FormatStringView) { } #endif +#if FMT_HAS_EXPERIMENTAL_STRING_VIEW +TEST(FormatterTest, FormatExperimentalStringView) { + EXPECT_EQ("test", format("{0}", std::experimental::string_view("test"))); +} +#endif + void format_arg(fmt::BasicFormatter &f, const char *, const Date &d) { f.writer() << d.year() << '-' << d.month() << '-' << d.day(); }