File indexing completed on 2025-11-03 09:50:39
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