Skip to content

Commit 1a8ecf1

Browse files
Abseil Teamderekmauro
authored andcommitted
Googletest export
Print std::u8string, std::u16string, and std::u32string as string literals Previously, these types were printed as "{ U+123, U+456, U+789 }". However, printed output in that form is difficult to compare against any literals that might be defined in code. Instead, just treat these types like std::string and std::wstring, escaping non-ASCII characters with a hexadecimal escape sequence. The tests have also been updated to cover the new functionality: as a bonus, the tests now also pass with the MSVC toolchain. Internally, the code has been reorganized to primarily operate in terms of char32_t, under the assumption that char32_t will always be at least as big as wchar_t. While that assumption is currently true, perhaps it won't be in the future... PiperOrigin-RevId: 364033132
1 parent 3ff1e8b commit 1a8ecf1

File tree

7 files changed

+394
-181
lines changed

7 files changed

+394
-181
lines changed

BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ config_setting(
4343
constraint_values = ["@platforms//os:windows"],
4444
)
4545

46+
config_setting(
47+
name = "msvc_compiler",
48+
flag_values = {
49+
"@bazel_tools//tools/cpp:compiler": "msvc-cl",
50+
},
51+
visibility = [":__subpackages__"],
52+
)
53+
4654
config_setting(
4755
name = "has_absl",
4856
values = {"define": "absl=1"},

googletest/cmake/internal_utils.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ macro(config_compiler_and_linker)
8181
# Suppress "unreachable code" warning
8282
# http://stackoverflow.com/questions/3232669 explains the issue.
8383
set(cxx_base_flags "${cxx_base_flags} -wd4702")
84+
# Ensure MSVC treats source files as UTF-8 encoded.
85+
set(cxx_base_flags "${cxx_base_flags} -utf-8")
8486
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
8587
set(cxx_base_flags "-Wall -Wshadow -Werror -Wconversion")
8688
set(cxx_exception_flags "-fexceptions")

googletest/include/gtest/gtest-printers.h

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -505,24 +505,21 @@ inline void PrintTo(unsigned char* s, ::std::ostream* os) {
505505
PrintTo(ImplicitCast_<const void*>(s), os);
506506
}
507507
#ifdef __cpp_char8_t
508-
inline void PrintTo(const char8_t* s, ::std::ostream* os) {
509-
PrintTo(ImplicitCast_<const void*>(s), os);
510-
}
508+
// Overloads for u8 strings.
509+
void PrintTo(const char8_t* s, ::std::ostream* os);
511510
inline void PrintTo(char8_t* s, ::std::ostream* os) {
512-
PrintTo(ImplicitCast_<const void*>(s), os);
511+
PrintTo(ImplicitCast_<const char8_t*>(s), os);
513512
}
514513
#endif
515-
inline void PrintTo(const char16_t* s, ::std::ostream* os) {
516-
PrintTo(ImplicitCast_<const void*>(s), os);
517-
}
514+
// Overloads for u16 strings.
515+
void PrintTo(const char16_t* s, ::std::ostream* os);
518516
inline void PrintTo(char16_t* s, ::std::ostream* os) {
519-
PrintTo(ImplicitCast_<const void*>(s), os);
520-
}
521-
inline void PrintTo(const char32_t* s, ::std::ostream* os) {
522-
PrintTo(ImplicitCast_<const void*>(s), os);
517+
PrintTo(ImplicitCast_<const char16_t*>(s), os);
523518
}
519+
// Overloads for u32 strings.
520+
void PrintTo(const char32_t* s, ::std::ostream* os);
524521
inline void PrintTo(char32_t* s, ::std::ostream* os) {
525-
PrintTo(ImplicitCast_<const void*>(s), os);
522+
PrintTo(ImplicitCast_<const char32_t*>(s), os);
526523
}
527524

528525
// MSVC can be configured to define wchar_t as a typedef of unsigned
@@ -558,6 +555,26 @@ inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
558555
PrintStringTo(s, os);
559556
}
560557

558+
// Overloads for ::std::u8string
559+
#ifdef __cpp_char8_t
560+
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
561+
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
562+
PrintU8StringTo(s, os);
563+
}
564+
#endif
565+
566+
// Overloads for ::std::u16string
567+
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
568+
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
569+
PrintU16StringTo(s, os);
570+
}
571+
572+
// Overloads for ::std::u32string
573+
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
574+
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
575+
PrintU32StringTo(s, os);
576+
}
577+
561578
// Overloads for ::std::wstring.
562579
#if GTEST_HAS_STD_WSTRING
563580
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
@@ -805,6 +822,20 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
805822
GTEST_API_ void UniversalPrintArray(
806823
const char* begin, size_t len, ::std::ostream* os);
807824

825+
#ifdef __cpp_char8_t
826+
// This overload prints a (const) char8_t array compactly.
827+
GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,
828+
::std::ostream* os);
829+
#endif
830+
831+
// This overload prints a (const) char16_t array compactly.
832+
GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,
833+
::std::ostream* os);
834+
835+
// This overload prints a (const) char32_t array compactly.
836+
GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,
837+
::std::ostream* os);
838+
808839
// This overload prints a (const) wchar_t array compactly.
809840
GTEST_API_ void UniversalPrintArray(
810841
const wchar_t* begin, size_t len, ::std::ostream* os);
@@ -877,12 +908,55 @@ class UniversalTersePrinter<const char*> {
877908
}
878909
};
879910
template <>
880-
class UniversalTersePrinter<char*> {
911+
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
912+
};
913+
914+
#ifdef __cpp_char8_t
915+
template <>
916+
class UniversalTersePrinter<const char8_t*> {
917+
public:
918+
static void Print(const char8_t* str, ::std::ostream* os) {
919+
if (str == nullptr) {
920+
*os << "NULL";
921+
} else {
922+
UniversalPrint(::std::u8string(str), os);
923+
}
924+
}
925+
};
926+
template <>
927+
class UniversalTersePrinter<char8_t*>
928+
: public UniversalTersePrinter<const char8_t*> {};
929+
#endif
930+
931+
template <>
932+
class UniversalTersePrinter<const char16_t*> {
933+
public:
934+
static void Print(const char16_t* str, ::std::ostream* os) {
935+
if (str == nullptr) {
936+
*os << "NULL";
937+
} else {
938+
UniversalPrint(::std::u16string(str), os);
939+
}
940+
}
941+
};
942+
template <>
943+
class UniversalTersePrinter<char16_t*>
944+
: public UniversalTersePrinter<const char16_t*> {};
945+
946+
template <>
947+
class UniversalTersePrinter<const char32_t*> {
881948
public:
882-
static void Print(char* str, ::std::ostream* os) {
883-
UniversalTersePrinter<const char*>::Print(str, os);
949+
static void Print(const char32_t* str, ::std::ostream* os) {
950+
if (str == nullptr) {
951+
*os << "NULL";
952+
} else {
953+
UniversalPrint(::std::u32string(str), os);
954+
}
884955
}
885956
};
957+
template <>
958+
class UniversalTersePrinter<char32_t*>
959+
: public UniversalTersePrinter<const char32_t*> {};
886960

887961
#if GTEST_HAS_STD_WSTRING
888962
template <>

googletest/include/gtest/internal/gtest-port.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,19 @@ inline bool IsUpper(char ch) {
19361936
inline bool IsXDigit(char ch) {
19371937
return isxdigit(static_cast<unsigned char>(ch)) != 0;
19381938
}
1939+
#ifdef __cpp_char8_t
1940+
inline bool IsXDigit(char8_t ch) {
1941+
return isxdigit(static_cast<unsigned char>(ch)) != 0;
1942+
}
1943+
#endif
1944+
inline bool IsXDigit(char16_t ch) {
1945+
const unsigned char low_byte = static_cast<unsigned char>(ch);
1946+
return ch == low_byte && isxdigit(low_byte) != 0;
1947+
}
1948+
inline bool IsXDigit(char32_t ch) {
1949+
const unsigned char low_byte = static_cast<unsigned char>(ch);
1950+
return ch == low_byte && isxdigit(low_byte) != 0;
1951+
}
19391952
inline bool IsXDigit(wchar_t ch) {
19401953
const unsigned char low_byte = static_cast<unsigned char>(ch);
19411954
return ch == low_byte && isxdigit(low_byte) != 0;

0 commit comments

Comments
 (0)