Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve support for printing std::basic_string_view #4624

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions googletest/include/gtest/gtest-printers.h
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,49 @@ inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
}
#endif // GTEST_HAS_STD_WSTRING

#if defined(__cpp_lib_string_view) || GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#include <string_view>

// Overloads for ::std::string_view.
#ifdef GTEST_HAS_ABSL
// Otherwise internal::StringView is implemented using ::std::string_view
// and has already overloaded PrintTo for it below.
GTEST_API_ void PrintStringTo(const ::std::string_view& sv, ::std::ostream* os);
inline void PrintTo(const ::std::string_view& sv, ::std::ostream* os) {
PrintStringTo(sv, os);
}
#endif // GTEST_HAS_ABSL

// Overloads for ::std::u8string_view
#ifdef __cpp_lib_char8_t
GTEST_API_ void PrintU8StringTo(const ::std::u8string_view& sv, ::std::ostream* os);
inline void PrintTo(const ::std::u8string_view& sv, ::std::ostream* os) {
PrintU8StringTo(sv, os);
}
#endif

// Overloads for ::std::u16string_view
GTEST_API_ void PrintU16StringTo(const ::std::u16string_view& sv, ::std::ostream* os);
inline void PrintTo(const ::std::u16string_view& sv, ::std::ostream* os) {
PrintU16StringTo(sv, os);
}

// Overloads for ::std::u32string_view
GTEST_API_ void PrintU32StringTo(const ::std::u32string_view& sv, ::std::ostream* os);
inline void PrintTo(const ::std::u32string_view& sv, ::std::ostream* os) {
PrintU32StringTo(sv, os);
}

// Overloads for ::std::wstring_view.
#if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring_view& sv, ::std::ostream* os);
inline void PrintTo(const ::std::wstring_view& sv, ::std::ostream* os) {
PrintWideStringTo(sv, os);
}
#endif // GTEST_HAS_STD_WSTRING
#endif // __cpp_lib_string_view


#if GTEST_INTERNAL_HAS_STRING_VIEW
// Overload for internal::StringView.
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
Expand Down
33 changes: 33 additions & 0 deletions googletest/src/gtest-printers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,39 @@ void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
}
#endif // GTEST_HAS_STD_WSTRING

#if defined(__cpp_lib_string_view) || GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L

#ifdef GTEST_HAS_ABSL
void PrintStringTo(const ::std::string_view& sv, ostream* os) {
if (PrintCharsAsStringTo(sv.data(), sv.size(), os) == kHexEscape) {
if (GTEST_FLAG_GET(print_utf8)) {
ConditionalPrintAsText(sv.data(), sv.size(), os);
}
}
}
#endif

#ifdef __cpp_lib_char8_t
void PrintU8StringTo(const ::std::u8string_view& sv, ostream* os) {
PrintCharsAsStringTo(sv.data(), sv.size(), os);
}
#endif

void PrintU16StringTo(const ::std::u16string_view& sv, ostream* os) {
PrintCharsAsStringTo(sv.data(), sv.size(), os);
}

void PrintU32StringTo(const ::std::u32string_view& sv, ostream* os) {
PrintCharsAsStringTo(sv.data(), sv.size(), os);
}

#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring_view& sv, ::std::ostream* os) {
PrintCharsAsStringTo(sv.data(), sv.size(), os);
}
#endif // GTEST_HAS_STD_WSTRING
#endif // __cpp_lib_string_view

} // namespace internal

} // namespace testing
102 changes: 102 additions & 0 deletions googletest/test/googletest-printers-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,108 @@ TEST(PrintStringTest, U32String) {
EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(str));
}

#if GTEST_HAS_STD_WSTRING
TEST(PrintStringTest, WString) {
std::wstring str = L"Hello, 世界";
EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type.
EXPECT_EQ("L\"Hello, \\x4E16\\x754C\"", Print(str));
}
#endif


// Tests printing ::std::basic_string_view's

#if defined(__cpp_lib_string_view) || GTEST_INTERNAL_CPLUSPLUS_LANG >= 201703L
#include <string_view>

// Tests printing ::std::string_view
#ifdef GTEST_HAS_ABSL

TEST(PrintStringViewTest, StringViewInStdNamespace) {
const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
const ::std::string_view str(s, sizeof(s));
EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
Print(str));
}
#endif // GTEST_HAS_ABSL

// Tests printing ::std::u8string_view
#ifdef __cpp_lib_char8_t
TEST(PrintStringViewTest, U8StringViewInStdNamespace) {
const char8_t s[] = u8"'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
const ::std::u8string_view str(s, sizeof(s));
EXPECT_EQ("u8\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
Print(str));
}
#endif

// Tests printing ::std::u16string_view
TEST(PrintStringViewTest, U16StringViewInStdNamespace) {
const char16_t s[] = u"'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
const ::std::u16string_view str(s, sizeof(s) / sizeof(char16_t));
EXPECT_EQ("u\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
Print(str));
}

// Tests printing ::std::u32string_view
TEST(PrintStringViewTest, U32StringViewInStdNamespace) {
const char32_t s[] = U"'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
const ::std::u32string_view str(s, sizeof(s) / sizeof(char32_t));
EXPECT_EQ("U\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
Print(str));
}

// Tests printing ::std::wstring_view
#if GTEST_HAS_STD_WSTRING
TEST(PrintStringViewTest, WStringViewInStdNamespace) {
const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a";
const ::std::wstring_view str(s, sizeof(s) / sizeof(wchar_t));
EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"",
Print(str));
}
#endif // GTEST_HAS_STD_WSTRING


#ifdef GTEST_HAS_ABSL
TEST(PrintStringViewTest, StringView) {
std::string_view sv = "Hello, world";
EXPECT_EQ(sv, sv); // Verify EXPECT_EQ compiles with this type.
EXPECT_EQ("\"Hello, world\"", Print(sv));
}
#endif // GTEST_HAS_ABSL

#ifdef __cpp_lib_char8_t
TEST(PrintStringViewTest, U8StringView) {
std::u8string_view sv = u8"Hello, 世界";
EXPECT_EQ(sv, sv); // Verify EXPECT_EQ compiles with this type.
EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(sv));
}
#endif

TEST(PrintStringViewTest, U16StringView) {
std::u16string_view sv = u"Hello, 世界";
EXPECT_EQ(sv, sv); // Verify EXPECT_EQ compiles with this type.
EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(sv));
}

TEST(PrintStringViewTest, U32StringView) {
std::u32string_view sv = U"Hello, 🗺️";
EXPECT_EQ(sv, sv); // Verify EXPECT_EQ compiles with this type
EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(sv));
}

#if GTEST_HAS_STD_WSTRING
TEST(PrintStringViewTest, WStringView) {
std::wstring_view sv = L"Hello, 世界";
EXPECT_EQ(sv, sv); // Verify EXPECT_EQ compiles with this type.
EXPECT_EQ("L\"Hello, \\x4E16\\x754C\"", Print(sv));
}
#endif


#endif // __cpp_lib_string_view


// Tests printing types that support generic streaming (i.e. streaming
// to std::basic_ostream<Char, CharTraits> for any valid Char and
// CharTraits types).
Expand Down