Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/googletest/include/gtest/gtest-printers.h
4806 views
1
// Copyright 2007, Google Inc.
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are
6
// met:
7
//
8
// * Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
// * Redistributions in binary form must reproduce the above
11
// copyright notice, this list of conditions and the following disclaimer
12
// in the documentation and/or other materials provided with the
13
// distribution.
14
// * Neither the name of Google Inc. nor the names of its
15
// contributors may be used to endorse or promote products derived from
16
// this software without specific prior written permission.
17
//
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
// Google Test - The Google C++ Testing and Mocking Framework
31
//
32
// This file implements a universal value printer that can print a
33
// value of any type T:
34
//
35
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
36
//
37
// A user can teach this function how to print a class type T by
38
// defining either operator<<() or PrintTo() in the namespace that
39
// defines T. More specifically, the FIRST defined function in the
40
// following list will be used (assuming T is defined in namespace
41
// foo):
42
//
43
// 1. foo::PrintTo(const T&, ostream*)
44
// 2. operator<<(ostream&, const T&) defined in either foo or the
45
// global namespace.
46
// * Prefer AbslStringify(..) to operator<<(..), per https://abseil.io/tips/215.
47
// * Define foo::PrintTo(..) if the type already has AbslStringify(..), but an
48
// alternative presentation in test results is of interest.
49
//
50
// However if T is an STL-style container then it is printed element-wise
51
// unless foo::PrintTo(const T&, ostream*) is defined. Note that
52
// operator<<() is ignored for container types.
53
//
54
// If none of the above is defined, it will print the debug string of
55
// the value if it is a protocol buffer, or print the raw bytes in the
56
// value otherwise.
57
//
58
// To aid debugging: when T is a reference type, the address of the
59
// value is also printed; when T is a (const) char pointer, both the
60
// pointer value and the NUL-terminated string it points to are
61
// printed.
62
//
63
// We also provide some convenient wrappers:
64
//
65
// // Prints a value to a string. For a (const or not) char
66
// // pointer, the NUL-terminated string (but not the pointer) is
67
// // printed.
68
// std::string ::testing::PrintToString(const T& value);
69
//
70
// // Prints a value tersely: for a reference type, the referenced
71
// // value (but not the address) is printed; for a (const or not) char
72
// // pointer, the NUL-terminated string (but not the pointer) is
73
// // printed.
74
// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
75
//
76
// // Prints value using the type inferred by the compiler. The difference
77
// // from UniversalTersePrint() is that this function prints both the
78
// // pointer and the NUL-terminated string for a (const or not) char pointer.
79
// void ::testing::internal::UniversalPrint(const T& value, ostream*);
80
//
81
// // Prints the fields of a tuple tersely to a string vector, one
82
// // element for each field. Tuple support must be enabled in
83
// // gtest-port.h.
84
// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
85
// const Tuple& value);
86
//
87
// Known limitation:
88
//
89
// The print primitives print the elements of an STL-style container
90
// using the compiler-inferred type of *iter where iter is a
91
// const_iterator of the container. When const_iterator is an input
92
// iterator but not a forward iterator, this inferred type may not
93
// match value_type, and the print output may be incorrect. In
94
// practice, this is rarely a problem as for most containers
95
// const_iterator is a forward iterator. We'll fix this if there's an
96
// actual need for it. Note that this fix cannot rely on value_type
97
// being defined as many user-defined container types don't have
98
// value_type.
99
100
// IWYU pragma: private, include "gtest/gtest.h"
101
// IWYU pragma: friend gtest/.*
102
// IWYU pragma: friend gmock/.*
103
104
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
105
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
106
107
#include <functional>
108
#include <memory>
109
#include <ostream> // NOLINT
110
#include <sstream>
111
#include <string>
112
#include <tuple>
113
#include <type_traits>
114
#include <typeinfo>
115
#include <utility>
116
#include <vector>
117
118
#ifdef GTEST_HAS_ABSL
119
#include "absl/strings/has_absl_stringify.h"
120
#include "absl/strings/str_cat.h"
121
#endif // GTEST_HAS_ABSL
122
#include "gtest/internal/gtest-internal.h"
123
#include "gtest/internal/gtest-port.h"
124
125
#if GTEST_INTERNAL_HAS_STD_SPAN
126
#include <span> // NOLINT
127
#endif // GTEST_INTERNAL_HAS_STD_SPAN
128
129
#if GTEST_INTERNAL_HAS_COMPARE_LIB
130
#include <compare> // NOLINT
131
#endif // GTEST_INTERNAL_HAS_COMPARE_LIB
132
133
namespace testing {
134
135
// Definitions in the internal* namespaces are subject to change without notice.
136
// DO NOT USE THEM IN USER CODE!
137
namespace internal {
138
139
template <typename T>
140
void UniversalPrint(const T& value, ::std::ostream* os);
141
142
template <typename T>
143
struct IsStdSpan {
144
static constexpr bool value = false;
145
};
146
147
#if GTEST_INTERNAL_HAS_STD_SPAN
148
template <typename E>
149
struct IsStdSpan<std::span<E>> {
150
static constexpr bool value = true;
151
};
152
#endif // GTEST_INTERNAL_HAS_STD_SPAN
153
154
// Used to print an STL-style container when the user doesn't define
155
// a PrintTo() for it.
156
//
157
// NOTE: Since std::span does not have const_iterator until C++23, it would
158
// fail IsContainerTest before C++23. However, IsContainerTest only uses
159
// the presence of const_iterator to avoid treating iterators as containers
160
// because of iterator::iterator. Which means std::span satisfies the *intended*
161
// condition of IsContainerTest.
162
struct ContainerPrinter {
163
template <typename T,
164
typename = typename std::enable_if<
165
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
166
!IsRecursiveContainer<T>::value) ||
167
IsStdSpan<T>::value>::type>
168
static void PrintValue(const T& container, std::ostream* os) {
169
const size_t kMaxCount = 32; // The maximum number of elements to print.
170
*os << '{';
171
size_t count = 0;
172
for (auto&& elem : container) {
173
if (count > 0) {
174
*os << ',';
175
if (count == kMaxCount) { // Enough has been printed.
176
*os << " ...";
177
break;
178
}
179
}
180
*os << ' ';
181
// We cannot call PrintTo(elem, os) here as PrintTo() doesn't
182
// handle `elem` being a native array.
183
internal::UniversalPrint(elem, os);
184
++count;
185
}
186
187
if (count > 0) {
188
*os << ' ';
189
}
190
*os << '}';
191
}
192
};
193
194
// Used to print a pointer that is neither a char pointer nor a member
195
// pointer, when the user doesn't define PrintTo() for it. (A member
196
// variable pointer or member function pointer doesn't really point to
197
// a location in the address space. Their representation is
198
// implementation-defined. Therefore they will be printed as raw
199
// bytes.)
200
struct FunctionPointerPrinter {
201
template <typename T, typename = typename std::enable_if<
202
std::is_function<T>::value>::type>
203
static void PrintValue(T* p, ::std::ostream* os) {
204
if (p == nullptr) {
205
*os << "NULL";
206
} else {
207
// T is a function type, so '*os << p' doesn't do what we want
208
// (it just prints p as bool). We want to print p as a const
209
// void*.
210
*os << reinterpret_cast<const void*>(p);
211
}
212
}
213
};
214
215
struct PointerPrinter {
216
template <typename T>
217
static void PrintValue(T* p, ::std::ostream* os) {
218
if (p == nullptr) {
219
*os << "NULL";
220
} else {
221
// T is not a function type. We just call << to print p,
222
// relying on ADL to pick up user-defined << for their pointer
223
// types, if any.
224
*os << p;
225
}
226
}
227
};
228
229
namespace internal_stream_operator_without_lexical_name_lookup {
230
231
// The presence of an operator<< here will terminate lexical scope lookup
232
// straight away (even though it cannot be a match because of its argument
233
// types). Thus, the two operator<< calls in StreamPrinter will find only ADL
234
// candidates.
235
struct LookupBlocker {};
236
void operator<<(LookupBlocker, LookupBlocker);
237
238
struct StreamPrinter {
239
template <typename T,
240
// Don't accept member pointers here. We'd print them via implicit
241
// conversion to bool, which isn't useful.
242
typename = typename std::enable_if<
243
!std::is_member_pointer<T>::value>::type>
244
// Only accept types for which we can find a streaming operator via
245
// ADL (possibly involving implicit conversions).
246
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
247
// lookup properly when we do it in the template parameter list.)
248
static auto PrintValue(const T& value,
249
::std::ostream* os) -> decltype((void)(*os << value)) {
250
// Call streaming operator found by ADL, possibly with implicit conversions
251
// of the arguments.
252
*os << value;
253
}
254
};
255
256
} // namespace internal_stream_operator_without_lexical_name_lookup
257
258
struct ProtobufPrinter {
259
// We print a protobuf using its ShortDebugString() when the string
260
// doesn't exceed this many characters; otherwise we print it using
261
// DebugString() for better readability.
262
static const size_t kProtobufOneLinerMaxLength = 50;
263
264
template <typename T,
265
typename = typename std::enable_if<
266
internal::HasDebugStringAndShortDebugString<T>::value>::type>
267
static void PrintValue(const T& value, ::std::ostream* os) {
268
std::string pretty_str = value.ShortDebugString();
269
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
270
pretty_str = "\n" + value.DebugString();
271
}
272
*os << ("<" + pretty_str + ">");
273
}
274
};
275
276
struct ConvertibleToIntegerPrinter {
277
// Since T has no << operator or PrintTo() but can be implicitly
278
// converted to BiggestInt, we print it as a BiggestInt.
279
//
280
// Most likely T is an enum type (either named or unnamed), in which
281
// case printing it as an integer is the desired behavior. In case
282
// T is not an enum, printing it as an integer is the best we can do
283
// given that it has no user-defined printer.
284
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
285
*os << value;
286
}
287
};
288
289
struct ConvertibleToStringViewPrinter {
290
#if GTEST_INTERNAL_HAS_STRING_VIEW
291
static void PrintValue(internal::StringView value, ::std::ostream* os) {
292
internal::UniversalPrint(value, os);
293
}
294
#endif
295
};
296
297
#ifdef GTEST_HAS_ABSL
298
struct ConvertibleToAbslStringifyPrinter {
299
template <typename T,
300
typename = typename std::enable_if<
301
absl::HasAbslStringify<T>::value>::type> // NOLINT
302
static void PrintValue(const T& value, ::std::ostream* os) {
303
*os << absl::StrCat(value);
304
}
305
};
306
#endif // GTEST_HAS_ABSL
307
308
// Prints the given number of bytes in the given object to the given
309
// ostream.
310
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
311
size_t count, ::std::ostream* os);
312
struct RawBytesPrinter {
313
// SFINAE on `sizeof` to make sure we have a complete type.
314
template <typename T, size_t = sizeof(T)>
315
static void PrintValue(const T& value, ::std::ostream* os) {
316
PrintBytesInObjectTo(
317
static_cast<const unsigned char*>(
318
// Load bearing cast to void* to support iOS
319
reinterpret_cast<const void*>(std::addressof(value))),
320
sizeof(value), os);
321
}
322
};
323
324
struct FallbackPrinter {
325
template <typename T>
326
static void PrintValue(const T&, ::std::ostream* os) {
327
*os << "(incomplete type)";
328
}
329
};
330
331
// Try every printer in order and return the first one that works.
332
template <typename T, typename E, typename Printer, typename... Printers>
333
struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};
334
335
template <typename T, typename Printer, typename... Printers>
336
struct FindFirstPrinter<
337
T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),
338
Printer, Printers...> {
339
using type = Printer;
340
};
341
342
// Select the best printer in the following order:
343
// - Print containers (they have begin/end/etc).
344
// - Print function pointers.
345
// - Print object pointers.
346
// - Print protocol buffers.
347
// - Use the stream operator, if available.
348
// - Print types convertible to BiggestInt.
349
// - Print types convertible to StringView, if available.
350
// - Fallback to printing the raw bytes of the object.
351
template <typename T>
352
void PrintWithFallback(const T& value, ::std::ostream* os) {
353
using Printer = typename FindFirstPrinter<
354
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
355
ProtobufPrinter,
356
#ifdef GTEST_HAS_ABSL
357
ConvertibleToAbslStringifyPrinter,
358
#endif // GTEST_HAS_ABSL
359
internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
360
ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,
361
RawBytesPrinter, FallbackPrinter>::type;
362
Printer::PrintValue(value, os);
363
}
364
365
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
366
// value of type ToPrint that is an operand of a comparison assertion
367
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
368
// the comparison, and is used to help determine the best way to
369
// format the value. In particular, when the value is a C string
370
// (char pointer) and the other operand is an STL string object, we
371
// want to format the C string as a string, since we know it is
372
// compared by value with the string object. If the value is a char
373
// pointer but the other operand is not an STL string object, we don't
374
// know whether the pointer is supposed to point to a NUL-terminated
375
// string, and thus want to print it as a pointer to be safe.
376
//
377
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
378
379
// The default case.
380
template <typename ToPrint, typename OtherOperand>
381
class FormatForComparison {
382
public:
383
static ::std::string Format(const ToPrint& value) {
384
return ::testing::PrintToString(value);
385
}
386
};
387
388
// Array.
389
template <typename ToPrint, size_t N, typename OtherOperand>
390
class FormatForComparison<ToPrint[N], OtherOperand> {
391
public:
392
static ::std::string Format(const ToPrint* value) {
393
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
394
}
395
};
396
397
// By default, print C string as pointers to be safe, as we don't know
398
// whether they actually point to a NUL-terminated string.
399
400
#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
401
template <typename OtherOperand> \
402
class FormatForComparison<CharType*, OtherOperand> { \
403
public: \
404
static ::std::string Format(CharType* value) { \
405
return ::testing::PrintToString(static_cast<const void*>(value)); \
406
} \
407
}
408
409
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
410
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
411
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
412
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
413
#ifdef __cpp_lib_char8_t
414
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
415
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
416
#endif
417
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t);
418
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t);
419
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t);
420
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);
421
422
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
423
424
// If a C string is compared with an STL string object, we know it's meant
425
// to point to a NUL-terminated string, and thus can print it as a string.
426
427
#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
428
template <> \
429
class FormatForComparison<CharType*, OtherStringType> { \
430
public: \
431
static ::std::string Format(CharType* value) { \
432
return ::testing::PrintToString(value); \
433
} \
434
}
435
436
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
437
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
438
#ifdef __cpp_lib_char8_t
439
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
440
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
441
#endif
442
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string);
443
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string);
444
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string);
445
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string);
446
447
#if GTEST_HAS_STD_WSTRING
448
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
449
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
450
#endif
451
452
#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
453
454
// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
455
// operand to be used in a failure message. The type (but not value)
456
// of the other operand may affect the format. This allows us to
457
// print a char* as a raw pointer when it is compared against another
458
// char* or void*, and print it as a C string when it is compared
459
// against an std::string object, for example.
460
//
461
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
462
template <typename T1, typename T2>
463
std::string FormatForComparisonFailureMessage(const T1& value,
464
const T2& /* other_operand */) {
465
return FormatForComparison<T1, T2>::Format(value);
466
}
467
468
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
469
// value to the given ostream. The caller must ensure that
470
// 'ostream_ptr' is not NULL, or the behavior is undefined.
471
//
472
// We define UniversalPrinter as a class template (as opposed to a
473
// function template), as we need to partially specialize it for
474
// reference types, which cannot be done with function templates.
475
template <typename T>
476
class UniversalPrinter;
477
478
// Prints the given value using the << operator if it has one;
479
// otherwise prints the bytes in it. This is what
480
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
481
// or overloaded for type T.
482
//
483
// A user can override this behavior for a class type Foo by defining
484
// an overload of PrintTo() in the namespace where Foo is defined. We
485
// give the user this option as sometimes defining a << operator for
486
// Foo is not desirable (e.g. the coding style may prevent doing it,
487
// or there is already a << operator but it doesn't do what the user
488
// wants).
489
template <typename T>
490
void PrintTo(const T& value, ::std::ostream* os) {
491
internal::PrintWithFallback(value, os);
492
}
493
494
// The following list of PrintTo() overloads tells
495
// UniversalPrinter<T>::Print() how to print standard types (built-in
496
// types, strings, plain arrays, and pointers).
497
498
// Overloads for various char types.
499
GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
500
GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
501
inline void PrintTo(char c, ::std::ostream* os) {
502
// When printing a plain char, we always treat it as unsigned. This
503
// way, the output won't be affected by whether the compiler thinks
504
// char is signed or not.
505
PrintTo(static_cast<unsigned char>(c), os);
506
}
507
508
// Overloads for other simple built-in types.
509
inline void PrintTo(bool x, ::std::ostream* os) {
510
*os << (x ? "true" : "false");
511
}
512
513
// Overload for wchar_t type.
514
// Prints a wchar_t as a symbol if it is printable or as its internal
515
// code otherwise and also as its decimal code (except for L'\0').
516
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
517
// as signed integer when wchar_t is implemented by the compiler
518
// as a signed type and is printed as an unsigned integer when wchar_t
519
// is implemented as an unsigned type.
520
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
521
522
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
523
inline void PrintTo(char16_t c, ::std::ostream* os) {
524
PrintTo(ImplicitCast_<char32_t>(c), os);
525
}
526
#ifdef __cpp_lib_char8_t
527
inline void PrintTo(char8_t c, ::std::ostream* os) {
528
PrintTo(ImplicitCast_<char32_t>(c), os);
529
}
530
#endif
531
532
// gcc/clang __{u,}int128_t
533
#if defined(__SIZEOF_INT128__)
534
GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
535
GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
536
#endif // __SIZEOF_INT128__
537
538
// The default resolution used to print floating-point values uses only
539
// 6 digits, which can be confusing if a test compares two values whose
540
// difference lies in the 7th digit. So we'd like to print out numbers
541
// in full precision.
542
// However if the value is something simple like 1.1, full will print a
543
// long string like 1.100000001 due to floating-point numbers not using
544
// a base of 10. This routiune returns an appropriate resolution for a
545
// given floating-point number, that is, 6 if it will be accurate, or a
546
// max_digits10 value (full precision) if it won't, for values between
547
// 0.0001 and one million.
548
// It does this by computing what those digits would be (by multiplying
549
// by an appropriate power of 10), then dividing by that power again to
550
// see if gets the original value back.
551
// A similar algorithm applies for values larger than one million; note
552
// that for those values, we must divide to get a six-digit number, and
553
// then multiply to possibly get the original value again.
554
template <typename FloatType>
555
int AppropriateResolution(FloatType val) {
556
int full = std::numeric_limits<FloatType>::max_digits10;
557
if (val < 0) val = -val;
558
559
#ifdef __GNUC__
560
#pragma GCC diagnostic push
561
#pragma GCC diagnostic ignored "-Wfloat-equal"
562
#endif
563
if (val < 1000000) {
564
FloatType mulfor6 = 1e10;
565
// Without these static casts, the template instantiation for float would
566
// fail to compile when -Wdouble-promotion is enabled, as the arithmetic and
567
// comparison logic would promote floats to doubles.
568
if (val >= static_cast<FloatType>(100000.0)) { // 100,000 to 999,999
569
mulfor6 = 1.0;
570
} else if (val >= static_cast<FloatType>(10000.0)) {
571
mulfor6 = 1e1;
572
} else if (val >= static_cast<FloatType>(1000.0)) {
573
mulfor6 = 1e2;
574
} else if (val >= static_cast<FloatType>(100.0)) {
575
mulfor6 = 1e3;
576
} else if (val >= static_cast<FloatType>(10.0)) {
577
mulfor6 = 1e4;
578
} else if (val >= static_cast<FloatType>(1.0)) {
579
mulfor6 = 1e5;
580
} else if (val >= static_cast<FloatType>(0.1)) {
581
mulfor6 = 1e6;
582
} else if (val >= static_cast<FloatType>(0.01)) {
583
mulfor6 = 1e7;
584
} else if (val >= static_cast<FloatType>(0.001)) {
585
mulfor6 = 1e8;
586
} else if (val >= static_cast<FloatType>(0.0001)) {
587
mulfor6 = 1e9;
588
}
589
if (static_cast<FloatType>(static_cast<int32_t>(
590
val * mulfor6 + (static_cast<FloatType>(0.5)))) /
591
mulfor6 ==
592
val)
593
return 6;
594
} else if (val < static_cast<FloatType>(1e10)) {
595
FloatType divfor6 = static_cast<FloatType>(1.0);
596
if (val >= static_cast<FloatType>(1e9)) { // 1,000,000,000 to 9,999,999,999
597
divfor6 = 10000;
598
} else if (val >=
599
static_cast<FloatType>(1e8)) { // 100,000,000 to 999,999,999
600
divfor6 = 1000;
601
} else if (val >=
602
static_cast<FloatType>(1e7)) { // 10,000,000 to 99,999,999
603
divfor6 = 100;
604
} else if (val >= static_cast<FloatType>(1e6)) { // 1,000,000 to 9,999,999
605
divfor6 = 10;
606
}
607
if (static_cast<FloatType>(static_cast<int32_t>(
608
val / divfor6 + (static_cast<FloatType>(0.5)))) *
609
divfor6 ==
610
val)
611
return 6;
612
}
613
#ifdef __GNUC__
614
#pragma GCC diagnostic pop
615
#endif
616
return full;
617
}
618
619
inline void PrintTo(float f, ::std::ostream* os) {
620
auto old_precision = os->precision();
621
os->precision(AppropriateResolution(f));
622
*os << f;
623
os->precision(old_precision);
624
}
625
626
inline void PrintTo(double d, ::std::ostream* os) {
627
auto old_precision = os->precision();
628
os->precision(AppropriateResolution(d));
629
*os << d;
630
os->precision(old_precision);
631
}
632
633
// Overloads for C strings.
634
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
635
inline void PrintTo(char* s, ::std::ostream* os) {
636
PrintTo(ImplicitCast_<const char*>(s), os);
637
}
638
639
// signed/unsigned char is often used for representing binary data, so
640
// we print pointers to it as void* to be safe.
641
inline void PrintTo(const signed char* s, ::std::ostream* os) {
642
PrintTo(ImplicitCast_<const void*>(s), os);
643
}
644
inline void PrintTo(signed char* s, ::std::ostream* os) {
645
PrintTo(ImplicitCast_<const void*>(s), os);
646
}
647
inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
648
PrintTo(ImplicitCast_<const void*>(s), os);
649
}
650
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
651
PrintTo(ImplicitCast_<const void*>(s), os);
652
}
653
#ifdef __cpp_lib_char8_t
654
// Overloads for u8 strings.
655
GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);
656
inline void PrintTo(char8_t* s, ::std::ostream* os) {
657
PrintTo(ImplicitCast_<const char8_t*>(s), os);
658
}
659
#endif
660
// Overloads for u16 strings.
661
GTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os);
662
inline void PrintTo(char16_t* s, ::std::ostream* os) {
663
PrintTo(ImplicitCast_<const char16_t*>(s), os);
664
}
665
// Overloads for u32 strings.
666
GTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os);
667
inline void PrintTo(char32_t* s, ::std::ostream* os) {
668
PrintTo(ImplicitCast_<const char32_t*>(s), os);
669
}
670
671
// MSVC can be configured to define wchar_t as a typedef of unsigned
672
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
673
// type. When wchar_t is a typedef, defining an overload for const
674
// wchar_t* would cause unsigned short* be printed as a wide string,
675
// possibly causing invalid memory accesses.
676
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
677
// Overloads for wide C strings
678
GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
679
inline void PrintTo(wchar_t* s, ::std::ostream* os) {
680
PrintTo(ImplicitCast_<const wchar_t*>(s), os);
681
}
682
#endif
683
684
// Overload for C arrays. Multi-dimensional arrays are printed
685
// properly.
686
687
// Prints the given number of elements in an array, without printing
688
// the curly braces.
689
template <typename T>
690
void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
691
UniversalPrint(a[0], os);
692
for (size_t i = 1; i != count; i++) {
693
*os << ", ";
694
UniversalPrint(a[i], os);
695
}
696
}
697
698
// Overloads for ::std::string.
699
GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
700
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
701
PrintStringTo(s, os);
702
}
703
704
// Overloads for ::std::u8string
705
#ifdef __cpp_lib_char8_t
706
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
707
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
708
PrintU8StringTo(s, os);
709
}
710
#endif
711
712
// Overloads for ::std::u16string
713
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
714
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
715
PrintU16StringTo(s, os);
716
}
717
718
// Overloads for ::std::u32string
719
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
720
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
721
PrintU32StringTo(s, os);
722
}
723
724
// Overloads for ::std::wstring.
725
#if GTEST_HAS_STD_WSTRING
726
GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
727
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
728
PrintWideStringTo(s, os);
729
}
730
#endif // GTEST_HAS_STD_WSTRING
731
732
#if GTEST_INTERNAL_HAS_STRING_VIEW
733
// Overload for internal::StringView.
734
inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
735
PrintTo(::std::string(sp), os);
736
}
737
#endif // GTEST_INTERNAL_HAS_STRING_VIEW
738
739
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
740
741
#if GTEST_HAS_RTTI
742
inline void PrintTo(const std::type_info& info, std::ostream* os) {
743
*os << internal::GetTypeName(info);
744
}
745
#endif // GTEST_HAS_RTTI
746
747
template <typename T>
748
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
749
UniversalPrinter<T&>::Print(ref.get(), os);
750
}
751
752
inline const void* VoidifyPointer(const void* p) { return p; }
753
inline const void* VoidifyPointer(volatile const void* p) {
754
return const_cast<const void*>(p);
755
}
756
757
template <typename T, typename Ptr>
758
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {
759
if (ptr == nullptr) {
760
*os << "(nullptr)";
761
} else {
762
// We can't print the value. Just print the pointer..
763
*os << "(" << (VoidifyPointer)(ptr.get()) << ")";
764
}
765
}
766
template <typename T, typename Ptr,
767
typename = typename std::enable_if<!std::is_void<T>::value &&
768
!std::is_array<T>::value>::type>
769
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {
770
if (ptr == nullptr) {
771
*os << "(nullptr)";
772
} else {
773
*os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = ";
774
UniversalPrinter<T>::Print(*ptr, os);
775
*os << ")";
776
}
777
}
778
779
template <typename T, typename D>
780
void PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {
781
(PrintSmartPointer<T>)(ptr, os, 0);
782
}
783
784
template <typename T>
785
void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
786
(PrintSmartPointer<T>)(ptr, os, 0);
787
}
788
789
#if GTEST_INTERNAL_HAS_COMPARE_LIB
790
template <typename T>
791
void PrintOrderingHelper(T ordering, std::ostream* os) {
792
if (ordering == T::less) {
793
*os << "(less)";
794
} else if (ordering == T::greater) {
795
*os << "(greater)";
796
} else if (ordering == T::equivalent) {
797
*os << "(equivalent)";
798
} else {
799
*os << "(unknown ordering)";
800
}
801
}
802
803
inline void PrintTo(std::strong_ordering ordering, std::ostream* os) {
804
if (ordering == std::strong_ordering::equal) {
805
*os << "(equal)";
806
} else {
807
PrintOrderingHelper(ordering, os);
808
}
809
}
810
811
inline void PrintTo(std::partial_ordering ordering, std::ostream* os) {
812
if (ordering == std::partial_ordering::unordered) {
813
*os << "(unordered)";
814
} else {
815
PrintOrderingHelper(ordering, os);
816
}
817
}
818
819
inline void PrintTo(std::weak_ordering ordering, std::ostream* os) {
820
PrintOrderingHelper(ordering, os);
821
}
822
#endif
823
824
// Helper function for printing a tuple. T must be instantiated with
825
// a tuple type.
826
template <typename T>
827
void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
828
::std::ostream*) {}
829
830
template <typename T, size_t I>
831
void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
832
::std::ostream* os) {
833
PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
834
GTEST_INTENTIONAL_CONST_COND_PUSH_()
835
if (I > 1) {
836
GTEST_INTENTIONAL_CONST_COND_POP_()
837
*os << ", ";
838
}
839
UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
840
std::get<I - 1>(t), os);
841
}
842
843
template <typename... Types>
844
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
845
*os << "(";
846
PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
847
*os << ")";
848
}
849
850
// Overload for std::pair.
851
template <typename T1, typename T2>
852
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
853
*os << '(';
854
// We cannot use UniversalPrint(value.first, os) here, as T1 may be
855
// a reference type. The same for printing value.second.
856
UniversalPrinter<T1>::Print(value.first, os);
857
*os << ", ";
858
UniversalPrinter<T2>::Print(value.second, os);
859
*os << ')';
860
}
861
862
// Implements printing a non-reference type T by letting the compiler
863
// pick the right overload of PrintTo() for T.
864
template <typename T>
865
class UniversalPrinter {
866
public:
867
// MSVC warns about adding const to a function type, so we want to
868
// disable the warning.
869
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
870
871
// Note: we deliberately don't call this PrintTo(), as that name
872
// conflicts with ::testing::internal::PrintTo in the body of the
873
// function.
874
static void Print(const T& value, ::std::ostream* os) {
875
// By default, ::testing::internal::PrintTo() is used for printing
876
// the value.
877
//
878
// Thanks to Koenig look-up, if T is a class and has its own
879
// PrintTo() function defined in its namespace, that function will
880
// be visible here. Since it is more specific than the generic ones
881
// in ::testing::internal, it will be picked by the compiler in the
882
// following statement - exactly what we want.
883
PrintTo(value, os);
884
}
885
886
GTEST_DISABLE_MSC_WARNINGS_POP_()
887
};
888
889
// Remove any const-qualifiers before passing a type to UniversalPrinter.
890
template <typename T>
891
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
892
893
#if GTEST_INTERNAL_HAS_ANY
894
895
// Printer for std::any / absl::any
896
897
template <>
898
class UniversalPrinter<Any> {
899
public:
900
static void Print(const Any& value, ::std::ostream* os) {
901
if (value.has_value()) {
902
*os << "value of type " << GetTypeName(value);
903
} else {
904
*os << "no value";
905
}
906
}
907
908
private:
909
static std::string GetTypeName(const Any& value) {
910
#if GTEST_HAS_RTTI
911
return internal::GetTypeName(value.type());
912
#else
913
static_cast<void>(value); // possibly unused
914
return "<unknown_type>";
915
#endif // GTEST_HAS_RTTI
916
}
917
};
918
919
#endif // GTEST_INTERNAL_HAS_ANY
920
921
#if GTEST_INTERNAL_HAS_OPTIONAL
922
923
// Printer for std::optional / absl::optional
924
925
template <typename T>
926
class UniversalPrinter<Optional<T>> {
927
public:
928
static void Print(const Optional<T>& value, ::std::ostream* os) {
929
*os << '(';
930
if (!value) {
931
*os << "nullopt";
932
} else {
933
UniversalPrint(*value, os);
934
}
935
*os << ')';
936
}
937
};
938
939
template <>
940
class UniversalPrinter<decltype(Nullopt())> {
941
public:
942
static void Print(decltype(Nullopt()), ::std::ostream* os) {
943
*os << "(nullopt)";
944
}
945
};
946
947
#endif // GTEST_INTERNAL_HAS_OPTIONAL
948
949
#if GTEST_INTERNAL_HAS_VARIANT
950
951
// Printer for std::variant / absl::variant
952
953
template <typename... T>
954
class UniversalPrinter<Variant<T...>> {
955
public:
956
static void Print(const Variant<T...>& value, ::std::ostream* os) {
957
*os << '(';
958
#ifdef GTEST_HAS_ABSL
959
absl::visit(Visitor{os, value.index()}, value);
960
#else
961
std::visit(Visitor{os, value.index()}, value);
962
#endif // GTEST_HAS_ABSL
963
*os << ')';
964
}
965
966
private:
967
struct Visitor {
968
template <typename U>
969
void operator()(const U& u) const {
970
*os << "'" << GetTypeName<U>() << "(index = " << index
971
<< ")' with value ";
972
UniversalPrint(u, os);
973
}
974
::std::ostream* os;
975
std::size_t index;
976
};
977
};
978
979
#endif // GTEST_INTERNAL_HAS_VARIANT
980
981
// UniversalPrintArray(begin, len, os) prints an array of 'len'
982
// elements, starting at address 'begin'.
983
template <typename T>
984
void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
985
if (len == 0) {
986
*os << "{}";
987
} else {
988
*os << "{ ";
989
const size_t kThreshold = 18;
990
const size_t kChunkSize = 8;
991
// If the array has more than kThreshold elements, we'll have to
992
// omit some details by printing only the first and the last
993
// kChunkSize elements.
994
if (len <= kThreshold) {
995
PrintRawArrayTo(begin, len, os);
996
} else {
997
PrintRawArrayTo(begin, kChunkSize, os);
998
*os << ", ..., ";
999
PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
1000
}
1001
*os << " }";
1002
}
1003
}
1004
// This overload prints a (const) char array compactly.
1005
GTEST_API_ void UniversalPrintArray(const char* begin, size_t len,
1006
::std::ostream* os);
1007
1008
#ifdef __cpp_lib_char8_t
1009
// This overload prints a (const) char8_t array compactly.
1010
GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,
1011
::std::ostream* os);
1012
#endif
1013
1014
// This overload prints a (const) char16_t array compactly.
1015
GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,
1016
::std::ostream* os);
1017
1018
// This overload prints a (const) char32_t array compactly.
1019
GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,
1020
::std::ostream* os);
1021
1022
// This overload prints a (const) wchar_t array compactly.
1023
GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
1024
::std::ostream* os);
1025
1026
// Implements printing an array type T[N].
1027
template <typename T, size_t N>
1028
class UniversalPrinter<T[N]> {
1029
public:
1030
// Prints the given array, omitting some elements when there are too
1031
// many.
1032
static void Print(const T (&a)[N], ::std::ostream* os) {
1033
UniversalPrintArray(a, N, os);
1034
}
1035
};
1036
1037
// Implements printing a reference type T&.
1038
template <typename T>
1039
class UniversalPrinter<T&> {
1040
public:
1041
// MSVC warns about adding const to a function type, so we want to
1042
// disable the warning.
1043
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
1044
1045
static void Print(const T& value, ::std::ostream* os) {
1046
// Prints the address of the value. We use reinterpret_cast here
1047
// as static_cast doesn't compile when T is a function type.
1048
*os << "@" << reinterpret_cast<const void*>(&value) << " ";
1049
1050
// Then prints the value itself.
1051
UniversalPrint(value, os);
1052
}
1053
1054
GTEST_DISABLE_MSC_WARNINGS_POP_()
1055
};
1056
1057
// Prints a value tersely: for a reference type, the referenced value
1058
// (but not the address) is printed; for a (const) char pointer, the
1059
// NUL-terminated string (but not the pointer) is printed.
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
// Prints a value using the type inferred by the compiler. The
1179
// difference between this and UniversalTersePrint() is that for a
1180
// (const) char pointer, this prints both the pointer and the
1181
// NUL-terminated string.
1182
template <typename T>
1183
void UniversalPrint(const T& value, ::std::ostream* os) {
1184
// A workarond for the bug in VC++ 7.1 that prevents us from instantiating
1185
// UniversalPrinter with T directly.
1186
typedef T T1;
1187
UniversalPrinter<T1>::Print(value, os);
1188
}
1189
1190
typedef ::std::vector<::std::string> Strings;
1191
1192
// Tersely prints the first N fields of a tuple to a string vector,
1193
// one element for each field.
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
// Prints the fields of a tuple tersely to a string vector, one
1209
// element for each field. See the comment before
1210
// UniversalTersePrint() for how we define "tersely".
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
} // namespace internal
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
} // namespace testing
1230
1231
// Include any custom printer added by the local installation.
1232
// We must include this header at the end to make sure it can use the
1233
// declarations from this file.
1234
#include "gtest/internal/custom/gtest-printers.h"
1235
1236
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
1237
1238