File indexing completed on 2025-09-13 08:59:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
0105 #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
0106
0107 #include <functional>
0108 #include <memory>
0109 #include <ostream> // NOLINT
0110 #include <sstream>
0111 #include <string>
0112 #include <tuple>
0113 #include <type_traits>
0114 #include <typeinfo>
0115 #include <utility>
0116 #include <vector>
0117
0118 #ifdef GTEST_HAS_ABSL
0119 #include "absl/strings/has_absl_stringify.h"
0120 #include "absl/strings/str_cat.h"
0121 #endif
0122 #include "gtest/internal/gtest-internal.h"
0123 #include "gtest/internal/gtest-port.h"
0124
0125 #if GTEST_INTERNAL_HAS_STD_SPAN
0126 #include <span> // NOLINT
0127 #endif
0128
0129 #if GTEST_INTERNAL_HAS_COMPARE_LIB
0130 #include <compare> // NOLINT
0131 #endif
0132
0133 namespace testing {
0134
0135
0136
0137 namespace internal {
0138
0139 template <typename T>
0140 void UniversalPrint(const T& value, ::std::ostream* os);
0141
0142 template <typename T>
0143 struct IsStdSpan {
0144 static constexpr bool value = false;
0145 };
0146
0147 #if GTEST_INTERNAL_HAS_STD_SPAN
0148 template <typename E>
0149 struct IsStdSpan<std::span<E>> {
0150 static constexpr bool value = true;
0151 };
0152 #endif
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 struct ContainerPrinter {
0163 template <typename T,
0164 typename = typename std::enable_if<
0165 ((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
0166 !IsRecursiveContainer<T>::value) ||
0167 IsStdSpan<T>::value>::type>
0168 static void PrintValue(const T& container, std::ostream* os) {
0169 const size_t kMaxCount = 32;
0170 *os << '{';
0171 size_t count = 0;
0172 for (auto&& elem : container) {
0173 if (count > 0) {
0174 *os << ',';
0175 if (count == kMaxCount) {
0176 *os << " ...";
0177 break;
0178 }
0179 }
0180 *os << ' ';
0181
0182
0183 internal::UniversalPrint(elem, os);
0184 ++count;
0185 }
0186
0187 if (count > 0) {
0188 *os << ' ';
0189 }
0190 *os << '}';
0191 }
0192 };
0193
0194
0195
0196
0197
0198
0199
0200 struct FunctionPointerPrinter {
0201 template <typename T, typename = typename std::enable_if<
0202 std::is_function<T>::value>::type>
0203 static void PrintValue(T* p, ::std::ostream* os) {
0204 if (p == nullptr) {
0205 *os << "NULL";
0206 } else {
0207
0208
0209
0210 *os << reinterpret_cast<const void*>(p);
0211 }
0212 }
0213 };
0214
0215 struct PointerPrinter {
0216 template <typename T>
0217 static void PrintValue(T* p, ::std::ostream* os) {
0218 if (p == nullptr) {
0219 *os << "NULL";
0220 } else {
0221
0222
0223
0224 *os << p;
0225 }
0226 }
0227 };
0228
0229 namespace internal_stream_operator_without_lexical_name_lookup {
0230
0231
0232
0233
0234
0235 struct LookupBlocker {};
0236 void operator<<(LookupBlocker, LookupBlocker);
0237
0238 struct StreamPrinter {
0239 template <typename T,
0240
0241
0242 typename = typename std::enable_if<
0243 !std::is_member_pointer<T>::value>::type>
0244
0245
0246
0247
0248 static auto PrintValue(const T& value,
0249 ::std::ostream* os) -> decltype((void)(*os << value)) {
0250
0251
0252 *os << value;
0253 }
0254 };
0255
0256 }
0257
0258 struct ProtobufPrinter {
0259
0260
0261
0262 static const size_t kProtobufOneLinerMaxLength = 50;
0263
0264 template <typename T,
0265 typename = typename std::enable_if<
0266 internal::HasDebugStringAndShortDebugString<T>::value>::type>
0267 static void PrintValue(const T& value, ::std::ostream* os) {
0268 std::string pretty_str = value.ShortDebugString();
0269 if (pretty_str.length() > kProtobufOneLinerMaxLength) {
0270 pretty_str = "\n" + value.DebugString();
0271 }
0272 *os << ("<" + pretty_str + ">");
0273 }
0274 };
0275
0276 struct ConvertibleToIntegerPrinter {
0277
0278
0279
0280
0281
0282
0283
0284 static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
0285 *os << value;
0286 }
0287 };
0288
0289 struct ConvertibleToStringViewPrinter {
0290 #if GTEST_INTERNAL_HAS_STRING_VIEW
0291 static void PrintValue(internal::StringView value, ::std::ostream* os) {
0292 internal::UniversalPrint(value, os);
0293 }
0294 #endif
0295 };
0296
0297 #ifdef GTEST_HAS_ABSL
0298 struct ConvertibleToAbslStringifyPrinter {
0299 template <typename T,
0300 typename = typename std::enable_if<
0301 absl::HasAbslStringify<T>::value>::type>
0302 static void PrintValue(const T& value, ::std::ostream* os) {
0303 *os << absl::StrCat(value);
0304 }
0305 };
0306 #endif
0307
0308
0309
0310 GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
0311 size_t count, ::std::ostream* os);
0312 struct RawBytesPrinter {
0313
0314 template <typename T, size_t = sizeof(T)>
0315 static void PrintValue(const T& value, ::std::ostream* os) {
0316 PrintBytesInObjectTo(
0317 static_cast<const unsigned char*>(
0318
0319 reinterpret_cast<const void*>(std::addressof(value))),
0320 sizeof(value), os);
0321 }
0322 };
0323
0324 struct FallbackPrinter {
0325 template <typename T>
0326 static void PrintValue(const T&, ::std::ostream* os) {
0327 *os << "(incomplete type)";
0328 }
0329 };
0330
0331
0332 template <typename T, typename E, typename Printer, typename... Printers>
0333 struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};
0334
0335 template <typename T, typename Printer, typename... Printers>
0336 struct FindFirstPrinter<
0337 T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),
0338 Printer, Printers...> {
0339 using type = Printer;
0340 };
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351 template <typename T>
0352 void PrintWithFallback(const T& value, ::std::ostream* os) {
0353 using Printer = typename FindFirstPrinter<
0354 T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
0355 ProtobufPrinter,
0356 #ifdef GTEST_HAS_ABSL
0357 ConvertibleToAbslStringifyPrinter,
0358 #endif
0359 internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
0360 ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,
0361 RawBytesPrinter, FallbackPrinter>::type;
0362 Printer::PrintValue(value, os);
0363 }
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 template <typename ToPrint, typename OtherOperand>
0381 class FormatForComparison {
0382 public:
0383 static ::std::string Format(const ToPrint& value) {
0384 return ::testing::PrintToString(value);
0385 }
0386 };
0387
0388
0389 template <typename ToPrint, size_t N, typename OtherOperand>
0390 class FormatForComparison<ToPrint[N], OtherOperand> {
0391 public:
0392 static ::std::string Format(const ToPrint* value) {
0393 return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
0394 }
0395 };
0396
0397
0398
0399
0400 #define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
0401 template <typename OtherOperand> \
0402 class FormatForComparison<CharType*, OtherOperand> { \
0403 public: \
0404 static ::std::string Format(CharType* value) { \
0405 return ::testing::PrintToString(static_cast<const void*>(value)); \
0406 } \
0407 }
0408
0409 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
0410 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
0411 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
0412 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
0413 #ifdef __cpp_lib_char8_t
0414 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
0415 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
0416 #endif
0417 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t);
0418 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t);
0419 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t);
0420 GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);
0421
0422 #undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
0423
0424
0425
0426
0427 #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
0428 template <> \
0429 class FormatForComparison<CharType*, OtherStringType> { \
0430 public: \
0431 static ::std::string Format(CharType* value) { \
0432 return ::testing::PrintToString(value); \
0433 } \
0434 }
0435
0436 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
0437 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
0438 #ifdef __cpp_lib_char8_t
0439 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
0440 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
0441 #endif
0442 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string);
0443 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string);
0444 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string);
0445 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string);
0446
0447 #if GTEST_HAS_STD_WSTRING
0448 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
0449 GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
0450 #endif
0451
0452 #undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462 template <typename T1, typename T2>
0463 std::string FormatForComparisonFailureMessage(const T1& value,
0464 const T2& ) {
0465 return FormatForComparison<T1, T2>::Format(value);
0466 }
0467
0468
0469
0470
0471
0472
0473
0474
0475 template <typename T>
0476 class UniversalPrinter;
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489 template <typename T>
0490 void PrintTo(const T& value, ::std::ostream* os) {
0491 internal::PrintWithFallback(value, os);
0492 }
0493
0494
0495
0496
0497
0498
0499 GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
0500 GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
0501 inline void PrintTo(char c, ::std::ostream* os) {
0502
0503
0504
0505 PrintTo(static_cast<unsigned char>(c), os);
0506 }
0507
0508
0509 inline void PrintTo(bool x, ::std::ostream* os) {
0510 *os << (x ? "true" : "false");
0511 }
0512
0513
0514
0515
0516
0517
0518
0519
0520 GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
0521
0522 GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
0523 inline void PrintTo(char16_t c, ::std::ostream* os) {
0524 PrintTo(ImplicitCast_<char32_t>(c), os);
0525 }
0526 #ifdef __cpp_lib_char8_t
0527 inline void PrintTo(char8_t c, ::std::ostream* os) {
0528 PrintTo(ImplicitCast_<char32_t>(c), os);
0529 }
0530 #endif
0531
0532
0533 #if defined(__SIZEOF_INT128__)
0534 GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
0535 GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
0536 #endif
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554 template <typename FloatType>
0555 int AppropriateResolution(FloatType val) {
0556 int full = std::numeric_limits<FloatType>::max_digits10;
0557 if (val < 0) val = -val;
0558
0559 #ifdef __GNUC__
0560 #pragma GCC diagnostic push
0561 #pragma GCC diagnostic ignored "-Wfloat-equal"
0562 #endif
0563 if (val < 1000000) {
0564 FloatType mulfor6 = 1e10;
0565
0566
0567
0568 if (val >= static_cast<FloatType>(100000.0)) {
0569 mulfor6 = 1.0;
0570 } else if (val >= static_cast<FloatType>(10000.0)) {
0571 mulfor6 = 1e1;
0572 } else if (val >= static_cast<FloatType>(1000.0)) {
0573 mulfor6 = 1e2;
0574 } else if (val >= static_cast<FloatType>(100.0)) {
0575 mulfor6 = 1e3;
0576 } else if (val >= static_cast<FloatType>(10.0)) {
0577 mulfor6 = 1e4;
0578 } else if (val >= static_cast<FloatType>(1.0)) {
0579 mulfor6 = 1e5;
0580 } else if (val >= static_cast<FloatType>(0.1)) {
0581 mulfor6 = 1e6;
0582 } else if (val >= static_cast<FloatType>(0.01)) {
0583 mulfor6 = 1e7;
0584 } else if (val >= static_cast<FloatType>(0.001)) {
0585 mulfor6 = 1e8;
0586 } else if (val >= static_cast<FloatType>(0.0001)) {
0587 mulfor6 = 1e9;
0588 }
0589 if (static_cast<FloatType>(static_cast<int32_t>(
0590 val * mulfor6 + (static_cast<FloatType>(0.5)))) /
0591 mulfor6 ==
0592 val)
0593 return 6;
0594 } else if (val < static_cast<FloatType>(1e10)) {
0595 FloatType divfor6 = static_cast<FloatType>(1.0);
0596 if (val >= static_cast<FloatType>(1e9)) {
0597 divfor6 = 10000;
0598 } else if (val >=
0599 static_cast<FloatType>(1e8)) {
0600 divfor6 = 1000;
0601 } else if (val >=
0602 static_cast<FloatType>(1e7)) {
0603 divfor6 = 100;
0604 } else if (val >= static_cast<FloatType>(1e6)) {
0605 divfor6 = 10;
0606 }
0607 if (static_cast<FloatType>(static_cast<int32_t>(
0608 val / divfor6 + (static_cast<FloatType>(0.5)))) *
0609 divfor6 ==
0610 val)
0611 return 6;
0612 }
0613 #ifdef __GNUC__
0614 #pragma GCC diagnostic pop
0615 #endif
0616 return full;
0617 }
0618
0619 inline void PrintTo(float f, ::std::ostream* os) {
0620 auto old_precision = os->precision();
0621 os->precision(AppropriateResolution(f));
0622 *os << f;
0623 os->precision(old_precision);
0624 }
0625
0626 inline void PrintTo(double d, ::std::ostream* os) {
0627 auto old_precision = os->precision();
0628 os->precision(AppropriateResolution(d));
0629 *os << d;
0630 os->precision(old_precision);
0631 }
0632
0633
0634 GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
0635 inline void PrintTo(char* s, ::std::ostream* os) {
0636 PrintTo(ImplicitCast_<const char*>(s), os);
0637 }
0638
0639
0640
0641 inline void PrintTo(const signed char* s, ::std::ostream* os) {
0642 PrintTo(ImplicitCast_<const void*>(s), os);
0643 }
0644 inline void PrintTo(signed char* s, ::std::ostream* os) {
0645 PrintTo(ImplicitCast_<const void*>(s), os);
0646 }
0647 inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
0648 PrintTo(ImplicitCast_<const void*>(s), os);
0649 }
0650 inline void PrintTo(unsigned char* s, ::std::ostream* os) {
0651 PrintTo(ImplicitCast_<const void*>(s), os);
0652 }
0653 #ifdef __cpp_lib_char8_t
0654
0655 GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);
0656 inline void PrintTo(char8_t* s, ::std::ostream* os) {
0657 PrintTo(ImplicitCast_<const char8_t*>(s), os);
0658 }
0659 #endif
0660
0661 GTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os);
0662 inline void PrintTo(char16_t* s, ::std::ostream* os) {
0663 PrintTo(ImplicitCast_<const char16_t*>(s), os);
0664 }
0665
0666 GTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os);
0667 inline void PrintTo(char32_t* s, ::std::ostream* os) {
0668 PrintTo(ImplicitCast_<const char32_t*>(s), os);
0669 }
0670
0671
0672
0673
0674
0675
0676 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
0677
0678 GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
0679 inline void PrintTo(wchar_t* s, ::std::ostream* os) {
0680 PrintTo(ImplicitCast_<const wchar_t*>(s), os);
0681 }
0682 #endif
0683
0684
0685
0686
0687
0688
0689 template <typename T>
0690 void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
0691 UniversalPrint(a[0], os);
0692 for (size_t i = 1; i != count; i++) {
0693 *os << ", ";
0694 UniversalPrint(a[i], os);
0695 }
0696 }
0697
0698
0699 GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
0700 inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
0701 PrintStringTo(s, os);
0702 }
0703
0704
0705 #ifdef __cpp_lib_char8_t
0706 GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
0707 inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
0708 PrintU8StringTo(s, os);
0709 }
0710 #endif
0711
0712
0713 GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
0714 inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
0715 PrintU16StringTo(s, os);
0716 }
0717
0718
0719 GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
0720 inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
0721 PrintU32StringTo(s, os);
0722 }
0723
0724
0725 #if GTEST_HAS_STD_WSTRING
0726 GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
0727 inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
0728 PrintWideStringTo(s, os);
0729 }
0730 #endif
0731
0732 #if GTEST_INTERNAL_HAS_STRING_VIEW
0733
0734 inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
0735 PrintTo(::std::string(sp), os);
0736 }
0737 #endif
0738
0739 inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
0740
0741 #if GTEST_HAS_RTTI
0742 inline void PrintTo(const std::type_info& info, std::ostream* os) {
0743 *os << internal::GetTypeName(info);
0744 }
0745 #endif
0746
0747 template <typename T>
0748 void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
0749 UniversalPrinter<T&>::Print(ref.get(), os);
0750 }
0751
0752 inline const void* VoidifyPointer(const void* p) { return p; }
0753 inline const void* VoidifyPointer(volatile const void* p) {
0754 return const_cast<const void*>(p);
0755 }
0756
0757 template <typename T, typename Ptr>
0758 void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {
0759 if (ptr == nullptr) {
0760 *os << "(nullptr)";
0761 } else {
0762
0763 *os << "(" << (VoidifyPointer)(ptr.get()) << ")";
0764 }
0765 }
0766 template <typename T, typename Ptr,
0767 typename = typename std::enable_if<!std::is_void<T>::value &&
0768 !std::is_array<T>::value>::type>
0769 void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {
0770 if (ptr == nullptr) {
0771 *os << "(nullptr)";
0772 } else {
0773 *os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = ";
0774 UniversalPrinter<T>::Print(*ptr, os);
0775 *os << ")";
0776 }
0777 }
0778
0779 template <typename T, typename D>
0780 void PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {
0781 (PrintSmartPointer<T>)(ptr, os, 0);
0782 }
0783
0784 template <typename T>
0785 void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
0786 (PrintSmartPointer<T>)(ptr, os, 0);
0787 }
0788
0789 #if GTEST_INTERNAL_HAS_COMPARE_LIB
0790 template <typename T>
0791 void PrintOrderingHelper(T ordering, std::ostream* os) {
0792 if (ordering == T::less) {
0793 *os << "(less)";
0794 } else if (ordering == T::greater) {
0795 *os << "(greater)";
0796 } else if (ordering == T::equivalent) {
0797 *os << "(equivalent)";
0798 } else {
0799 *os << "(unknown ordering)";
0800 }
0801 }
0802
0803 inline void PrintTo(std::strong_ordering ordering, std::ostream* os) {
0804 if (ordering == std::strong_ordering::equal) {
0805 *os << "(equal)";
0806 } else {
0807 PrintOrderingHelper(ordering, os);
0808 }
0809 }
0810
0811 inline void PrintTo(std::partial_ordering ordering, std::ostream* os) {
0812 if (ordering == std::partial_ordering::unordered) {
0813 *os << "(unordered)";
0814 } else {
0815 PrintOrderingHelper(ordering, os);
0816 }
0817 }
0818
0819 inline void PrintTo(std::weak_ordering ordering, std::ostream* os) {
0820 PrintOrderingHelper(ordering, os);
0821 }
0822 #endif
0823
0824
0825
0826 template <typename T>
0827 void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
0828 ::std::ostream*) {}
0829
0830 template <typename T, size_t I>
0831 void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
0832 ::std::ostream* os) {
0833 PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
0834 GTEST_INTENTIONAL_CONST_COND_PUSH_()
0835 if (I > 1) {
0836 GTEST_INTENTIONAL_CONST_COND_POP_()
0837 *os << ", ";
0838 }
0839 UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
0840 std::get<I - 1>(t), os);
0841 }
0842
0843 template <typename... Types>
0844 void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
0845 *os << "(";
0846 PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
0847 *os << ")";
0848 }
0849
0850
0851 template <typename T1, typename T2>
0852 void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
0853 *os << '(';
0854
0855
0856 UniversalPrinter<T1>::Print(value.first, os);
0857 *os << ", ";
0858 UniversalPrinter<T2>::Print(value.second, os);
0859 *os << ')';
0860 }
0861
0862
0863
0864 template <typename T>
0865 class UniversalPrinter {
0866 public:
0867
0868
0869 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
0870
0871
0872
0873
0874 static void Print(const T& value, ::std::ostream* os) {
0875
0876
0877
0878
0879
0880
0881
0882
0883 PrintTo(value, os);
0884 }
0885
0886 GTEST_DISABLE_MSC_WARNINGS_POP_()
0887 };
0888
0889
0890 template <typename T>
0891 class UniversalPrinter<const T> : public UniversalPrinter<T> {};
0892
0893 #if GTEST_INTERNAL_HAS_ANY
0894
0895
0896
0897 template <>
0898 class UniversalPrinter<Any> {
0899 public:
0900 static void Print(const Any& value, ::std::ostream* os) {
0901 if (value.has_value()) {
0902 *os << "value of type " << GetTypeName(value);
0903 } else {
0904 *os << "no value";
0905 }
0906 }
0907
0908 private:
0909 static std::string GetTypeName(const Any& value) {
0910 #if GTEST_HAS_RTTI
0911 return internal::GetTypeName(value.type());
0912 #else
0913 static_cast<void>(value);
0914 return "<unknown_type>";
0915 #endif
0916 }
0917 };
0918
0919 #endif
0920
0921 #if GTEST_INTERNAL_HAS_OPTIONAL
0922
0923
0924
0925 template <typename T>
0926 class UniversalPrinter<Optional<T>> {
0927 public:
0928 static void Print(const Optional<T>& value, ::std::ostream* os) {
0929 *os << '(';
0930 if (!value) {
0931 *os << "nullopt";
0932 } else {
0933 UniversalPrint(*value, os);
0934 }
0935 *os << ')';
0936 }
0937 };
0938
0939 template <>
0940 class UniversalPrinter<decltype(Nullopt())> {
0941 public:
0942 static void Print(decltype(Nullopt()), ::std::ostream* os) {
0943 *os << "(nullopt)";
0944 }
0945 };
0946
0947 #endif
0948
0949 #if GTEST_INTERNAL_HAS_VARIANT
0950
0951
0952
0953 template <typename... T>
0954 class UniversalPrinter<Variant<T...>> {
0955 public:
0956 static void Print(const Variant<T...>& value, ::std::ostream* os) {
0957 *os << '(';
0958 #ifdef GTEST_HAS_ABSL
0959 absl::visit(Visitor{os, value.index()}, value);
0960 #else
0961 std::visit(Visitor{os, value.index()}, value);
0962 #endif
0963 *os << ')';
0964 }
0965
0966 private:
0967 struct Visitor {
0968 template <typename U>
0969 void operator()(const U& u) const {
0970 *os << "'" << GetTypeName<U>() << "(index = " << index
0971 << ")' with value ";
0972 UniversalPrint(u, os);
0973 }
0974 ::std::ostream* os;
0975 std::size_t index;
0976 };
0977 };
0978
0979 #endif
0980
0981
0982
0983 template <typename T>
0984 void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
0985 if (len == 0) {
0986 *os << "{}";
0987 } else {
0988 *os << "{ ";
0989 const size_t kThreshold = 18;
0990 const size_t kChunkSize = 8;
0991
0992
0993
0994 if (len <= kThreshold) {
0995 PrintRawArrayTo(begin, len, os);
0996 } else {
0997 PrintRawArrayTo(begin, kChunkSize, os);
0998 *os << ", ..., ";
0999 PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
1000 }
1001 *os << " }";
1002 }
1003 }
1004
1005 GTEST_API_ void UniversalPrintArray(const char* begin, size_t len,
1006 ::std::ostream* os);
1007
1008 #ifdef __cpp_lib_char8_t
1009
1010 GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,
1011 ::std::ostream* os);
1012 #endif
1013
1014
1015 GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,
1016 ::std::ostream* os);
1017
1018
1019 GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,
1020 ::std::ostream* os);
1021
1022
1023 GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
1024 ::std::ostream* os);
1025
1026
1027 template <typename T, size_t N>
1028 class UniversalPrinter<T[N]> {
1029 public:
1030
1031
1032 static void Print(const T (&a)[N], ::std::ostream* os) {
1033 UniversalPrintArray(a, N, os);
1034 }
1035 };
1036
1037
1038 template <typename T>
1039 class UniversalPrinter<T&> {
1040 public:
1041
1042
1043 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
1044
1045 static void Print(const T& value, ::std::ostream* os) {
1046
1047
1048 *os << "@" << reinterpret_cast<const void*>(&value) << " ";
1049
1050
1051 UniversalPrint(value, os);
1052 }
1053
1054 GTEST_DISABLE_MSC_WARNINGS_POP_()
1055 };
1056
1057
1058
1059
1060
1061 template <typename T>
1062 class UniversalTersePrinter {
1063 public:
1064 static void Print(const T& value, ::std::ostream* os) {
1065 UniversalPrint(value, os);
1066 }
1067 };
1068 template <typename T>
1069 class UniversalTersePrinter<T&> {
1070 public:
1071 static void Print(const T& value, ::std::ostream* os) {
1072 UniversalPrint(value, os);
1073 }
1074 };
1075 template <typename T>
1076 class UniversalTersePrinter<std::reference_wrapper<T>> {
1077 public:
1078 static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
1079 UniversalTersePrinter<T>::Print(value.get(), os);
1080 }
1081 };
1082 template <typename T, size_t N>
1083 class UniversalTersePrinter<T[N]> {
1084 public:
1085 static void Print(const T (&value)[N], ::std::ostream* os) {
1086 UniversalPrinter<T[N]>::Print(value, os);
1087 }
1088 };
1089 template <>
1090 class UniversalTersePrinter<const char*> {
1091 public:
1092 static void Print(const char* str, ::std::ostream* os) {
1093 if (str == nullptr) {
1094 *os << "NULL";
1095 } else {
1096 UniversalPrint(std::string(str), os);
1097 }
1098 }
1099 };
1100 template <>
1101 class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
1102 };
1103
1104 #ifdef __cpp_lib_char8_t
1105 template <>
1106 class UniversalTersePrinter<const char8_t*> {
1107 public:
1108 static void Print(const char8_t* str, ::std::ostream* os) {
1109 if (str == nullptr) {
1110 *os << "NULL";
1111 } else {
1112 UniversalPrint(::std::u8string(str), os);
1113 }
1114 }
1115 };
1116 template <>
1117 class UniversalTersePrinter<char8_t*>
1118 : public UniversalTersePrinter<const char8_t*> {};
1119 #endif
1120
1121 template <>
1122 class UniversalTersePrinter<const char16_t*> {
1123 public:
1124 static void Print(const char16_t* str, ::std::ostream* os) {
1125 if (str == nullptr) {
1126 *os << "NULL";
1127 } else {
1128 UniversalPrint(::std::u16string(str), os);
1129 }
1130 }
1131 };
1132 template <>
1133 class UniversalTersePrinter<char16_t*>
1134 : public UniversalTersePrinter<const char16_t*> {};
1135
1136 template <>
1137 class UniversalTersePrinter<const char32_t*> {
1138 public:
1139 static void Print(const char32_t* str, ::std::ostream* os) {
1140 if (str == nullptr) {
1141 *os << "NULL";
1142 } else {
1143 UniversalPrint(::std::u32string(str), os);
1144 }
1145 }
1146 };
1147 template <>
1148 class UniversalTersePrinter<char32_t*>
1149 : public UniversalTersePrinter<const char32_t*> {};
1150
1151 #if GTEST_HAS_STD_WSTRING
1152 template <>
1153 class UniversalTersePrinter<const wchar_t*> {
1154 public:
1155 static void Print(const wchar_t* str, ::std::ostream* os) {
1156 if (str == nullptr) {
1157 *os << "NULL";
1158 } else {
1159 UniversalPrint(::std::wstring(str), os);
1160 }
1161 }
1162 };
1163 #endif
1164
1165 template <>
1166 class UniversalTersePrinter<wchar_t*> {
1167 public:
1168 static void Print(wchar_t* str, ::std::ostream* os) {
1169 UniversalTersePrinter<const wchar_t*>::Print(str, os);
1170 }
1171 };
1172
1173 template <typename T>
1174 void UniversalTersePrint(const T& value, ::std::ostream* os) {
1175 UniversalTersePrinter<T>::Print(value, os);
1176 }
1177
1178
1179
1180
1181
1182 template <typename T>
1183 void UniversalPrint(const T& value, ::std::ostream* os) {
1184
1185
1186 typedef T T1;
1187 UniversalPrinter<T1>::Print(value, os);
1188 }
1189
1190 typedef ::std::vector<::std::string> Strings;
1191
1192
1193
1194 template <typename Tuple>
1195 void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
1196 Strings*) {}
1197 template <typename Tuple, size_t I>
1198 void TersePrintPrefixToStrings(const Tuple& t,
1199 std::integral_constant<size_t, I>,
1200 Strings* strings) {
1201 TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),
1202 strings);
1203 ::std::stringstream ss;
1204 UniversalTersePrint(std::get<I - 1>(t), &ss);
1205 strings->push_back(ss.str());
1206 }
1207
1208
1209
1210
1211 template <typename Tuple>
1212 Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
1213 Strings result;
1214 TersePrintPrefixToStrings(
1215 value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
1216 &result);
1217 return result;
1218 }
1219
1220 }
1221
1222 template <typename T>
1223 ::std::string PrintToString(const T& value) {
1224 ::std::stringstream ss;
1225 internal::UniversalTersePrinter<T>::Print(value, &ss);
1226 return ss.str();
1227 }
1228
1229 }
1230
1231
1232
1233
1234 #include "gtest/internal/custom/gtest-printers.h"
1235
1236 #endif