xref: /freebsd-src/contrib/googletest/googletest/include/gtest/gtest-printers.h (revision 5ca8c28cd8c725b81781201cfdb5f9969396f934)
1b89a7cc2SEnji Cooper // Copyright 2007, Google Inc.
2b89a7cc2SEnji Cooper // All rights reserved.
3b89a7cc2SEnji Cooper //
4b89a7cc2SEnji Cooper // Redistribution and use in source and binary forms, with or without
5b89a7cc2SEnji Cooper // modification, are permitted provided that the following conditions are
6b89a7cc2SEnji Cooper // met:
7b89a7cc2SEnji Cooper //
8b89a7cc2SEnji Cooper //     * Redistributions of source code must retain the above copyright
9b89a7cc2SEnji Cooper // notice, this list of conditions and the following disclaimer.
10b89a7cc2SEnji Cooper //     * Redistributions in binary form must reproduce the above
11b89a7cc2SEnji Cooper // copyright notice, this list of conditions and the following disclaimer
12b89a7cc2SEnji Cooper // in the documentation and/or other materials provided with the
13b89a7cc2SEnji Cooper // distribution.
14b89a7cc2SEnji Cooper //     * Neither the name of Google Inc. nor the names of its
15b89a7cc2SEnji Cooper // contributors may be used to endorse or promote products derived from
16b89a7cc2SEnji Cooper // this software without specific prior written permission.
17b89a7cc2SEnji Cooper //
18b89a7cc2SEnji Cooper // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19b89a7cc2SEnji Cooper // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20b89a7cc2SEnji Cooper // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21b89a7cc2SEnji Cooper // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22b89a7cc2SEnji Cooper // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23b89a7cc2SEnji Cooper // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24b89a7cc2SEnji Cooper // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25b89a7cc2SEnji Cooper // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26b89a7cc2SEnji Cooper // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b89a7cc2SEnji Cooper // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28b89a7cc2SEnji Cooper // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29b89a7cc2SEnji Cooper 
30b89a7cc2SEnji Cooper // Google Test - The Google C++ Testing and Mocking Framework
31b89a7cc2SEnji Cooper //
32b89a7cc2SEnji Cooper // This file implements a universal value printer that can print a
33b89a7cc2SEnji Cooper // value of any type T:
34b89a7cc2SEnji Cooper //
35b89a7cc2SEnji Cooper //   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
36b89a7cc2SEnji Cooper //
37b89a7cc2SEnji Cooper // A user can teach this function how to print a class type T by
38b89a7cc2SEnji Cooper // defining either operator<<() or PrintTo() in the namespace that
39b89a7cc2SEnji Cooper // defines T.  More specifically, the FIRST defined function in the
40b89a7cc2SEnji Cooper // following list will be used (assuming T is defined in namespace
41b89a7cc2SEnji Cooper // foo):
42b89a7cc2SEnji Cooper //
43b89a7cc2SEnji Cooper //   1. foo::PrintTo(const T&, ostream*)
44b89a7cc2SEnji Cooper //   2. operator<<(ostream&, const T&) defined in either foo or the
45b89a7cc2SEnji Cooper //      global namespace.
4628f6c2f2SEnji Cooper // * Prefer AbslStringify(..) to operator<<(..), per https://abseil.io/tips/215.
4728f6c2f2SEnji Cooper // * Define foo::PrintTo(..) if the type already has AbslStringify(..), but an
4828f6c2f2SEnji Cooper //   alternative presentation in test results is of interest.
49b89a7cc2SEnji Cooper //
50b89a7cc2SEnji Cooper // However if T is an STL-style container then it is printed element-wise
51b89a7cc2SEnji Cooper // unless foo::PrintTo(const T&, ostream*) is defined. Note that
52b89a7cc2SEnji Cooper // operator<<() is ignored for container types.
53b89a7cc2SEnji Cooper //
54b89a7cc2SEnji Cooper // If none of the above is defined, it will print the debug string of
55b89a7cc2SEnji Cooper // the value if it is a protocol buffer, or print the raw bytes in the
56b89a7cc2SEnji Cooper // value otherwise.
57b89a7cc2SEnji Cooper //
58b89a7cc2SEnji Cooper // To aid debugging: when T is a reference type, the address of the
59b89a7cc2SEnji Cooper // value is also printed; when T is a (const) char pointer, both the
60b89a7cc2SEnji Cooper // pointer value and the NUL-terminated string it points to are
61b89a7cc2SEnji Cooper // printed.
62b89a7cc2SEnji Cooper //
63b89a7cc2SEnji Cooper // We also provide some convenient wrappers:
64b89a7cc2SEnji Cooper //
65b89a7cc2SEnji Cooper //   // Prints a value to a string.  For a (const or not) char
66b89a7cc2SEnji Cooper //   // pointer, the NUL-terminated string (but not the pointer) is
67b89a7cc2SEnji Cooper //   // printed.
68b89a7cc2SEnji Cooper //   std::string ::testing::PrintToString(const T& value);
69b89a7cc2SEnji Cooper //
70b89a7cc2SEnji Cooper //   // Prints a value tersely: for a reference type, the referenced
71b89a7cc2SEnji Cooper //   // value (but not the address) is printed; for a (const or not) char
72b89a7cc2SEnji Cooper //   // pointer, the NUL-terminated string (but not the pointer) is
73b89a7cc2SEnji Cooper //   // printed.
74b89a7cc2SEnji Cooper //   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
75b89a7cc2SEnji Cooper //
76b89a7cc2SEnji Cooper //   // Prints value using the type inferred by the compiler.  The difference
77b89a7cc2SEnji Cooper //   // from UniversalTersePrint() is that this function prints both the
78b89a7cc2SEnji Cooper //   // pointer and the NUL-terminated string for a (const or not) char pointer.
79b89a7cc2SEnji Cooper //   void ::testing::internal::UniversalPrint(const T& value, ostream*);
80b89a7cc2SEnji Cooper //
81b89a7cc2SEnji Cooper //   // Prints the fields of a tuple tersely to a string vector, one
82b89a7cc2SEnji Cooper //   // element for each field. Tuple support must be enabled in
83b89a7cc2SEnji Cooper //   // gtest-port.h.
84b89a7cc2SEnji Cooper //   std::vector<string> UniversalTersePrintTupleFieldsToStrings(
85b89a7cc2SEnji Cooper //       const Tuple& value);
86b89a7cc2SEnji Cooper //
87b89a7cc2SEnji Cooper // Known limitation:
88b89a7cc2SEnji Cooper //
89b89a7cc2SEnji Cooper // The print primitives print the elements of an STL-style container
90b89a7cc2SEnji Cooper // using the compiler-inferred type of *iter where iter is a
91b89a7cc2SEnji Cooper // const_iterator of the container.  When const_iterator is an input
92b89a7cc2SEnji Cooper // iterator but not a forward iterator, this inferred type may not
93b89a7cc2SEnji Cooper // match value_type, and the print output may be incorrect.  In
94b89a7cc2SEnji Cooper // practice, this is rarely a problem as for most containers
95b89a7cc2SEnji Cooper // const_iterator is a forward iterator.  We'll fix this if there's an
96b89a7cc2SEnji Cooper // actual need for it.  Note that this fix cannot rely on value_type
97b89a7cc2SEnji Cooper // being defined as many user-defined container types don't have
98b89a7cc2SEnji Cooper // value_type.
99b89a7cc2SEnji Cooper 
10028f6c2f2SEnji Cooper // IWYU pragma: private, include "gtest/gtest.h"
10128f6c2f2SEnji Cooper // IWYU pragma: friend gtest/.*
10228f6c2f2SEnji Cooper // IWYU pragma: friend gmock/.*
103b89a7cc2SEnji Cooper 
10428f6c2f2SEnji Cooper #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
10528f6c2f2SEnji Cooper #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
106b89a7cc2SEnji Cooper 
10728f6c2f2SEnji Cooper #include <functional>
10828f6c2f2SEnji Cooper #include <memory>
109b89a7cc2SEnji Cooper #include <ostream>  // NOLINT
110b89a7cc2SEnji Cooper #include <sstream>
111b89a7cc2SEnji Cooper #include <string>
11228f6c2f2SEnji Cooper #include <tuple>
11328f6c2f2SEnji Cooper #include <type_traits>
11428f6c2f2SEnji Cooper #include <typeinfo>
115b89a7cc2SEnji Cooper #include <utility>
116b89a7cc2SEnji Cooper #include <vector>
117b89a7cc2SEnji Cooper 
11828f6c2f2SEnji Cooper #ifdef GTEST_HAS_ABSL
119*5ca8c28cSEnji Cooper #include "absl/strings/has_absl_stringify.h"
12028f6c2f2SEnji Cooper #include "absl/strings/str_cat.h"
121b89a7cc2SEnji Cooper #endif  // GTEST_HAS_ABSL
12228f6c2f2SEnji Cooper #include "gtest/internal/gtest-internal.h"
12328f6c2f2SEnji Cooper #include "gtest/internal/gtest-port.h"
124b89a7cc2SEnji Cooper 
125*5ca8c28cSEnji Cooper #if GTEST_INTERNAL_HAS_STD_SPAN
126*5ca8c28cSEnji Cooper #include <span>  // NOLINT
127*5ca8c28cSEnji Cooper #endif           // GTEST_INTERNAL_HAS_STD_SPAN
128*5ca8c28cSEnji Cooper 
129b89a7cc2SEnji Cooper namespace testing {
130b89a7cc2SEnji Cooper 
13128f6c2f2SEnji Cooper // Definitions in the internal* namespaces are subject to change without notice.
13228f6c2f2SEnji Cooper // DO NOT USE THEM IN USER CODE!
13328f6c2f2SEnji Cooper namespace internal {
134b89a7cc2SEnji Cooper 
13528f6c2f2SEnji Cooper template <typename T>
13628f6c2f2SEnji Cooper void UniversalPrint(const T& value, ::std::ostream* os);
137b89a7cc2SEnji Cooper 
138*5ca8c28cSEnji Cooper template <typename T>
139*5ca8c28cSEnji Cooper struct IsStdSpan {
140*5ca8c28cSEnji Cooper   static constexpr bool value = false;
141*5ca8c28cSEnji Cooper };
142*5ca8c28cSEnji Cooper 
143*5ca8c28cSEnji Cooper #if GTEST_INTERNAL_HAS_STD_SPAN
144*5ca8c28cSEnji Cooper template <typename E>
145*5ca8c28cSEnji Cooper struct IsStdSpan<std::span<E>> {
146*5ca8c28cSEnji Cooper   static constexpr bool value = true;
147*5ca8c28cSEnji Cooper };
148*5ca8c28cSEnji Cooper #endif  // GTEST_INTERNAL_HAS_STD_SPAN
149*5ca8c28cSEnji Cooper 
15028f6c2f2SEnji Cooper // Used to print an STL-style container when the user doesn't define
15128f6c2f2SEnji Cooper // a PrintTo() for it.
152*5ca8c28cSEnji Cooper //
153*5ca8c28cSEnji Cooper // NOTE: Since std::span does not have const_iterator until C++23, it would
154*5ca8c28cSEnji Cooper // fail IsContainerTest before C++23. However, IsContainerTest only uses
155*5ca8c28cSEnji Cooper // the presence of const_iterator to avoid treating iterators as containers
156*5ca8c28cSEnji Cooper // because of iterator::iterator. Which means std::span satisfies the *intended*
157*5ca8c28cSEnji Cooper // condition of IsContainerTest.
15828f6c2f2SEnji Cooper struct ContainerPrinter {
15928f6c2f2SEnji Cooper   template <typename T,
16028f6c2f2SEnji Cooper             typename = typename std::enable_if<
161*5ca8c28cSEnji Cooper                 ((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
162*5ca8c28cSEnji Cooper                  !IsRecursiveContainer<T>::value) ||
163*5ca8c28cSEnji Cooper                 IsStdSpan<T>::value>::type>
16428f6c2f2SEnji Cooper   static void PrintValue(const T& container, std::ostream* os) {
16528f6c2f2SEnji Cooper     const size_t kMaxCount = 32;  // The maximum number of elements to print.
16628f6c2f2SEnji Cooper     *os << '{';
16728f6c2f2SEnji Cooper     size_t count = 0;
16828f6c2f2SEnji Cooper     for (auto&& elem : container) {
16928f6c2f2SEnji Cooper       if (count > 0) {
17028f6c2f2SEnji Cooper         *os << ',';
17128f6c2f2SEnji Cooper         if (count == kMaxCount) {  // Enough has been printed.
17228f6c2f2SEnji Cooper           *os << " ...";
17328f6c2f2SEnji Cooper           break;
17428f6c2f2SEnji Cooper         }
17528f6c2f2SEnji Cooper       }
17628f6c2f2SEnji Cooper       *os << ' ';
17728f6c2f2SEnji Cooper       // We cannot call PrintTo(elem, os) here as PrintTo() doesn't
17828f6c2f2SEnji Cooper       // handle `elem` being a native array.
17928f6c2f2SEnji Cooper       internal::UniversalPrint(elem, os);
18028f6c2f2SEnji Cooper       ++count;
18128f6c2f2SEnji Cooper     }
182b89a7cc2SEnji Cooper 
18328f6c2f2SEnji Cooper     if (count > 0) {
18428f6c2f2SEnji Cooper       *os << ' ';
18528f6c2f2SEnji Cooper     }
18628f6c2f2SEnji Cooper     *os << '}';
187b89a7cc2SEnji Cooper   }
188b89a7cc2SEnji Cooper };
189b89a7cc2SEnji Cooper 
19028f6c2f2SEnji Cooper // Used to print a pointer that is neither a char pointer nor a member
19128f6c2f2SEnji Cooper // pointer, when the user doesn't define PrintTo() for it.  (A member
19228f6c2f2SEnji Cooper // variable pointer or member function pointer doesn't really point to
19328f6c2f2SEnji Cooper // a location in the address space.  Their representation is
19428f6c2f2SEnji Cooper // implementation-defined.  Therefore they will be printed as raw
19528f6c2f2SEnji Cooper // bytes.)
19628f6c2f2SEnji Cooper struct FunctionPointerPrinter {
19728f6c2f2SEnji Cooper   template <typename T, typename = typename std::enable_if<
19828f6c2f2SEnji Cooper                             std::is_function<T>::value>::type>
19928f6c2f2SEnji Cooper   static void PrintValue(T* p, ::std::ostream* os) {
20028f6c2f2SEnji Cooper     if (p == nullptr) {
20128f6c2f2SEnji Cooper       *os << "NULL";
20228f6c2f2SEnji Cooper     } else {
20328f6c2f2SEnji Cooper       // T is a function type, so '*os << p' doesn't do what we want
20428f6c2f2SEnji Cooper       // (it just prints p as bool).  We want to print p as a const
20528f6c2f2SEnji Cooper       // void*.
20628f6c2f2SEnji Cooper       *os << reinterpret_cast<const void*>(p);
20728f6c2f2SEnji Cooper     }
20828f6c2f2SEnji Cooper   }
20928f6c2f2SEnji Cooper };
21028f6c2f2SEnji Cooper 
21128f6c2f2SEnji Cooper struct PointerPrinter {
21228f6c2f2SEnji Cooper   template <typename T>
21328f6c2f2SEnji Cooper   static void PrintValue(T* p, ::std::ostream* os) {
21428f6c2f2SEnji Cooper     if (p == nullptr) {
21528f6c2f2SEnji Cooper       *os << "NULL";
21628f6c2f2SEnji Cooper     } else {
21728f6c2f2SEnji Cooper       // T is not a function type.  We just call << to print p,
21828f6c2f2SEnji Cooper       // relying on ADL to pick up user-defined << for their pointer
21928f6c2f2SEnji Cooper       // types, if any.
22028f6c2f2SEnji Cooper       *os << p;
22128f6c2f2SEnji Cooper     }
22228f6c2f2SEnji Cooper   }
22328f6c2f2SEnji Cooper };
22428f6c2f2SEnji Cooper 
22528f6c2f2SEnji Cooper namespace internal_stream_operator_without_lexical_name_lookup {
22628f6c2f2SEnji Cooper 
22728f6c2f2SEnji Cooper // The presence of an operator<< here will terminate lexical scope lookup
22828f6c2f2SEnji Cooper // straight away (even though it cannot be a match because of its argument
22928f6c2f2SEnji Cooper // types). Thus, the two operator<< calls in StreamPrinter will find only ADL
23028f6c2f2SEnji Cooper // candidates.
23128f6c2f2SEnji Cooper struct LookupBlocker {};
23228f6c2f2SEnji Cooper void operator<<(LookupBlocker, LookupBlocker);
23328f6c2f2SEnji Cooper 
23428f6c2f2SEnji Cooper struct StreamPrinter {
23528f6c2f2SEnji Cooper   template <typename T,
23628f6c2f2SEnji Cooper             // Don't accept member pointers here. We'd print them via implicit
23728f6c2f2SEnji Cooper             // conversion to bool, which isn't useful.
23828f6c2f2SEnji Cooper             typename = typename std::enable_if<
23928f6c2f2SEnji Cooper                 !std::is_member_pointer<T>::value>::type>
24028f6c2f2SEnji Cooper   // Only accept types for which we can find a streaming operator via
24128f6c2f2SEnji Cooper   // ADL (possibly involving implicit conversions).
24228f6c2f2SEnji Cooper   // (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
24328f6c2f2SEnji Cooper   // lookup properly when we do it in the template parameter list.)
244*5ca8c28cSEnji Cooper   static auto PrintValue(const T& value,
245*5ca8c28cSEnji Cooper                          ::std::ostream* os) -> decltype((void)(*os << value)) {
24628f6c2f2SEnji Cooper     // Call streaming operator found by ADL, possibly with implicit conversions
24728f6c2f2SEnji Cooper     // of the arguments.
24828f6c2f2SEnji Cooper     *os << value;
24928f6c2f2SEnji Cooper   }
25028f6c2f2SEnji Cooper };
25128f6c2f2SEnji Cooper 
25228f6c2f2SEnji Cooper }  // namespace internal_stream_operator_without_lexical_name_lookup
25328f6c2f2SEnji Cooper 
25428f6c2f2SEnji Cooper struct ProtobufPrinter {
255b89a7cc2SEnji Cooper   // We print a protobuf using its ShortDebugString() when the string
256b89a7cc2SEnji Cooper   // doesn't exceed this many characters; otherwise we print it using
257b89a7cc2SEnji Cooper   // DebugString() for better readability.
25828f6c2f2SEnji Cooper   static const size_t kProtobufOneLinerMaxLength = 50;
259b89a7cc2SEnji Cooper 
26028f6c2f2SEnji Cooper   template <typename T,
26128f6c2f2SEnji Cooper             typename = typename std::enable_if<
26228f6c2f2SEnji Cooper                 internal::HasDebugStringAndShortDebugString<T>::value>::type>
263b89a7cc2SEnji Cooper   static void PrintValue(const T& value, ::std::ostream* os) {
264b89a7cc2SEnji Cooper     std::string pretty_str = value.ShortDebugString();
265b89a7cc2SEnji Cooper     if (pretty_str.length() > kProtobufOneLinerMaxLength) {
266b89a7cc2SEnji Cooper       pretty_str = "\n" + value.DebugString();
267b89a7cc2SEnji Cooper     }
268b89a7cc2SEnji Cooper     *os << ("<" + pretty_str + ">");
269b89a7cc2SEnji Cooper   }
270b89a7cc2SEnji Cooper };
271b89a7cc2SEnji Cooper 
27228f6c2f2SEnji Cooper struct ConvertibleToIntegerPrinter {
273b89a7cc2SEnji Cooper   // Since T has no << operator or PrintTo() but can be implicitly
274b89a7cc2SEnji Cooper   // converted to BiggestInt, we print it as a BiggestInt.
275b89a7cc2SEnji Cooper   //
276b89a7cc2SEnji Cooper   // Most likely T is an enum type (either named or unnamed), in which
277b89a7cc2SEnji Cooper   // case printing it as an integer is the desired behavior.  In case
278b89a7cc2SEnji Cooper   // T is not an enum, printing it as an integer is the best we can do
279b89a7cc2SEnji Cooper   // given that it has no user-defined printer.
28028f6c2f2SEnji Cooper   static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
281b89a7cc2SEnji Cooper     *os << value;
282b89a7cc2SEnji Cooper   }
28328f6c2f2SEnji Cooper };
284b89a7cc2SEnji Cooper 
28528f6c2f2SEnji Cooper struct ConvertibleToStringViewPrinter {
28628f6c2f2SEnji Cooper #if GTEST_INTERNAL_HAS_STRING_VIEW
28728f6c2f2SEnji Cooper   static void PrintValue(internal::StringView value, ::std::ostream* os) {
28828f6c2f2SEnji Cooper     internal::UniversalPrint(value, os);
28928f6c2f2SEnji Cooper   }
29028f6c2f2SEnji Cooper #endif
29128f6c2f2SEnji Cooper };
292b89a7cc2SEnji Cooper 
29328f6c2f2SEnji Cooper #ifdef GTEST_HAS_ABSL
29428f6c2f2SEnji Cooper struct ConvertibleToAbslStringifyPrinter {
295*5ca8c28cSEnji Cooper   template <typename T,
29628f6c2f2SEnji Cooper             typename = typename std::enable_if<
297*5ca8c28cSEnji Cooper                 absl::HasAbslStringify<T>::value>::type>  // NOLINT
29828f6c2f2SEnji Cooper   static void PrintValue(const T& value, ::std::ostream* os) {
29928f6c2f2SEnji Cooper     *os << absl::StrCat(value);
30028f6c2f2SEnji Cooper   }
30128f6c2f2SEnji Cooper };
30228f6c2f2SEnji Cooper #endif  // GTEST_HAS_ABSL
30328f6c2f2SEnji Cooper 
30428f6c2f2SEnji Cooper // Prints the given number of bytes in the given object to the given
30528f6c2f2SEnji Cooper // ostream.
30628f6c2f2SEnji Cooper GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
30728f6c2f2SEnji Cooper                                      size_t count, ::std::ostream* os);
30828f6c2f2SEnji Cooper struct RawBytesPrinter {
30928f6c2f2SEnji Cooper   // SFINAE on `sizeof` to make sure we have a complete type.
31028f6c2f2SEnji Cooper   template <typename T, size_t = sizeof(T)>
31128f6c2f2SEnji Cooper   static void PrintValue(const T& value, ::std::ostream* os) {
31228f6c2f2SEnji Cooper     PrintBytesInObjectTo(
31328f6c2f2SEnji Cooper         static_cast<const unsigned char*>(
31428f6c2f2SEnji Cooper             // Load bearing cast to void* to support iOS
31528f6c2f2SEnji Cooper             reinterpret_cast<const void*>(std::addressof(value))),
31628f6c2f2SEnji Cooper         sizeof(value), os);
31728f6c2f2SEnji Cooper   }
31828f6c2f2SEnji Cooper };
31928f6c2f2SEnji Cooper 
32028f6c2f2SEnji Cooper struct FallbackPrinter {
32128f6c2f2SEnji Cooper   template <typename T>
32228f6c2f2SEnji Cooper   static void PrintValue(const T&, ::std::ostream* os) {
32328f6c2f2SEnji Cooper     *os << "(incomplete type)";
32428f6c2f2SEnji Cooper   }
32528f6c2f2SEnji Cooper };
32628f6c2f2SEnji Cooper 
32728f6c2f2SEnji Cooper // Try every printer in order and return the first one that works.
32828f6c2f2SEnji Cooper template <typename T, typename E, typename Printer, typename... Printers>
32928f6c2f2SEnji Cooper struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};
33028f6c2f2SEnji Cooper 
33128f6c2f2SEnji Cooper template <typename T, typename Printer, typename... Printers>
33228f6c2f2SEnji Cooper struct FindFirstPrinter<
33328f6c2f2SEnji Cooper     T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),
33428f6c2f2SEnji Cooper     Printer, Printers...> {
33528f6c2f2SEnji Cooper   using type = Printer;
33628f6c2f2SEnji Cooper };
33728f6c2f2SEnji Cooper 
33828f6c2f2SEnji Cooper // Select the best printer in the following order:
33928f6c2f2SEnji Cooper //  - Print containers (they have begin/end/etc).
34028f6c2f2SEnji Cooper //  - Print function pointers.
34128f6c2f2SEnji Cooper //  - Print object pointers.
34228f6c2f2SEnji Cooper //  - Print protocol buffers.
34328f6c2f2SEnji Cooper //  - Use the stream operator, if available.
34428f6c2f2SEnji Cooper //  - Print types convertible to BiggestInt.
34528f6c2f2SEnji Cooper //  - Print types convertible to StringView, if available.
34628f6c2f2SEnji Cooper //  - Fallback to printing the raw bytes of the object.
34728f6c2f2SEnji Cooper template <typename T>
34828f6c2f2SEnji Cooper void PrintWithFallback(const T& value, ::std::ostream* os) {
34928f6c2f2SEnji Cooper   using Printer = typename FindFirstPrinter<
35028f6c2f2SEnji Cooper       T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
35128f6c2f2SEnji Cooper       ProtobufPrinter,
35228f6c2f2SEnji Cooper #ifdef GTEST_HAS_ABSL
35328f6c2f2SEnji Cooper       ConvertibleToAbslStringifyPrinter,
35428f6c2f2SEnji Cooper #endif  // GTEST_HAS_ABSL
35528f6c2f2SEnji Cooper       internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
35628f6c2f2SEnji Cooper       ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,
35728f6c2f2SEnji Cooper       RawBytesPrinter, FallbackPrinter>::type;
35828f6c2f2SEnji Cooper   Printer::PrintValue(value, os);
35928f6c2f2SEnji Cooper }
360b89a7cc2SEnji Cooper 
361b89a7cc2SEnji Cooper // FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
362b89a7cc2SEnji Cooper // value of type ToPrint that is an operand of a comparison assertion
363b89a7cc2SEnji Cooper // (e.g. ASSERT_EQ).  OtherOperand is the type of the other operand in
364b89a7cc2SEnji Cooper // the comparison, and is used to help determine the best way to
365b89a7cc2SEnji Cooper // format the value.  In particular, when the value is a C string
366b89a7cc2SEnji Cooper // (char pointer) and the other operand is an STL string object, we
367b89a7cc2SEnji Cooper // want to format the C string as a string, since we know it is
368b89a7cc2SEnji Cooper // compared by value with the string object.  If the value is a char
369b89a7cc2SEnji Cooper // pointer but the other operand is not an STL string object, we don't
370b89a7cc2SEnji Cooper // know whether the pointer is supposed to point to a NUL-terminated
371b89a7cc2SEnji Cooper // string, and thus want to print it as a pointer to be safe.
372b89a7cc2SEnji Cooper //
373b89a7cc2SEnji Cooper // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
374b89a7cc2SEnji Cooper 
375b89a7cc2SEnji Cooper // The default case.
376b89a7cc2SEnji Cooper template <typename ToPrint, typename OtherOperand>
377b89a7cc2SEnji Cooper class FormatForComparison {
378b89a7cc2SEnji Cooper  public:
379b89a7cc2SEnji Cooper   static ::std::string Format(const ToPrint& value) {
380b89a7cc2SEnji Cooper     return ::testing::PrintToString(value);
381b89a7cc2SEnji Cooper   }
382b89a7cc2SEnji Cooper };
383b89a7cc2SEnji Cooper 
384b89a7cc2SEnji Cooper // Array.
385b89a7cc2SEnji Cooper template <typename ToPrint, size_t N, typename OtherOperand>
386b89a7cc2SEnji Cooper class FormatForComparison<ToPrint[N], OtherOperand> {
387b89a7cc2SEnji Cooper  public:
388b89a7cc2SEnji Cooper   static ::std::string Format(const ToPrint* value) {
389b89a7cc2SEnji Cooper     return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
390b89a7cc2SEnji Cooper   }
391b89a7cc2SEnji Cooper };
392b89a7cc2SEnji Cooper 
393b89a7cc2SEnji Cooper // By default, print C string as pointers to be safe, as we don't know
394b89a7cc2SEnji Cooper // whether they actually point to a NUL-terminated string.
395b89a7cc2SEnji Cooper 
396b89a7cc2SEnji Cooper #define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType)                \
397b89a7cc2SEnji Cooper   template <typename OtherOperand>                                      \
398b89a7cc2SEnji Cooper   class FormatForComparison<CharType*, OtherOperand> {                  \
399b89a7cc2SEnji Cooper    public:                                                              \
400b89a7cc2SEnji Cooper     static ::std::string Format(CharType* value) {                      \
401b89a7cc2SEnji Cooper       return ::testing::PrintToString(static_cast<const void*>(value)); \
402b89a7cc2SEnji Cooper     }                                                                   \
403b89a7cc2SEnji Cooper   }
404b89a7cc2SEnji Cooper 
405b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
406b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
407b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
408b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
40928f6c2f2SEnji Cooper #ifdef __cpp_lib_char8_t
41028f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
41128f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
41228f6c2f2SEnji Cooper #endif
41328f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t);
41428f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t);
41528f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t);
41628f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);
417b89a7cc2SEnji Cooper 
418b89a7cc2SEnji Cooper #undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
419b89a7cc2SEnji Cooper 
420b89a7cc2SEnji Cooper // If a C string is compared with an STL string object, we know it's meant
421b89a7cc2SEnji Cooper // to point to a NUL-terminated string, and thus can print it as a string.
422b89a7cc2SEnji Cooper 
423b89a7cc2SEnji Cooper #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
424b89a7cc2SEnji Cooper   template <>                                                            \
425b89a7cc2SEnji Cooper   class FormatForComparison<CharType*, OtherStringType> {                \
426b89a7cc2SEnji Cooper    public:                                                               \
427b89a7cc2SEnji Cooper     static ::std::string Format(CharType* value) {                       \
428b89a7cc2SEnji Cooper       return ::testing::PrintToString(value);                            \
429b89a7cc2SEnji Cooper     }                                                                    \
430b89a7cc2SEnji Cooper   }
431b89a7cc2SEnji Cooper 
432b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
433b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
43428f6c2f2SEnji Cooper #ifdef __cpp_lib_char8_t
43528f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
43628f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
437b89a7cc2SEnji Cooper #endif
43828f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string);
43928f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string);
44028f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string);
44128f6c2f2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string);
442b89a7cc2SEnji Cooper 
443b89a7cc2SEnji Cooper #if GTEST_HAS_STD_WSTRING
444b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
445b89a7cc2SEnji Cooper GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
446b89a7cc2SEnji Cooper #endif
447b89a7cc2SEnji Cooper 
448b89a7cc2SEnji Cooper #undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
449b89a7cc2SEnji Cooper 
450b89a7cc2SEnji Cooper // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
451b89a7cc2SEnji Cooper // operand to be used in a failure message.  The type (but not value)
452b89a7cc2SEnji Cooper // of the other operand may affect the format.  This allows us to
453b89a7cc2SEnji Cooper // print a char* as a raw pointer when it is compared against another
454b89a7cc2SEnji Cooper // char* or void*, and print it as a C string when it is compared
455b89a7cc2SEnji Cooper // against an std::string object, for example.
456b89a7cc2SEnji Cooper //
457b89a7cc2SEnji Cooper // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
458b89a7cc2SEnji Cooper template <typename T1, typename T2>
45928f6c2f2SEnji Cooper std::string FormatForComparisonFailureMessage(const T1& value,
46028f6c2f2SEnji Cooper                                               const T2& /* other_operand */) {
461b89a7cc2SEnji Cooper   return FormatForComparison<T1, T2>::Format(value);
462b89a7cc2SEnji Cooper }
463b89a7cc2SEnji Cooper 
464b89a7cc2SEnji Cooper // UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
465b89a7cc2SEnji Cooper // value to the given ostream.  The caller must ensure that
466b89a7cc2SEnji Cooper // 'ostream_ptr' is not NULL, or the behavior is undefined.
467b89a7cc2SEnji Cooper //
468b89a7cc2SEnji Cooper // We define UniversalPrinter as a class template (as opposed to a
469b89a7cc2SEnji Cooper // function template), as we need to partially specialize it for
470b89a7cc2SEnji Cooper // reference types, which cannot be done with function templates.
471b89a7cc2SEnji Cooper template <typename T>
472b89a7cc2SEnji Cooper class UniversalPrinter;
473b89a7cc2SEnji Cooper 
474b89a7cc2SEnji Cooper // Prints the given value using the << operator if it has one;
475b89a7cc2SEnji Cooper // otherwise prints the bytes in it.  This is what
476b89a7cc2SEnji Cooper // UniversalPrinter<T>::Print() does when PrintTo() is not specialized
477b89a7cc2SEnji Cooper // or overloaded for type T.
478b89a7cc2SEnji Cooper //
479b89a7cc2SEnji Cooper // A user can override this behavior for a class type Foo by defining
480b89a7cc2SEnji Cooper // an overload of PrintTo() in the namespace where Foo is defined.  We
481b89a7cc2SEnji Cooper // give the user this option as sometimes defining a << operator for
482b89a7cc2SEnji Cooper // Foo is not desirable (e.g. the coding style may prevent doing it,
483b89a7cc2SEnji Cooper // or there is already a << operator but it doesn't do what the user
484b89a7cc2SEnji Cooper // wants).
485b89a7cc2SEnji Cooper template <typename T>
486b89a7cc2SEnji Cooper void PrintTo(const T& value, ::std::ostream* os) {
48728f6c2f2SEnji Cooper   internal::PrintWithFallback(value, os);
488b89a7cc2SEnji Cooper }
489b89a7cc2SEnji Cooper 
490b89a7cc2SEnji Cooper // The following list of PrintTo() overloads tells
491b89a7cc2SEnji Cooper // UniversalPrinter<T>::Print() how to print standard types (built-in
492b89a7cc2SEnji Cooper // types, strings, plain arrays, and pointers).
493b89a7cc2SEnji Cooper 
494b89a7cc2SEnji Cooper // Overloads for various char types.
495b89a7cc2SEnji Cooper GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
496b89a7cc2SEnji Cooper GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
497b89a7cc2SEnji Cooper inline void PrintTo(char c, ::std::ostream* os) {
498b89a7cc2SEnji Cooper   // When printing a plain char, we always treat it as unsigned.  This
499b89a7cc2SEnji Cooper   // way, the output won't be affected by whether the compiler thinks
500b89a7cc2SEnji Cooper   // char is signed or not.
501b89a7cc2SEnji Cooper   PrintTo(static_cast<unsigned char>(c), os);
502b89a7cc2SEnji Cooper }
503b89a7cc2SEnji Cooper 
504b89a7cc2SEnji Cooper // Overloads for other simple built-in types.
505b89a7cc2SEnji Cooper inline void PrintTo(bool x, ::std::ostream* os) {
506b89a7cc2SEnji Cooper   *os << (x ? "true" : "false");
507b89a7cc2SEnji Cooper }
508b89a7cc2SEnji Cooper 
509b89a7cc2SEnji Cooper // Overload for wchar_t type.
510b89a7cc2SEnji Cooper // Prints a wchar_t as a symbol if it is printable or as its internal
511b89a7cc2SEnji Cooper // code otherwise and also as its decimal code (except for L'\0').
512b89a7cc2SEnji Cooper // The L'\0' char is printed as "L'\\0'". The decimal code is printed
513b89a7cc2SEnji Cooper // as signed integer when wchar_t is implemented by the compiler
514b89a7cc2SEnji Cooper // as a signed type and is printed as an unsigned integer when wchar_t
515b89a7cc2SEnji Cooper // is implemented as an unsigned type.
516b89a7cc2SEnji Cooper GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
517b89a7cc2SEnji Cooper 
51828f6c2f2SEnji Cooper GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
51928f6c2f2SEnji Cooper inline void PrintTo(char16_t c, ::std::ostream* os) {
52028f6c2f2SEnji Cooper   PrintTo(ImplicitCast_<char32_t>(c), os);
52128f6c2f2SEnji Cooper }
52228f6c2f2SEnji Cooper #ifdef __cpp_lib_char8_t
52328f6c2f2SEnji Cooper inline void PrintTo(char8_t c, ::std::ostream* os) {
52428f6c2f2SEnji Cooper   PrintTo(ImplicitCast_<char32_t>(c), os);
52528f6c2f2SEnji Cooper }
52628f6c2f2SEnji Cooper #endif
52728f6c2f2SEnji Cooper 
52828f6c2f2SEnji Cooper // gcc/clang __{u,}int128_t
52928f6c2f2SEnji Cooper #if defined(__SIZEOF_INT128__)
53028f6c2f2SEnji Cooper GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
53128f6c2f2SEnji Cooper GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
53228f6c2f2SEnji Cooper #endif  // __SIZEOF_INT128__
53328f6c2f2SEnji Cooper 
53428f6c2f2SEnji Cooper // The default resolution used to print floating-point values uses only
53528f6c2f2SEnji Cooper // 6 digits, which can be confusing if a test compares two values whose
53628f6c2f2SEnji Cooper // difference lies in the 7th digit.  So we'd like to print out numbers
53728f6c2f2SEnji Cooper // in full precision.
53828f6c2f2SEnji Cooper // However if the value is something simple like 1.1, full will print a
53928f6c2f2SEnji Cooper // long string like 1.100000001 due to floating-point numbers not using
54028f6c2f2SEnji Cooper // a base of 10.  This routiune returns an appropriate resolution for a
54128f6c2f2SEnji Cooper // given floating-point number, that is, 6 if it will be accurate, or a
54228f6c2f2SEnji Cooper // max_digits10 value (full precision) if it won't,  for values between
54328f6c2f2SEnji Cooper // 0.0001 and one million.
54428f6c2f2SEnji Cooper // It does this by computing what those digits would be (by multiplying
54528f6c2f2SEnji Cooper // by an appropriate power of 10), then dividing by that power again to
54628f6c2f2SEnji Cooper // see if gets the original value back.
54728f6c2f2SEnji Cooper // A similar algorithm applies for values larger than one million; note
54828f6c2f2SEnji Cooper // that for those values, we must divide to get a six-digit number, and
54928f6c2f2SEnji Cooper // then multiply to possibly get the original value again.
55028f6c2f2SEnji Cooper template <typename FloatType>
55128f6c2f2SEnji Cooper int AppropriateResolution(FloatType val) {
55228f6c2f2SEnji Cooper   int full = std::numeric_limits<FloatType>::max_digits10;
55328f6c2f2SEnji Cooper   if (val < 0) val = -val;
55428f6c2f2SEnji Cooper 
555*5ca8c28cSEnji Cooper #ifdef __GNUC__
556*5ca8c28cSEnji Cooper #pragma GCC diagnostic push
557*5ca8c28cSEnji Cooper #pragma GCC diagnostic ignored "-Wfloat-equal"
558*5ca8c28cSEnji Cooper #endif
55928f6c2f2SEnji Cooper   if (val < 1000000) {
56028f6c2f2SEnji Cooper     FloatType mulfor6 = 1e10;
561*5ca8c28cSEnji Cooper     // Without these static casts, the template instantiation for float would
562*5ca8c28cSEnji Cooper     // fail to compile when -Wdouble-promotion is enabled, as the arithmetic and
563*5ca8c28cSEnji Cooper     // comparison logic would promote floats to doubles.
564*5ca8c28cSEnji Cooper     if (val >= static_cast<FloatType>(100000.0)) {  // 100,000 to 999,999
56528f6c2f2SEnji Cooper       mulfor6 = 1.0;
566*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(10000.0)) {
56728f6c2f2SEnji Cooper       mulfor6 = 1e1;
568*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(1000.0)) {
56928f6c2f2SEnji Cooper       mulfor6 = 1e2;
570*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(100.0)) {
57128f6c2f2SEnji Cooper       mulfor6 = 1e3;
572*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(10.0)) {
57328f6c2f2SEnji Cooper       mulfor6 = 1e4;
574*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(1.0)) {
57528f6c2f2SEnji Cooper       mulfor6 = 1e5;
576*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(0.1)) {
57728f6c2f2SEnji Cooper       mulfor6 = 1e6;
578*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(0.01)) {
57928f6c2f2SEnji Cooper       mulfor6 = 1e7;
580*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(0.001)) {
58128f6c2f2SEnji Cooper       mulfor6 = 1e8;
582*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(0.0001)) {
58328f6c2f2SEnji Cooper       mulfor6 = 1e9;
58428f6c2f2SEnji Cooper     }
585*5ca8c28cSEnji Cooper     if (static_cast<FloatType>(static_cast<int32_t>(
586*5ca8c28cSEnji Cooper             val * mulfor6 + (static_cast<FloatType>(0.5)))) /
58728f6c2f2SEnji Cooper             mulfor6 ==
58828f6c2f2SEnji Cooper         val)
58928f6c2f2SEnji Cooper       return 6;
590*5ca8c28cSEnji Cooper   } else if (val < static_cast<FloatType>(1e10)) {
591*5ca8c28cSEnji Cooper     FloatType divfor6 = static_cast<FloatType>(1.0);
592*5ca8c28cSEnji Cooper     if (val >= static_cast<FloatType>(1e9)) {  // 1,000,000,000 to 9,999,999,999
59328f6c2f2SEnji Cooper       divfor6 = 10000;
594*5ca8c28cSEnji Cooper     } else if (val >=
595*5ca8c28cSEnji Cooper                static_cast<FloatType>(1e8)) {  // 100,000,000 to 999,999,999
59628f6c2f2SEnji Cooper       divfor6 = 1000;
597*5ca8c28cSEnji Cooper     } else if (val >=
598*5ca8c28cSEnji Cooper                static_cast<FloatType>(1e7)) {  // 10,000,000 to 99,999,999
59928f6c2f2SEnji Cooper       divfor6 = 100;
600*5ca8c28cSEnji Cooper     } else if (val >= static_cast<FloatType>(1e6)) {  // 1,000,000 to 9,999,999
60128f6c2f2SEnji Cooper       divfor6 = 10;
60228f6c2f2SEnji Cooper     }
603*5ca8c28cSEnji Cooper     if (static_cast<FloatType>(static_cast<int32_t>(
604*5ca8c28cSEnji Cooper             val / divfor6 + (static_cast<FloatType>(0.5)))) *
60528f6c2f2SEnji Cooper             divfor6 ==
60628f6c2f2SEnji Cooper         val)
60728f6c2f2SEnji Cooper       return 6;
60828f6c2f2SEnji Cooper   }
609*5ca8c28cSEnji Cooper #ifdef __GNUC__
610*5ca8c28cSEnji Cooper #pragma GCC diagnostic pop
611*5ca8c28cSEnji Cooper #endif
61228f6c2f2SEnji Cooper   return full;
61328f6c2f2SEnji Cooper }
61428f6c2f2SEnji Cooper 
61528f6c2f2SEnji Cooper inline void PrintTo(float f, ::std::ostream* os) {
61628f6c2f2SEnji Cooper   auto old_precision = os->precision();
61728f6c2f2SEnji Cooper   os->precision(AppropriateResolution(f));
61828f6c2f2SEnji Cooper   *os << f;
61928f6c2f2SEnji Cooper   os->precision(old_precision);
62028f6c2f2SEnji Cooper }
62128f6c2f2SEnji Cooper 
62228f6c2f2SEnji Cooper inline void PrintTo(double d, ::std::ostream* os) {
62328f6c2f2SEnji Cooper   auto old_precision = os->precision();
62428f6c2f2SEnji Cooper   os->precision(AppropriateResolution(d));
62528f6c2f2SEnji Cooper   *os << d;
62628f6c2f2SEnji Cooper   os->precision(old_precision);
62728f6c2f2SEnji Cooper }
62828f6c2f2SEnji Cooper 
629b89a7cc2SEnji Cooper // Overloads for C strings.
630b89a7cc2SEnji Cooper GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
631b89a7cc2SEnji Cooper inline void PrintTo(char* s, ::std::ostream* os) {
632b89a7cc2SEnji Cooper   PrintTo(ImplicitCast_<const char*>(s), os);
633b89a7cc2SEnji Cooper }
634b89a7cc2SEnji Cooper 
635b89a7cc2SEnji Cooper // signed/unsigned char is often used for representing binary data, so
636b89a7cc2SEnji Cooper // we print pointers to it as void* to be safe.
637b89a7cc2SEnji Cooper inline void PrintTo(const signed char* s, ::std::ostream* os) {
638b89a7cc2SEnji Cooper   PrintTo(ImplicitCast_<const void*>(s), os);
639b89a7cc2SEnji Cooper }
640b89a7cc2SEnji Cooper inline void PrintTo(signed char* s, ::std::ostream* os) {
641b89a7cc2SEnji Cooper   PrintTo(ImplicitCast_<const void*>(s), os);
642b89a7cc2SEnji Cooper }
643b89a7cc2SEnji Cooper inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
644b89a7cc2SEnji Cooper   PrintTo(ImplicitCast_<const void*>(s), os);
645b89a7cc2SEnji Cooper }
646b89a7cc2SEnji Cooper inline void PrintTo(unsigned char* s, ::std::ostream* os) {
647b89a7cc2SEnji Cooper   PrintTo(ImplicitCast_<const void*>(s), os);
648b89a7cc2SEnji Cooper }
64928f6c2f2SEnji Cooper #ifdef __cpp_lib_char8_t
65028f6c2f2SEnji Cooper // Overloads for u8 strings.
65128f6c2f2SEnji Cooper GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);
65228f6c2f2SEnji Cooper inline void PrintTo(char8_t* s, ::std::ostream* os) {
65328f6c2f2SEnji Cooper   PrintTo(ImplicitCast_<const char8_t*>(s), os);
65428f6c2f2SEnji Cooper }
65528f6c2f2SEnji Cooper #endif
65628f6c2f2SEnji Cooper // Overloads for u16 strings.
65728f6c2f2SEnji Cooper GTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os);
65828f6c2f2SEnji Cooper inline void PrintTo(char16_t* s, ::std::ostream* os) {
65928f6c2f2SEnji Cooper   PrintTo(ImplicitCast_<const char16_t*>(s), os);
66028f6c2f2SEnji Cooper }
66128f6c2f2SEnji Cooper // Overloads for u32 strings.
66228f6c2f2SEnji Cooper GTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os);
66328f6c2f2SEnji Cooper inline void PrintTo(char32_t* s, ::std::ostream* os) {
66428f6c2f2SEnji Cooper   PrintTo(ImplicitCast_<const char32_t*>(s), os);
66528f6c2f2SEnji Cooper }
666b89a7cc2SEnji Cooper 
667b89a7cc2SEnji Cooper // MSVC can be configured to define wchar_t as a typedef of unsigned
668b89a7cc2SEnji Cooper // short.  It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
669b89a7cc2SEnji Cooper // type.  When wchar_t is a typedef, defining an overload for const
670b89a7cc2SEnji Cooper // wchar_t* would cause unsigned short* be printed as a wide string,
671b89a7cc2SEnji Cooper // possibly causing invalid memory accesses.
672b89a7cc2SEnji Cooper #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
673b89a7cc2SEnji Cooper // Overloads for wide C strings
674b89a7cc2SEnji Cooper GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
675b89a7cc2SEnji Cooper inline void PrintTo(wchar_t* s, ::std::ostream* os) {
676b89a7cc2SEnji Cooper   PrintTo(ImplicitCast_<const wchar_t*>(s), os);
677b89a7cc2SEnji Cooper }
678b89a7cc2SEnji Cooper #endif
679b89a7cc2SEnji Cooper 
680b89a7cc2SEnji Cooper // Overload for C arrays.  Multi-dimensional arrays are printed
681b89a7cc2SEnji Cooper // properly.
682b89a7cc2SEnji Cooper 
683b89a7cc2SEnji Cooper // Prints the given number of elements in an array, without printing
684b89a7cc2SEnji Cooper // the curly braces.
685b89a7cc2SEnji Cooper template <typename T>
686b89a7cc2SEnji Cooper void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
687b89a7cc2SEnji Cooper   UniversalPrint(a[0], os);
688b89a7cc2SEnji Cooper   for (size_t i = 1; i != count; i++) {
689b89a7cc2SEnji Cooper     *os << ", ";
690b89a7cc2SEnji Cooper     UniversalPrint(a[i], os);
691b89a7cc2SEnji Cooper   }
692b89a7cc2SEnji Cooper }
693b89a7cc2SEnji Cooper 
69428f6c2f2SEnji Cooper // Overloads for ::std::string.
695b89a7cc2SEnji Cooper GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
696b89a7cc2SEnji Cooper inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
697b89a7cc2SEnji Cooper   PrintStringTo(s, os);
698b89a7cc2SEnji Cooper }
699b89a7cc2SEnji Cooper 
70028f6c2f2SEnji Cooper // Overloads for ::std::u8string
70128f6c2f2SEnji Cooper #ifdef __cpp_lib_char8_t
70228f6c2f2SEnji Cooper GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
70328f6c2f2SEnji Cooper inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
70428f6c2f2SEnji Cooper   PrintU8StringTo(s, os);
705b89a7cc2SEnji Cooper }
70628f6c2f2SEnji Cooper #endif
707b89a7cc2SEnji Cooper 
70828f6c2f2SEnji Cooper // Overloads for ::std::u16string
70928f6c2f2SEnji Cooper GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
71028f6c2f2SEnji Cooper inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
71128f6c2f2SEnji Cooper   PrintU16StringTo(s, os);
71228f6c2f2SEnji Cooper }
71328f6c2f2SEnji Cooper 
71428f6c2f2SEnji Cooper // Overloads for ::std::u32string
71528f6c2f2SEnji Cooper GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
71628f6c2f2SEnji Cooper inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
71728f6c2f2SEnji Cooper   PrintU32StringTo(s, os);
71828f6c2f2SEnji Cooper }
71928f6c2f2SEnji Cooper 
72028f6c2f2SEnji Cooper // Overloads for ::std::wstring.
721b89a7cc2SEnji Cooper #if GTEST_HAS_STD_WSTRING
722b89a7cc2SEnji Cooper GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
723b89a7cc2SEnji Cooper inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
724b89a7cc2SEnji Cooper   PrintWideStringTo(s, os);
725b89a7cc2SEnji Cooper }
726b89a7cc2SEnji Cooper #endif  // GTEST_HAS_STD_WSTRING
727b89a7cc2SEnji Cooper 
72828f6c2f2SEnji Cooper #if GTEST_INTERNAL_HAS_STRING_VIEW
72928f6c2f2SEnji Cooper // Overload for internal::StringView.
73028f6c2f2SEnji Cooper inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
731b89a7cc2SEnji Cooper   PrintTo(::std::string(sp), os);
732b89a7cc2SEnji Cooper }
73328f6c2f2SEnji Cooper #endif  // GTEST_INTERNAL_HAS_STRING_VIEW
734b89a7cc2SEnji Cooper 
735b89a7cc2SEnji Cooper inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
736b89a7cc2SEnji Cooper 
73728f6c2f2SEnji Cooper #if GTEST_HAS_RTTI
73828f6c2f2SEnji Cooper inline void PrintTo(const std::type_info& info, std::ostream* os) {
73928f6c2f2SEnji Cooper   *os << internal::GetTypeName(info);
74028f6c2f2SEnji Cooper }
74128f6c2f2SEnji Cooper #endif  // GTEST_HAS_RTTI
74228f6c2f2SEnji Cooper 
74328f6c2f2SEnji Cooper template <typename T>
74428f6c2f2SEnji Cooper void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
74528f6c2f2SEnji Cooper   UniversalPrinter<T&>::Print(ref.get(), os);
74628f6c2f2SEnji Cooper }
74728f6c2f2SEnji Cooper 
74828f6c2f2SEnji Cooper inline const void* VoidifyPointer(const void* p) { return p; }
74928f6c2f2SEnji Cooper inline const void* VoidifyPointer(volatile const void* p) {
75028f6c2f2SEnji Cooper   return const_cast<const void*>(p);
75128f6c2f2SEnji Cooper }
75228f6c2f2SEnji Cooper 
75328f6c2f2SEnji Cooper template <typename T, typename Ptr>
75428f6c2f2SEnji Cooper void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {
75528f6c2f2SEnji Cooper   if (ptr == nullptr) {
75628f6c2f2SEnji Cooper     *os << "(nullptr)";
75728f6c2f2SEnji Cooper   } else {
75828f6c2f2SEnji Cooper     // We can't print the value. Just print the pointer..
75928f6c2f2SEnji Cooper     *os << "(" << (VoidifyPointer)(ptr.get()) << ")";
76028f6c2f2SEnji Cooper   }
76128f6c2f2SEnji Cooper }
76228f6c2f2SEnji Cooper template <typename T, typename Ptr,
76328f6c2f2SEnji Cooper           typename = typename std::enable_if<!std::is_void<T>::value &&
76428f6c2f2SEnji Cooper                                              !std::is_array<T>::value>::type>
76528f6c2f2SEnji Cooper void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {
76628f6c2f2SEnji Cooper   if (ptr == nullptr) {
76728f6c2f2SEnji Cooper     *os << "(nullptr)";
76828f6c2f2SEnji Cooper   } else {
76928f6c2f2SEnji Cooper     *os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = ";
77028f6c2f2SEnji Cooper     UniversalPrinter<T>::Print(*ptr, os);
77128f6c2f2SEnji Cooper     *os << ")";
77228f6c2f2SEnji Cooper   }
77328f6c2f2SEnji Cooper }
77428f6c2f2SEnji Cooper 
77528f6c2f2SEnji Cooper template <typename T, typename D>
77628f6c2f2SEnji Cooper void PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {
77728f6c2f2SEnji Cooper   (PrintSmartPointer<T>)(ptr, os, 0);
77828f6c2f2SEnji Cooper }
77928f6c2f2SEnji Cooper 
78028f6c2f2SEnji Cooper template <typename T>
78128f6c2f2SEnji Cooper void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
78228f6c2f2SEnji Cooper   (PrintSmartPointer<T>)(ptr, os, 0);
78328f6c2f2SEnji Cooper }
78428f6c2f2SEnji Cooper 
785b89a7cc2SEnji Cooper // Helper function for printing a tuple.  T must be instantiated with
786b89a7cc2SEnji Cooper // a tuple type.
787b89a7cc2SEnji Cooper template <typename T>
78828f6c2f2SEnji Cooper void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
78928f6c2f2SEnji Cooper                   ::std::ostream*) {}
790b89a7cc2SEnji Cooper 
79128f6c2f2SEnji Cooper template <typename T, size_t I>
79228f6c2f2SEnji Cooper void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
793b89a7cc2SEnji Cooper                   ::std::ostream* os) {
79428f6c2f2SEnji Cooper   PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
79528f6c2f2SEnji Cooper   GTEST_INTENTIONAL_CONST_COND_PUSH_()
79628f6c2f2SEnji Cooper   if (I > 1) {
79728f6c2f2SEnji Cooper     GTEST_INTENTIONAL_CONST_COND_POP_()
79828f6c2f2SEnji Cooper     *os << ", ";
79928f6c2f2SEnji Cooper   }
80028f6c2f2SEnji Cooper   UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
80128f6c2f2SEnji Cooper       std::get<I - 1>(t), os);
802b89a7cc2SEnji Cooper }
803b89a7cc2SEnji Cooper 
804b89a7cc2SEnji Cooper template <typename... Types>
805b89a7cc2SEnji Cooper void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
80628f6c2f2SEnji Cooper   *os << "(";
80728f6c2f2SEnji Cooper   PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
80828f6c2f2SEnji Cooper   *os << ")";
809b89a7cc2SEnji Cooper }
810b89a7cc2SEnji Cooper 
811b89a7cc2SEnji Cooper // Overload for std::pair.
812b89a7cc2SEnji Cooper template <typename T1, typename T2>
813b89a7cc2SEnji Cooper void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
814b89a7cc2SEnji Cooper   *os << '(';
815b89a7cc2SEnji Cooper   // We cannot use UniversalPrint(value.first, os) here, as T1 may be
816b89a7cc2SEnji Cooper   // a reference type.  The same for printing value.second.
817b89a7cc2SEnji Cooper   UniversalPrinter<T1>::Print(value.first, os);
818b89a7cc2SEnji Cooper   *os << ", ";
819b89a7cc2SEnji Cooper   UniversalPrinter<T2>::Print(value.second, os);
820b89a7cc2SEnji Cooper   *os << ')';
821b89a7cc2SEnji Cooper }
822b89a7cc2SEnji Cooper 
823b89a7cc2SEnji Cooper // Implements printing a non-reference type T by letting the compiler
824b89a7cc2SEnji Cooper // pick the right overload of PrintTo() for T.
825b89a7cc2SEnji Cooper template <typename T>
826b89a7cc2SEnji Cooper class UniversalPrinter {
827b89a7cc2SEnji Cooper  public:
828b89a7cc2SEnji Cooper   // MSVC warns about adding const to a function type, so we want to
829b89a7cc2SEnji Cooper   // disable the warning.
830b89a7cc2SEnji Cooper   GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
831b89a7cc2SEnji Cooper 
832b89a7cc2SEnji Cooper   // Note: we deliberately don't call this PrintTo(), as that name
833b89a7cc2SEnji Cooper   // conflicts with ::testing::internal::PrintTo in the body of the
834b89a7cc2SEnji Cooper   // function.
835b89a7cc2SEnji Cooper   static void Print(const T& value, ::std::ostream* os) {
836b89a7cc2SEnji Cooper     // By default, ::testing::internal::PrintTo() is used for printing
837b89a7cc2SEnji Cooper     // the value.
838b89a7cc2SEnji Cooper     //
839b89a7cc2SEnji Cooper     // Thanks to Koenig look-up, if T is a class and has its own
840b89a7cc2SEnji Cooper     // PrintTo() function defined in its namespace, that function will
841b89a7cc2SEnji Cooper     // be visible here.  Since it is more specific than the generic ones
842b89a7cc2SEnji Cooper     // in ::testing::internal, it will be picked by the compiler in the
843b89a7cc2SEnji Cooper     // following statement - exactly what we want.
844b89a7cc2SEnji Cooper     PrintTo(value, os);
845b89a7cc2SEnji Cooper   }
846b89a7cc2SEnji Cooper 
847b89a7cc2SEnji Cooper   GTEST_DISABLE_MSC_WARNINGS_POP_()
848b89a7cc2SEnji Cooper };
849b89a7cc2SEnji Cooper 
85028f6c2f2SEnji Cooper // Remove any const-qualifiers before passing a type to UniversalPrinter.
85128f6c2f2SEnji Cooper template <typename T>
85228f6c2f2SEnji Cooper class UniversalPrinter<const T> : public UniversalPrinter<T> {};
853b89a7cc2SEnji Cooper 
85428f6c2f2SEnji Cooper #if GTEST_INTERNAL_HAS_ANY
85528f6c2f2SEnji Cooper 
85628f6c2f2SEnji Cooper // Printer for std::any / absl::any
85728f6c2f2SEnji Cooper 
85828f6c2f2SEnji Cooper template <>
85928f6c2f2SEnji Cooper class UniversalPrinter<Any> {
86028f6c2f2SEnji Cooper  public:
86128f6c2f2SEnji Cooper   static void Print(const Any& value, ::std::ostream* os) {
86228f6c2f2SEnji Cooper     if (value.has_value()) {
86328f6c2f2SEnji Cooper       *os << "value of type " << GetTypeName(value);
86428f6c2f2SEnji Cooper     } else {
86528f6c2f2SEnji Cooper       *os << "no value";
86628f6c2f2SEnji Cooper     }
86728f6c2f2SEnji Cooper   }
86828f6c2f2SEnji Cooper 
86928f6c2f2SEnji Cooper  private:
87028f6c2f2SEnji Cooper   static std::string GetTypeName(const Any& value) {
87128f6c2f2SEnji Cooper #if GTEST_HAS_RTTI
87228f6c2f2SEnji Cooper     return internal::GetTypeName(value.type());
87328f6c2f2SEnji Cooper #else
87428f6c2f2SEnji Cooper     static_cast<void>(value);  // possibly unused
87528f6c2f2SEnji Cooper     return "<unknown_type>";
87628f6c2f2SEnji Cooper #endif  // GTEST_HAS_RTTI
87728f6c2f2SEnji Cooper   }
87828f6c2f2SEnji Cooper };
87928f6c2f2SEnji Cooper 
88028f6c2f2SEnji Cooper #endif  // GTEST_INTERNAL_HAS_ANY
88128f6c2f2SEnji Cooper 
88228f6c2f2SEnji Cooper #if GTEST_INTERNAL_HAS_OPTIONAL
88328f6c2f2SEnji Cooper 
88428f6c2f2SEnji Cooper // Printer for std::optional / absl::optional
885b89a7cc2SEnji Cooper 
886b89a7cc2SEnji Cooper template <typename T>
88728f6c2f2SEnji Cooper class UniversalPrinter<Optional<T>> {
888b89a7cc2SEnji Cooper  public:
88928f6c2f2SEnji Cooper   static void Print(const Optional<T>& value, ::std::ostream* os) {
890b89a7cc2SEnji Cooper     *os << '(';
891b89a7cc2SEnji Cooper     if (!value) {
892b89a7cc2SEnji Cooper       *os << "nullopt";
893b89a7cc2SEnji Cooper     } else {
894b89a7cc2SEnji Cooper       UniversalPrint(*value, os);
895b89a7cc2SEnji Cooper     }
896b89a7cc2SEnji Cooper     *os << ')';
897b89a7cc2SEnji Cooper   }
898b89a7cc2SEnji Cooper };
899b89a7cc2SEnji Cooper 
90028f6c2f2SEnji Cooper template <>
90128f6c2f2SEnji Cooper class UniversalPrinter<decltype(Nullopt())> {
90228f6c2f2SEnji Cooper  public:
90328f6c2f2SEnji Cooper   static void Print(decltype(Nullopt()), ::std::ostream* os) {
90428f6c2f2SEnji Cooper     *os << "(nullopt)";
90528f6c2f2SEnji Cooper   }
90628f6c2f2SEnji Cooper };
90728f6c2f2SEnji Cooper 
90828f6c2f2SEnji Cooper #endif  // GTEST_INTERNAL_HAS_OPTIONAL
90928f6c2f2SEnji Cooper 
91028f6c2f2SEnji Cooper #if GTEST_INTERNAL_HAS_VARIANT
91128f6c2f2SEnji Cooper 
91228f6c2f2SEnji Cooper // Printer for std::variant / absl::variant
913b89a7cc2SEnji Cooper 
914b89a7cc2SEnji Cooper template <typename... T>
91528f6c2f2SEnji Cooper class UniversalPrinter<Variant<T...>> {
916b89a7cc2SEnji Cooper  public:
91728f6c2f2SEnji Cooper   static void Print(const Variant<T...>& value, ::std::ostream* os) {
918b89a7cc2SEnji Cooper     *os << '(';
91928f6c2f2SEnji Cooper #ifdef GTEST_HAS_ABSL
92028f6c2f2SEnji Cooper     absl::visit(Visitor{os, value.index()}, value);
92128f6c2f2SEnji Cooper #else
92228f6c2f2SEnji Cooper     std::visit(Visitor{os, value.index()}, value);
92328f6c2f2SEnji Cooper #endif  // GTEST_HAS_ABSL
924b89a7cc2SEnji Cooper     *os << ')';
925b89a7cc2SEnji Cooper   }
926b89a7cc2SEnji Cooper 
927b89a7cc2SEnji Cooper  private:
928b89a7cc2SEnji Cooper   struct Visitor {
929b89a7cc2SEnji Cooper     template <typename U>
930b89a7cc2SEnji Cooper     void operator()(const U& u) const {
93128f6c2f2SEnji Cooper       *os << "'" << GetTypeName<U>() << "(index = " << index
93228f6c2f2SEnji Cooper           << ")' with value ";
933b89a7cc2SEnji Cooper       UniversalPrint(u, os);
934b89a7cc2SEnji Cooper     }
935b89a7cc2SEnji Cooper     ::std::ostream* os;
93628f6c2f2SEnji Cooper     std::size_t index;
937b89a7cc2SEnji Cooper   };
938b89a7cc2SEnji Cooper };
939b89a7cc2SEnji Cooper 
94028f6c2f2SEnji Cooper #endif  // GTEST_INTERNAL_HAS_VARIANT
941b89a7cc2SEnji Cooper 
942b89a7cc2SEnji Cooper // UniversalPrintArray(begin, len, os) prints an array of 'len'
943b89a7cc2SEnji Cooper // elements, starting at address 'begin'.
944b89a7cc2SEnji Cooper template <typename T>
945b89a7cc2SEnji Cooper void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
946b89a7cc2SEnji Cooper   if (len == 0) {
947b89a7cc2SEnji Cooper     *os << "{}";
948b89a7cc2SEnji Cooper   } else {
949b89a7cc2SEnji Cooper     *os << "{ ";
950b89a7cc2SEnji Cooper     const size_t kThreshold = 18;
951b89a7cc2SEnji Cooper     const size_t kChunkSize = 8;
952b89a7cc2SEnji Cooper     // If the array has more than kThreshold elements, we'll have to
953b89a7cc2SEnji Cooper     // omit some details by printing only the first and the last
954b89a7cc2SEnji Cooper     // kChunkSize elements.
955b89a7cc2SEnji Cooper     if (len <= kThreshold) {
956b89a7cc2SEnji Cooper       PrintRawArrayTo(begin, len, os);
957b89a7cc2SEnji Cooper     } else {
958b89a7cc2SEnji Cooper       PrintRawArrayTo(begin, kChunkSize, os);
959b89a7cc2SEnji Cooper       *os << ", ..., ";
960b89a7cc2SEnji Cooper       PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
961b89a7cc2SEnji Cooper     }
962b89a7cc2SEnji Cooper     *os << " }";
963b89a7cc2SEnji Cooper   }
964b89a7cc2SEnji Cooper }
965b89a7cc2SEnji Cooper // This overload prints a (const) char array compactly.
96628f6c2f2SEnji Cooper GTEST_API_ void UniversalPrintArray(const char* begin, size_t len,
96728f6c2f2SEnji Cooper                                     ::std::ostream* os);
96828f6c2f2SEnji Cooper 
96928f6c2f2SEnji Cooper #ifdef __cpp_lib_char8_t
97028f6c2f2SEnji Cooper // This overload prints a (const) char8_t array compactly.
97128f6c2f2SEnji Cooper GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,
97228f6c2f2SEnji Cooper                                     ::std::ostream* os);
97328f6c2f2SEnji Cooper #endif
97428f6c2f2SEnji Cooper 
97528f6c2f2SEnji Cooper // This overload prints a (const) char16_t array compactly.
97628f6c2f2SEnji Cooper GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,
97728f6c2f2SEnji Cooper                                     ::std::ostream* os);
97828f6c2f2SEnji Cooper 
97928f6c2f2SEnji Cooper // This overload prints a (const) char32_t array compactly.
98028f6c2f2SEnji Cooper GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,
98128f6c2f2SEnji Cooper                                     ::std::ostream* os);
982b89a7cc2SEnji Cooper 
983b89a7cc2SEnji Cooper // This overload prints a (const) wchar_t array compactly.
98428f6c2f2SEnji Cooper GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
98528f6c2f2SEnji Cooper                                     ::std::ostream* os);
986b89a7cc2SEnji Cooper 
987b89a7cc2SEnji Cooper // Implements printing an array type T[N].
988b89a7cc2SEnji Cooper template <typename T, size_t N>
989b89a7cc2SEnji Cooper class UniversalPrinter<T[N]> {
990b89a7cc2SEnji Cooper  public:
991b89a7cc2SEnji Cooper   // Prints the given array, omitting some elements when there are too
992b89a7cc2SEnji Cooper   // many.
993b89a7cc2SEnji Cooper   static void Print(const T (&a)[N], ::std::ostream* os) {
994b89a7cc2SEnji Cooper     UniversalPrintArray(a, N, os);
995b89a7cc2SEnji Cooper   }
996b89a7cc2SEnji Cooper };
997b89a7cc2SEnji Cooper 
998b89a7cc2SEnji Cooper // Implements printing a reference type T&.
999b89a7cc2SEnji Cooper template <typename T>
1000b89a7cc2SEnji Cooper class UniversalPrinter<T&> {
1001b89a7cc2SEnji Cooper  public:
1002b89a7cc2SEnji Cooper   // MSVC warns about adding const to a function type, so we want to
1003b89a7cc2SEnji Cooper   // disable the warning.
1004b89a7cc2SEnji Cooper   GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
1005b89a7cc2SEnji Cooper 
1006b89a7cc2SEnji Cooper   static void Print(const T& value, ::std::ostream* os) {
1007b89a7cc2SEnji Cooper     // Prints the address of the value.  We use reinterpret_cast here
1008b89a7cc2SEnji Cooper     // as static_cast doesn't compile when T is a function type.
1009b89a7cc2SEnji Cooper     *os << "@" << reinterpret_cast<const void*>(&value) << " ";
1010b89a7cc2SEnji Cooper 
1011b89a7cc2SEnji Cooper     // Then prints the value itself.
1012b89a7cc2SEnji Cooper     UniversalPrint(value, os);
1013b89a7cc2SEnji Cooper   }
1014b89a7cc2SEnji Cooper 
1015b89a7cc2SEnji Cooper   GTEST_DISABLE_MSC_WARNINGS_POP_()
1016b89a7cc2SEnji Cooper };
1017b89a7cc2SEnji Cooper 
1018b89a7cc2SEnji Cooper // Prints a value tersely: for a reference type, the referenced value
1019b89a7cc2SEnji Cooper // (but not the address) is printed; for a (const) char pointer, the
1020b89a7cc2SEnji Cooper // NUL-terminated string (but not the pointer) is printed.
1021b89a7cc2SEnji Cooper 
1022b89a7cc2SEnji Cooper template <typename T>
1023b89a7cc2SEnji Cooper class UniversalTersePrinter {
1024b89a7cc2SEnji Cooper  public:
1025b89a7cc2SEnji Cooper   static void Print(const T& value, ::std::ostream* os) {
1026b89a7cc2SEnji Cooper     UniversalPrint(value, os);
1027b89a7cc2SEnji Cooper   }
1028b89a7cc2SEnji Cooper };
1029b89a7cc2SEnji Cooper template <typename T>
1030b89a7cc2SEnji Cooper class UniversalTersePrinter<T&> {
1031b89a7cc2SEnji Cooper  public:
1032b89a7cc2SEnji Cooper   static void Print(const T& value, ::std::ostream* os) {
1033b89a7cc2SEnji Cooper     UniversalPrint(value, os);
1034b89a7cc2SEnji Cooper   }
1035b89a7cc2SEnji Cooper };
103628f6c2f2SEnji Cooper template <typename T>
103728f6c2f2SEnji Cooper class UniversalTersePrinter<std::reference_wrapper<T>> {
103828f6c2f2SEnji Cooper  public:
103928f6c2f2SEnji Cooper   static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
104028f6c2f2SEnji Cooper     UniversalTersePrinter<T>::Print(value.get(), os);
104128f6c2f2SEnji Cooper   }
104228f6c2f2SEnji Cooper };
1043b89a7cc2SEnji Cooper template <typename T, size_t N>
1044b89a7cc2SEnji Cooper class UniversalTersePrinter<T[N]> {
1045b89a7cc2SEnji Cooper  public:
1046b89a7cc2SEnji Cooper   static void Print(const T (&value)[N], ::std::ostream* os) {
1047b89a7cc2SEnji Cooper     UniversalPrinter<T[N]>::Print(value, os);
1048b89a7cc2SEnji Cooper   }
1049b89a7cc2SEnji Cooper };
1050b89a7cc2SEnji Cooper template <>
1051b89a7cc2SEnji Cooper class UniversalTersePrinter<const char*> {
1052b89a7cc2SEnji Cooper  public:
1053b89a7cc2SEnji Cooper   static void Print(const char* str, ::std::ostream* os) {
105428f6c2f2SEnji Cooper     if (str == nullptr) {
1055b89a7cc2SEnji Cooper       *os << "NULL";
1056b89a7cc2SEnji Cooper     } else {
1057b89a7cc2SEnji Cooper       UniversalPrint(std::string(str), os);
1058b89a7cc2SEnji Cooper     }
1059b89a7cc2SEnji Cooper   }
1060b89a7cc2SEnji Cooper };
1061b89a7cc2SEnji Cooper template <>
106228f6c2f2SEnji Cooper class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
106328f6c2f2SEnji Cooper };
106428f6c2f2SEnji Cooper 
106528f6c2f2SEnji Cooper #ifdef __cpp_lib_char8_t
106628f6c2f2SEnji Cooper template <>
106728f6c2f2SEnji Cooper class UniversalTersePrinter<const char8_t*> {
1068b89a7cc2SEnji Cooper  public:
106928f6c2f2SEnji Cooper   static void Print(const char8_t* str, ::std::ostream* os) {
107028f6c2f2SEnji Cooper     if (str == nullptr) {
107128f6c2f2SEnji Cooper       *os << "NULL";
107228f6c2f2SEnji Cooper     } else {
107328f6c2f2SEnji Cooper       UniversalPrint(::std::u8string(str), os);
107428f6c2f2SEnji Cooper     }
1075b89a7cc2SEnji Cooper   }
1076b89a7cc2SEnji Cooper };
107728f6c2f2SEnji Cooper template <>
107828f6c2f2SEnji Cooper class UniversalTersePrinter<char8_t*>
107928f6c2f2SEnji Cooper     : public UniversalTersePrinter<const char8_t*> {};
108028f6c2f2SEnji Cooper #endif
108128f6c2f2SEnji Cooper 
108228f6c2f2SEnji Cooper template <>
108328f6c2f2SEnji Cooper class UniversalTersePrinter<const char16_t*> {
108428f6c2f2SEnji Cooper  public:
108528f6c2f2SEnji Cooper   static void Print(const char16_t* str, ::std::ostream* os) {
108628f6c2f2SEnji Cooper     if (str == nullptr) {
108728f6c2f2SEnji Cooper       *os << "NULL";
108828f6c2f2SEnji Cooper     } else {
108928f6c2f2SEnji Cooper       UniversalPrint(::std::u16string(str), os);
109028f6c2f2SEnji Cooper     }
109128f6c2f2SEnji Cooper   }
109228f6c2f2SEnji Cooper };
109328f6c2f2SEnji Cooper template <>
109428f6c2f2SEnji Cooper class UniversalTersePrinter<char16_t*>
109528f6c2f2SEnji Cooper     : public UniversalTersePrinter<const char16_t*> {};
109628f6c2f2SEnji Cooper 
109728f6c2f2SEnji Cooper template <>
109828f6c2f2SEnji Cooper class UniversalTersePrinter<const char32_t*> {
109928f6c2f2SEnji Cooper  public:
110028f6c2f2SEnji Cooper   static void Print(const char32_t* str, ::std::ostream* os) {
110128f6c2f2SEnji Cooper     if (str == nullptr) {
110228f6c2f2SEnji Cooper       *os << "NULL";
110328f6c2f2SEnji Cooper     } else {
110428f6c2f2SEnji Cooper       UniversalPrint(::std::u32string(str), os);
110528f6c2f2SEnji Cooper     }
110628f6c2f2SEnji Cooper   }
110728f6c2f2SEnji Cooper };
110828f6c2f2SEnji Cooper template <>
110928f6c2f2SEnji Cooper class UniversalTersePrinter<char32_t*>
111028f6c2f2SEnji Cooper     : public UniversalTersePrinter<const char32_t*> {};
1111b89a7cc2SEnji Cooper 
1112b89a7cc2SEnji Cooper #if GTEST_HAS_STD_WSTRING
1113b89a7cc2SEnji Cooper template <>
1114b89a7cc2SEnji Cooper class UniversalTersePrinter<const wchar_t*> {
1115b89a7cc2SEnji Cooper  public:
1116b89a7cc2SEnji Cooper   static void Print(const wchar_t* str, ::std::ostream* os) {
111728f6c2f2SEnji Cooper     if (str == nullptr) {
1118b89a7cc2SEnji Cooper       *os << "NULL";
1119b89a7cc2SEnji Cooper     } else {
1120b89a7cc2SEnji Cooper       UniversalPrint(::std::wstring(str), os);
1121b89a7cc2SEnji Cooper     }
1122b89a7cc2SEnji Cooper   }
1123b89a7cc2SEnji Cooper };
1124b89a7cc2SEnji Cooper #endif
1125b89a7cc2SEnji Cooper 
1126b89a7cc2SEnji Cooper template <>
1127b89a7cc2SEnji Cooper class UniversalTersePrinter<wchar_t*> {
1128b89a7cc2SEnji Cooper  public:
1129b89a7cc2SEnji Cooper   static void Print(wchar_t* str, ::std::ostream* os) {
1130b89a7cc2SEnji Cooper     UniversalTersePrinter<const wchar_t*>::Print(str, os);
1131b89a7cc2SEnji Cooper   }
1132b89a7cc2SEnji Cooper };
1133b89a7cc2SEnji Cooper 
1134b89a7cc2SEnji Cooper template <typename T>
1135b89a7cc2SEnji Cooper void UniversalTersePrint(const T& value, ::std::ostream* os) {
1136b89a7cc2SEnji Cooper   UniversalTersePrinter<T>::Print(value, os);
1137b89a7cc2SEnji Cooper }
1138b89a7cc2SEnji Cooper 
1139b89a7cc2SEnji Cooper // Prints a value using the type inferred by the compiler.  The
1140b89a7cc2SEnji Cooper // difference between this and UniversalTersePrint() is that for a
1141b89a7cc2SEnji Cooper // (const) char pointer, this prints both the pointer and the
1142b89a7cc2SEnji Cooper // NUL-terminated string.
1143b89a7cc2SEnji Cooper template <typename T>
1144b89a7cc2SEnji Cooper void UniversalPrint(const T& value, ::std::ostream* os) {
1145b89a7cc2SEnji Cooper   // A workarond for the bug in VC++ 7.1 that prevents us from instantiating
1146b89a7cc2SEnji Cooper   // UniversalPrinter with T directly.
1147b89a7cc2SEnji Cooper   typedef T T1;
1148b89a7cc2SEnji Cooper   UniversalPrinter<T1>::Print(value, os);
1149b89a7cc2SEnji Cooper }
1150b89a7cc2SEnji Cooper 
1151b89a7cc2SEnji Cooper typedef ::std::vector<::std::string> Strings;
1152b89a7cc2SEnji Cooper 
1153b89a7cc2SEnji Cooper // Tersely prints the first N fields of a tuple to a string vector,
1154b89a7cc2SEnji Cooper // one element for each field.
1155b89a7cc2SEnji Cooper template <typename Tuple>
115628f6c2f2SEnji Cooper void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
115728f6c2f2SEnji Cooper                                Strings*) {}
115828f6c2f2SEnji Cooper template <typename Tuple, size_t I>
115928f6c2f2SEnji Cooper void TersePrintPrefixToStrings(const Tuple& t,
116028f6c2f2SEnji Cooper                                std::integral_constant<size_t, I>,
116128f6c2f2SEnji Cooper                                Strings* strings) {
116228f6c2f2SEnji Cooper   TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),
116328f6c2f2SEnji Cooper                             strings);
1164b89a7cc2SEnji Cooper   ::std::stringstream ss;
116528f6c2f2SEnji Cooper   UniversalTersePrint(std::get<I - 1>(t), &ss);
1166b89a7cc2SEnji Cooper   strings->push_back(ss.str());
1167b89a7cc2SEnji Cooper }
1168b89a7cc2SEnji Cooper 
1169b89a7cc2SEnji Cooper // Prints the fields of a tuple tersely to a string vector, one
1170b89a7cc2SEnji Cooper // element for each field.  See the comment before
1171b89a7cc2SEnji Cooper // UniversalTersePrint() for how we define "tersely".
1172b89a7cc2SEnji Cooper template <typename Tuple>
1173b89a7cc2SEnji Cooper Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
1174b89a7cc2SEnji Cooper   Strings result;
117528f6c2f2SEnji Cooper   TersePrintPrefixToStrings(
117628f6c2f2SEnji Cooper       value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
117728f6c2f2SEnji Cooper       &result);
1178b89a7cc2SEnji Cooper   return result;
1179b89a7cc2SEnji Cooper }
1180b89a7cc2SEnji Cooper 
1181b89a7cc2SEnji Cooper }  // namespace internal
1182b89a7cc2SEnji Cooper 
1183b89a7cc2SEnji Cooper template <typename T>
1184b89a7cc2SEnji Cooper ::std::string PrintToString(const T& value) {
1185b89a7cc2SEnji Cooper   ::std::stringstream ss;
1186b89a7cc2SEnji Cooper   internal::UniversalTersePrinter<T>::Print(value, &ss);
1187b89a7cc2SEnji Cooper   return ss.str();
1188b89a7cc2SEnji Cooper }
1189b89a7cc2SEnji Cooper 
1190b89a7cc2SEnji Cooper }  // namespace testing
1191b89a7cc2SEnji Cooper 
1192b89a7cc2SEnji Cooper // Include any custom printer added by the local installation.
1193b89a7cc2SEnji Cooper // We must include this header at the end to make sure it can use the
1194b89a7cc2SEnji Cooper // declarations from this file.
1195b89a7cc2SEnji Cooper #include "gtest/internal/custom/gtest-printers.h"
1196b89a7cc2SEnji Cooper 
119728f6c2f2SEnji Cooper #endif  // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
1198