Skip to content

Commit

Permalink
Make format work with C++17 std::string_view (#571)
Browse files Browse the repository at this point in the history
Tests for C++17 std::string_view
  • Loading branch information
Mário Feroldi authored and vitaut committed Sep 20, 2017
1 parent e051de3 commit 2a619d9
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
42 changes: 42 additions & 0 deletions fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(<string_view>) && __cplusplus > 201402L
# include <string_view>
# 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
Expand Down Expand Up @@ -521,6 +534,26 @@ class BasicStringRef {
const std::basic_string<Char, std::char_traits<Char>, 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<Char, std::char_traits<Char>> &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<Char>() const FMT_NOEXCEPT {
return std::basic_string_view<Char>(data_, size_);
}
#endif

/**
\rst
Converts a string reference to an ``std::string`` object.
Expand Down Expand Up @@ -1299,6 +1332,9 @@ class MakeValue : public Arg {
MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
#if FMT_HAS_STRING_VIEW
MakeValue(typename WCharHelper<const std::wstring_view &, Char>::Unsupported);
#endif
MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);

void set_string(StringRef str) {
Expand Down Expand Up @@ -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())

Expand All @@ -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)
Expand Down
21 changes: 21 additions & 0 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string_view>(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
Expand Down Expand Up @@ -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<char> &f, const char *, const Date &d) {
f.writer() << d.year() << '-' << d.month() << '-' << d.day();
}
Expand Down

0 comments on commit 2a619d9

Please sign in to comment.