113481Sgiacomo.travaglini@arm.com// Copyright 2007, Google Inc.
213481Sgiacomo.travaglini@arm.com// All rights reserved.
313481Sgiacomo.travaglini@arm.com//
413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
613481Sgiacomo.travaglini@arm.com// met:
713481Sgiacomo.travaglini@arm.com//
813481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1013481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1313481Sgiacomo.travaglini@arm.com// distribution.
1413481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1713481Sgiacomo.travaglini@arm.com//
1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913481Sgiacomo.travaglini@arm.com//
3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan)
3113481Sgiacomo.travaglini@arm.com
3213481Sgiacomo.travaglini@arm.com// Google Test - The Google C++ Testing Framework
3313481Sgiacomo.travaglini@arm.com//
3413481Sgiacomo.travaglini@arm.com// This file implements a universal value printer that can print a
3513481Sgiacomo.travaglini@arm.com// value of any type T:
3613481Sgiacomo.travaglini@arm.com//
3713481Sgiacomo.travaglini@arm.com//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
3813481Sgiacomo.travaglini@arm.com//
3913481Sgiacomo.travaglini@arm.com// A user can teach this function how to print a class type T by
4013481Sgiacomo.travaglini@arm.com// defining either operator<<() or PrintTo() in the namespace that
4113481Sgiacomo.travaglini@arm.com// defines T.  More specifically, the FIRST defined function in the
4213481Sgiacomo.travaglini@arm.com// following list will be used (assuming T is defined in namespace
4313481Sgiacomo.travaglini@arm.com// foo):
4413481Sgiacomo.travaglini@arm.com//
4513481Sgiacomo.travaglini@arm.com//   1. foo::PrintTo(const T&, ostream*)
4613481Sgiacomo.travaglini@arm.com//   2. operator<<(ostream&, const T&) defined in either foo or the
4713481Sgiacomo.travaglini@arm.com//      global namespace.
4813481Sgiacomo.travaglini@arm.com//
4913481Sgiacomo.travaglini@arm.com// If none of the above is defined, it will print the debug string of
5013481Sgiacomo.travaglini@arm.com// the value if it is a protocol buffer, or print the raw bytes in the
5113481Sgiacomo.travaglini@arm.com// value otherwise.
5213481Sgiacomo.travaglini@arm.com//
5313481Sgiacomo.travaglini@arm.com// To aid debugging: when T is a reference type, the address of the
5413481Sgiacomo.travaglini@arm.com// value is also printed; when T is a (const) char pointer, both the
5513481Sgiacomo.travaglini@arm.com// pointer value and the NUL-terminated string it points to are
5613481Sgiacomo.travaglini@arm.com// printed.
5713481Sgiacomo.travaglini@arm.com//
5813481Sgiacomo.travaglini@arm.com// We also provide some convenient wrappers:
5913481Sgiacomo.travaglini@arm.com//
6013481Sgiacomo.travaglini@arm.com//   // Prints a value to a string.  For a (const or not) char
6113481Sgiacomo.travaglini@arm.com//   // pointer, the NUL-terminated string (but not the pointer) is
6213481Sgiacomo.travaglini@arm.com//   // printed.
6313481Sgiacomo.travaglini@arm.com//   std::string ::testing::PrintToString(const T& value);
6413481Sgiacomo.travaglini@arm.com//
6513481Sgiacomo.travaglini@arm.com//   // Prints a value tersely: for a reference type, the referenced
6613481Sgiacomo.travaglini@arm.com//   // value (but not the address) is printed; for a (const or not) char
6713481Sgiacomo.travaglini@arm.com//   // pointer, the NUL-terminated string (but not the pointer) is
6813481Sgiacomo.travaglini@arm.com//   // printed.
6913481Sgiacomo.travaglini@arm.com//   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
7013481Sgiacomo.travaglini@arm.com//
7113481Sgiacomo.travaglini@arm.com//   // Prints value using the type inferred by the compiler.  The difference
7213481Sgiacomo.travaglini@arm.com//   // from UniversalTersePrint() is that this function prints both the
7313481Sgiacomo.travaglini@arm.com//   // pointer and the NUL-terminated string for a (const or not) char pointer.
7413481Sgiacomo.travaglini@arm.com//   void ::testing::internal::UniversalPrint(const T& value, ostream*);
7513481Sgiacomo.travaglini@arm.com//
7613481Sgiacomo.travaglini@arm.com//   // Prints the fields of a tuple tersely to a string vector, one
7713481Sgiacomo.travaglini@arm.com//   // element for each field. Tuple support must be enabled in
7813481Sgiacomo.travaglini@arm.com//   // gtest-port.h.
7913481Sgiacomo.travaglini@arm.com//   std::vector<string> UniversalTersePrintTupleFieldsToStrings(
8013481Sgiacomo.travaglini@arm.com//       const Tuple& value);
8113481Sgiacomo.travaglini@arm.com//
8213481Sgiacomo.travaglini@arm.com// Known limitation:
8313481Sgiacomo.travaglini@arm.com//
8413481Sgiacomo.travaglini@arm.com// The print primitives print the elements of an STL-style container
8513481Sgiacomo.travaglini@arm.com// using the compiler-inferred type of *iter where iter is a
8613481Sgiacomo.travaglini@arm.com// const_iterator of the container.  When const_iterator is an input
8713481Sgiacomo.travaglini@arm.com// iterator but not a forward iterator, this inferred type may not
8813481Sgiacomo.travaglini@arm.com// match value_type, and the print output may be incorrect.  In
8913481Sgiacomo.travaglini@arm.com// practice, this is rarely a problem as for most containers
9013481Sgiacomo.travaglini@arm.com// const_iterator is a forward iterator.  We'll fix this if there's an
9113481Sgiacomo.travaglini@arm.com// actual need for it.  Note that this fix cannot rely on value_type
9213481Sgiacomo.travaglini@arm.com// being defined as many user-defined container types don't have
9313481Sgiacomo.travaglini@arm.com// value_type.
9413481Sgiacomo.travaglini@arm.com
9513481Sgiacomo.travaglini@arm.com#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
9613481Sgiacomo.travaglini@arm.com#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
9713481Sgiacomo.travaglini@arm.com
9813481Sgiacomo.travaglini@arm.com#include <ostream>  // NOLINT
9913481Sgiacomo.travaglini@arm.com#include <sstream>
10013481Sgiacomo.travaglini@arm.com#include <string>
10113481Sgiacomo.travaglini@arm.com#include <utility>
10213481Sgiacomo.travaglini@arm.com#include <vector>
10313481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-port.h"
10413481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-internal.h"
10513481Sgiacomo.travaglini@arm.com
10613481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_TUPLE_
10713481Sgiacomo.travaglini@arm.com# include <tuple>
10813481Sgiacomo.travaglini@arm.com#endif
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.comnamespace testing {
11113481Sgiacomo.travaglini@arm.com
11213481Sgiacomo.travaglini@arm.com// Definitions in the 'internal' and 'internal2' name spaces are
11313481Sgiacomo.travaglini@arm.com// subject to change without notice.  DO NOT USE THEM IN USER CODE!
11413481Sgiacomo.travaglini@arm.comnamespace internal2 {
11513481Sgiacomo.travaglini@arm.com
11613481Sgiacomo.travaglini@arm.com// Prints the given number of bytes in the given object to the given
11713481Sgiacomo.travaglini@arm.com// ostream.
11813481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
11913481Sgiacomo.travaglini@arm.com                                     size_t count,
12013481Sgiacomo.travaglini@arm.com                                     ::std::ostream* os);
12113481Sgiacomo.travaglini@arm.com
12213481Sgiacomo.travaglini@arm.com// For selecting which printer to use when a given type has neither <<
12313481Sgiacomo.travaglini@arm.com// nor PrintTo().
12413481Sgiacomo.travaglini@arm.comenum TypeKind {
12513481Sgiacomo.travaglini@arm.com  kProtobuf,              // a protobuf type
12613481Sgiacomo.travaglini@arm.com  kConvertibleToInteger,  // a type implicitly convertible to BiggestInt
12713481Sgiacomo.travaglini@arm.com                          // (e.g. a named or unnamed enum type)
12813481Sgiacomo.travaglini@arm.com  kOtherType              // anything else
12913481Sgiacomo.travaglini@arm.com};
13013481Sgiacomo.travaglini@arm.com
13113481Sgiacomo.travaglini@arm.com// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
13213481Sgiacomo.travaglini@arm.com// by the universal printer to print a value of type T when neither
13313481Sgiacomo.travaglini@arm.com// operator<< nor PrintTo() is defined for T, where kTypeKind is the
13413481Sgiacomo.travaglini@arm.com// "kind" of T as defined by enum TypeKind.
13513481Sgiacomo.travaglini@arm.comtemplate <typename T, TypeKind kTypeKind>
13613481Sgiacomo.travaglini@arm.comclass TypeWithoutFormatter {
13713481Sgiacomo.travaglini@arm.com public:
13813481Sgiacomo.travaglini@arm.com  // This default version is called when kTypeKind is kOtherType.
13913481Sgiacomo.travaglini@arm.com  static void PrintValue(const T& value, ::std::ostream* os) {
14013481Sgiacomo.travaglini@arm.com    PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
14113481Sgiacomo.travaglini@arm.com                         sizeof(value), os);
14213481Sgiacomo.travaglini@arm.com  }
14313481Sgiacomo.travaglini@arm.com};
14413481Sgiacomo.travaglini@arm.com
14513481Sgiacomo.travaglini@arm.com// We print a protobuf using its ShortDebugString() when the string
14613481Sgiacomo.travaglini@arm.com// doesn't exceed this many characters; otherwise we print it using
14713481Sgiacomo.travaglini@arm.com// DebugString() for better readability.
14813481Sgiacomo.travaglini@arm.comconst size_t kProtobufOneLinerMaxLength = 50;
14913481Sgiacomo.travaglini@arm.com
15013481Sgiacomo.travaglini@arm.comtemplate <typename T>
15113481Sgiacomo.travaglini@arm.comclass TypeWithoutFormatter<T, kProtobuf> {
15213481Sgiacomo.travaglini@arm.com public:
15313481Sgiacomo.travaglini@arm.com  static void PrintValue(const T& value, ::std::ostream* os) {
15413481Sgiacomo.travaglini@arm.com    const ::testing::internal::string short_str = value.ShortDebugString();
15513481Sgiacomo.travaglini@arm.com    const ::testing::internal::string pretty_str =
15613481Sgiacomo.travaglini@arm.com        short_str.length() <= kProtobufOneLinerMaxLength ?
15713481Sgiacomo.travaglini@arm.com        short_str : ("\n" + value.DebugString());
15813481Sgiacomo.travaglini@arm.com    *os << ("<" + pretty_str + ">");
15913481Sgiacomo.travaglini@arm.com  }
16013481Sgiacomo.travaglini@arm.com};
16113481Sgiacomo.travaglini@arm.com
16213481Sgiacomo.travaglini@arm.comtemplate <typename T>
16313481Sgiacomo.travaglini@arm.comclass TypeWithoutFormatter<T, kConvertibleToInteger> {
16413481Sgiacomo.travaglini@arm.com public:
16513481Sgiacomo.travaglini@arm.com  // Since T has no << operator or PrintTo() but can be implicitly
16613481Sgiacomo.travaglini@arm.com  // converted to BiggestInt, we print it as a BiggestInt.
16713481Sgiacomo.travaglini@arm.com  //
16813481Sgiacomo.travaglini@arm.com  // Most likely T is an enum type (either named or unnamed), in which
16913481Sgiacomo.travaglini@arm.com  // case printing it as an integer is the desired behavior.  In case
17013481Sgiacomo.travaglini@arm.com  // T is not an enum, printing it as an integer is the best we can do
17113481Sgiacomo.travaglini@arm.com  // given that it has no user-defined printer.
17213481Sgiacomo.travaglini@arm.com  static void PrintValue(const T& value, ::std::ostream* os) {
17313481Sgiacomo.travaglini@arm.com    const internal::BiggestInt kBigInt = value;
17413481Sgiacomo.travaglini@arm.com    *os << kBigInt;
17513481Sgiacomo.travaglini@arm.com  }
17613481Sgiacomo.travaglini@arm.com};
17713481Sgiacomo.travaglini@arm.com
17813481Sgiacomo.travaglini@arm.com// Prints the given value to the given ostream.  If the value is a
17913481Sgiacomo.travaglini@arm.com// protocol message, its debug string is printed; if it's an enum or
18013481Sgiacomo.travaglini@arm.com// of a type implicitly convertible to BiggestInt, it's printed as an
18113481Sgiacomo.travaglini@arm.com// integer; otherwise the bytes in the value are printed.  This is
18213481Sgiacomo.travaglini@arm.com// what UniversalPrinter<T>::Print() does when it knows nothing about
18313481Sgiacomo.travaglini@arm.com// type T and T has neither << operator nor PrintTo().
18413481Sgiacomo.travaglini@arm.com//
18513481Sgiacomo.travaglini@arm.com// A user can override this behavior for a class type Foo by defining
18613481Sgiacomo.travaglini@arm.com// a << operator in the namespace where Foo is defined.
18713481Sgiacomo.travaglini@arm.com//
18813481Sgiacomo.travaglini@arm.com// We put this operator in namespace 'internal2' instead of 'internal'
18913481Sgiacomo.travaglini@arm.com// to simplify the implementation, as much code in 'internal' needs to
19013481Sgiacomo.travaglini@arm.com// use << in STL, which would conflict with our own << were it defined
19113481Sgiacomo.travaglini@arm.com// in 'internal'.
19213481Sgiacomo.travaglini@arm.com//
19313481Sgiacomo.travaglini@arm.com// Note that this operator<< takes a generic std::basic_ostream<Char,
19413481Sgiacomo.travaglini@arm.com// CharTraits> type instead of the more restricted std::ostream.  If
19513481Sgiacomo.travaglini@arm.com// we define it to take an std::ostream instead, we'll get an
19613481Sgiacomo.travaglini@arm.com// "ambiguous overloads" compiler error when trying to print a type
19713481Sgiacomo.travaglini@arm.com// Foo that supports streaming to std::basic_ostream<Char,
19813481Sgiacomo.travaglini@arm.com// CharTraits>, as the compiler cannot tell whether
19913481Sgiacomo.travaglini@arm.com// operator<<(std::ostream&, const T&) or
20013481Sgiacomo.travaglini@arm.com// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
20113481Sgiacomo.travaglini@arm.com// specific.
20213481Sgiacomo.travaglini@arm.comtemplate <typename Char, typename CharTraits, typename T>
20313481Sgiacomo.travaglini@arm.com::std::basic_ostream<Char, CharTraits>& operator<<(
20413481Sgiacomo.travaglini@arm.com    ::std::basic_ostream<Char, CharTraits>& os, const T& x) {
20513481Sgiacomo.travaglini@arm.com  TypeWithoutFormatter<T,
20613481Sgiacomo.travaglini@arm.com      (internal::IsAProtocolMessage<T>::value ? kProtobuf :
20713481Sgiacomo.travaglini@arm.com       internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
20813481Sgiacomo.travaglini@arm.com       kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
20913481Sgiacomo.travaglini@arm.com  return os;
21013481Sgiacomo.travaglini@arm.com}
21113481Sgiacomo.travaglini@arm.com
21213481Sgiacomo.travaglini@arm.com}  // namespace internal2
21313481Sgiacomo.travaglini@arm.com}  // namespace testing
21413481Sgiacomo.travaglini@arm.com
21513481Sgiacomo.travaglini@arm.com// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
21613481Sgiacomo.travaglini@arm.com// magic needed for implementing UniversalPrinter won't work.
21713481Sgiacomo.travaglini@arm.comnamespace testing_internal {
21813481Sgiacomo.travaglini@arm.com
21913481Sgiacomo.travaglini@arm.com// Used to print a value that is not an STL-style container when the
22013481Sgiacomo.travaglini@arm.com// user doesn't define PrintTo() for it.
22113481Sgiacomo.travaglini@arm.comtemplate <typename T>
22213481Sgiacomo.travaglini@arm.comvoid DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
22313481Sgiacomo.travaglini@arm.com  // With the following statement, during unqualified name lookup,
22413481Sgiacomo.travaglini@arm.com  // testing::internal2::operator<< appears as if it was declared in
22513481Sgiacomo.travaglini@arm.com  // the nearest enclosing namespace that contains both
22613481Sgiacomo.travaglini@arm.com  // ::testing_internal and ::testing::internal2, i.e. the global
22713481Sgiacomo.travaglini@arm.com  // namespace.  For more details, refer to the C++ Standard section
22813481Sgiacomo.travaglini@arm.com  // 7.3.4-1 [namespace.udir].  This allows us to fall back onto
22913481Sgiacomo.travaglini@arm.com  // testing::internal2::operator<< in case T doesn't come with a <<
23013481Sgiacomo.travaglini@arm.com  // operator.
23113481Sgiacomo.travaglini@arm.com  //
23213481Sgiacomo.travaglini@arm.com  // We cannot write 'using ::testing::internal2::operator<<;', which
23313481Sgiacomo.travaglini@arm.com  // gcc 3.3 fails to compile due to a compiler bug.
23413481Sgiacomo.travaglini@arm.com  using namespace ::testing::internal2;  // NOLINT
23513481Sgiacomo.travaglini@arm.com
23613481Sgiacomo.travaglini@arm.com  // Assuming T is defined in namespace foo, in the next statement,
23713481Sgiacomo.travaglini@arm.com  // the compiler will consider all of:
23813481Sgiacomo.travaglini@arm.com  //
23913481Sgiacomo.travaglini@arm.com  //   1. foo::operator<< (thanks to Koenig look-up),
24013481Sgiacomo.travaglini@arm.com  //   2. ::operator<< (as the current namespace is enclosed in ::),
24113481Sgiacomo.travaglini@arm.com  //   3. testing::internal2::operator<< (thanks to the using statement above).
24213481Sgiacomo.travaglini@arm.com  //
24313481Sgiacomo.travaglini@arm.com  // The operator<< whose type matches T best will be picked.
24413481Sgiacomo.travaglini@arm.com  //
24513481Sgiacomo.travaglini@arm.com  // We deliberately allow #2 to be a candidate, as sometimes it's
24613481Sgiacomo.travaglini@arm.com  // impossible to define #1 (e.g. when foo is ::std, defining
24713481Sgiacomo.travaglini@arm.com  // anything in it is undefined behavior unless you are a compiler
24813481Sgiacomo.travaglini@arm.com  // vendor.).
24913481Sgiacomo.travaglini@arm.com  *os << value;
25013481Sgiacomo.travaglini@arm.com}
25113481Sgiacomo.travaglini@arm.com
25213481Sgiacomo.travaglini@arm.com}  // namespace testing_internal
25313481Sgiacomo.travaglini@arm.com
25413481Sgiacomo.travaglini@arm.comnamespace testing {
25513481Sgiacomo.travaglini@arm.comnamespace internal {
25613481Sgiacomo.travaglini@arm.com
25713481Sgiacomo.travaglini@arm.com// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
25813481Sgiacomo.travaglini@arm.com// value of type ToPrint that is an operand of a comparison assertion
25913481Sgiacomo.travaglini@arm.com// (e.g. ASSERT_EQ).  OtherOperand is the type of the other operand in
26013481Sgiacomo.travaglini@arm.com// the comparison, and is used to help determine the best way to
26113481Sgiacomo.travaglini@arm.com// format the value.  In particular, when the value is a C string
26213481Sgiacomo.travaglini@arm.com// (char pointer) and the other operand is an STL string object, we
26313481Sgiacomo.travaglini@arm.com// want to format the C string as a string, since we know it is
26413481Sgiacomo.travaglini@arm.com// compared by value with the string object.  If the value is a char
26513481Sgiacomo.travaglini@arm.com// pointer but the other operand is not an STL string object, we don't
26613481Sgiacomo.travaglini@arm.com// know whether the pointer is supposed to point to a NUL-terminated
26713481Sgiacomo.travaglini@arm.com// string, and thus want to print it as a pointer to be safe.
26813481Sgiacomo.travaglini@arm.com//
26913481Sgiacomo.travaglini@arm.com// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
27013481Sgiacomo.travaglini@arm.com
27113481Sgiacomo.travaglini@arm.com// The default case.
27213481Sgiacomo.travaglini@arm.comtemplate <typename ToPrint, typename OtherOperand>
27313481Sgiacomo.travaglini@arm.comclass FormatForComparison {
27413481Sgiacomo.travaglini@arm.com public:
27513481Sgiacomo.travaglini@arm.com  static ::std::string Format(const ToPrint& value) {
27613481Sgiacomo.travaglini@arm.com    return ::testing::PrintToString(value);
27713481Sgiacomo.travaglini@arm.com  }
27813481Sgiacomo.travaglini@arm.com};
27913481Sgiacomo.travaglini@arm.com
28013481Sgiacomo.travaglini@arm.com// Array.
28113481Sgiacomo.travaglini@arm.comtemplate <typename ToPrint, size_t N, typename OtherOperand>
28213481Sgiacomo.travaglini@arm.comclass FormatForComparison<ToPrint[N], OtherOperand> {
28313481Sgiacomo.travaglini@arm.com public:
28413481Sgiacomo.travaglini@arm.com  static ::std::string Format(const ToPrint* value) {
28513481Sgiacomo.travaglini@arm.com    return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
28613481Sgiacomo.travaglini@arm.com  }
28713481Sgiacomo.travaglini@arm.com};
28813481Sgiacomo.travaglini@arm.com
28913481Sgiacomo.travaglini@arm.com// By default, print C string as pointers to be safe, as we don't know
29013481Sgiacomo.travaglini@arm.com// whether they actually point to a NUL-terminated string.
29113481Sgiacomo.travaglini@arm.com
29213481Sgiacomo.travaglini@arm.com#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType)                \
29313481Sgiacomo.travaglini@arm.com  template <typename OtherOperand>                                      \
29413481Sgiacomo.travaglini@arm.com  class FormatForComparison<CharType*, OtherOperand> {                  \
29513481Sgiacomo.travaglini@arm.com   public:                                                              \
29613481Sgiacomo.travaglini@arm.com    static ::std::string Format(CharType* value) {                      \
29713481Sgiacomo.travaglini@arm.com      return ::testing::PrintToString(static_cast<const void*>(value)); \
29813481Sgiacomo.travaglini@arm.com    }                                                                   \
29913481Sgiacomo.travaglini@arm.com  }
30013481Sgiacomo.travaglini@arm.com
30113481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
30213481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
30313481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
30413481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
30513481Sgiacomo.travaglini@arm.com
30613481Sgiacomo.travaglini@arm.com#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
30713481Sgiacomo.travaglini@arm.com
30813481Sgiacomo.travaglini@arm.com// If a C string is compared with an STL string object, we know it's meant
30913481Sgiacomo.travaglini@arm.com// to point to a NUL-terminated string, and thus can print it as a string.
31013481Sgiacomo.travaglini@arm.com
31113481Sgiacomo.travaglini@arm.com#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
31213481Sgiacomo.travaglini@arm.com  template <>                                                           \
31313481Sgiacomo.travaglini@arm.com  class FormatForComparison<CharType*, OtherStringType> {               \
31413481Sgiacomo.travaglini@arm.com   public:                                                              \
31513481Sgiacomo.travaglini@arm.com    static ::std::string Format(CharType* value) {                      \
31613481Sgiacomo.travaglini@arm.com      return ::testing::PrintToString(value);                           \
31713481Sgiacomo.travaglini@arm.com    }                                                                   \
31813481Sgiacomo.travaglini@arm.com  }
31913481Sgiacomo.travaglini@arm.com
32013481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
32113481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
32213481Sgiacomo.travaglini@arm.com
32313481Sgiacomo.travaglini@arm.com#if GTEST_HAS_GLOBAL_STRING
32413481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);
32513481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);
32613481Sgiacomo.travaglini@arm.com#endif
32713481Sgiacomo.travaglini@arm.com
32813481Sgiacomo.travaglini@arm.com#if GTEST_HAS_GLOBAL_WSTRING
32913481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);
33013481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);
33113481Sgiacomo.travaglini@arm.com#endif
33213481Sgiacomo.travaglini@arm.com
33313481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_WSTRING
33413481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
33513481Sgiacomo.travaglini@arm.comGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
33613481Sgiacomo.travaglini@arm.com#endif
33713481Sgiacomo.travaglini@arm.com
33813481Sgiacomo.travaglini@arm.com#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
33913481Sgiacomo.travaglini@arm.com
34013481Sgiacomo.travaglini@arm.com// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
34113481Sgiacomo.travaglini@arm.com// operand to be used in a failure message.  The type (but not value)
34213481Sgiacomo.travaglini@arm.com// of the other operand may affect the format.  This allows us to
34313481Sgiacomo.travaglini@arm.com// print a char* as a raw pointer when it is compared against another
34413481Sgiacomo.travaglini@arm.com// char* or void*, and print it as a C string when it is compared
34513481Sgiacomo.travaglini@arm.com// against an std::string object, for example.
34613481Sgiacomo.travaglini@arm.com//
34713481Sgiacomo.travaglini@arm.com// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
34813481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2>
34913481Sgiacomo.travaglini@arm.comstd::string FormatForComparisonFailureMessage(
35013481Sgiacomo.travaglini@arm.com    const T1& value, const T2& /* other_operand */) {
35113481Sgiacomo.travaglini@arm.com  return FormatForComparison<T1, T2>::Format(value);
35213481Sgiacomo.travaglini@arm.com}
35313481Sgiacomo.travaglini@arm.com
35413481Sgiacomo.travaglini@arm.com// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
35513481Sgiacomo.travaglini@arm.com// value to the given ostream.  The caller must ensure that
35613481Sgiacomo.travaglini@arm.com// 'ostream_ptr' is not NULL, or the behavior is undefined.
35713481Sgiacomo.travaglini@arm.com//
35813481Sgiacomo.travaglini@arm.com// We define UniversalPrinter as a class template (as opposed to a
35913481Sgiacomo.travaglini@arm.com// function template), as we need to partially specialize it for
36013481Sgiacomo.travaglini@arm.com// reference types, which cannot be done with function templates.
36113481Sgiacomo.travaglini@arm.comtemplate <typename T>
36213481Sgiacomo.travaglini@arm.comclass UniversalPrinter;
36313481Sgiacomo.travaglini@arm.com
36413481Sgiacomo.travaglini@arm.comtemplate <typename T>
36513481Sgiacomo.travaglini@arm.comvoid UniversalPrint(const T& value, ::std::ostream* os);
36613481Sgiacomo.travaglini@arm.com
36713481Sgiacomo.travaglini@arm.com// Used to print an STL-style container when the user doesn't define
36813481Sgiacomo.travaglini@arm.com// a PrintTo() for it.
36913481Sgiacomo.travaglini@arm.comtemplate <typename C>
37013481Sgiacomo.travaglini@arm.comvoid DefaultPrintTo(IsContainer /* dummy */,
37113481Sgiacomo.travaglini@arm.com                    false_type /* is not a pointer */,
37213481Sgiacomo.travaglini@arm.com                    const C& container, ::std::ostream* os) {
37313481Sgiacomo.travaglini@arm.com  const size_t kMaxCount = 32;  // The maximum number of elements to print.
37413481Sgiacomo.travaglini@arm.com  *os << '{';
37513481Sgiacomo.travaglini@arm.com  size_t count = 0;
37613481Sgiacomo.travaglini@arm.com  for (typename C::const_iterator it = container.begin();
37713481Sgiacomo.travaglini@arm.com       it != container.end(); ++it, ++count) {
37813481Sgiacomo.travaglini@arm.com    if (count > 0) {
37913481Sgiacomo.travaglini@arm.com      *os << ',';
38013481Sgiacomo.travaglini@arm.com      if (count == kMaxCount) {  // Enough has been printed.
38113481Sgiacomo.travaglini@arm.com        *os << " ...";
38213481Sgiacomo.travaglini@arm.com        break;
38313481Sgiacomo.travaglini@arm.com      }
38413481Sgiacomo.travaglini@arm.com    }
38513481Sgiacomo.travaglini@arm.com    *os << ' ';
38613481Sgiacomo.travaglini@arm.com    // We cannot call PrintTo(*it, os) here as PrintTo() doesn't
38713481Sgiacomo.travaglini@arm.com    // handle *it being a native array.
38813481Sgiacomo.travaglini@arm.com    internal::UniversalPrint(*it, os);
38913481Sgiacomo.travaglini@arm.com  }
39013481Sgiacomo.travaglini@arm.com
39113481Sgiacomo.travaglini@arm.com  if (count > 0) {
39213481Sgiacomo.travaglini@arm.com    *os << ' ';
39313481Sgiacomo.travaglini@arm.com  }
39413481Sgiacomo.travaglini@arm.com  *os << '}';
39513481Sgiacomo.travaglini@arm.com}
39613481Sgiacomo.travaglini@arm.com
39713481Sgiacomo.travaglini@arm.com// Used to print a pointer that is neither a char pointer nor a member
39813481Sgiacomo.travaglini@arm.com// pointer, when the user doesn't define PrintTo() for it.  (A member
39913481Sgiacomo.travaglini@arm.com// variable pointer or member function pointer doesn't really point to
40013481Sgiacomo.travaglini@arm.com// a location in the address space.  Their representation is
40113481Sgiacomo.travaglini@arm.com// implementation-defined.  Therefore they will be printed as raw
40213481Sgiacomo.travaglini@arm.com// bytes.)
40313481Sgiacomo.travaglini@arm.comtemplate <typename T>
40413481Sgiacomo.travaglini@arm.comvoid DefaultPrintTo(IsNotContainer /* dummy */,
40513481Sgiacomo.travaglini@arm.com                    true_type /* is a pointer */,
40613481Sgiacomo.travaglini@arm.com                    T* p, ::std::ostream* os) {
40713481Sgiacomo.travaglini@arm.com  if (p == NULL) {
40813481Sgiacomo.travaglini@arm.com    *os << "NULL";
40913481Sgiacomo.travaglini@arm.com  } else {
41013481Sgiacomo.travaglini@arm.com    // C++ doesn't allow casting from a function pointer to any object
41113481Sgiacomo.travaglini@arm.com    // pointer.
41213481Sgiacomo.travaglini@arm.com    //
41313481Sgiacomo.travaglini@arm.com    // IsTrue() silences warnings: "Condition is always true",
41413481Sgiacomo.travaglini@arm.com    // "unreachable code".
41513481Sgiacomo.travaglini@arm.com    if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {
41613481Sgiacomo.travaglini@arm.com      // T is not a function type.  We just call << to print p,
41713481Sgiacomo.travaglini@arm.com      // relying on ADL to pick up user-defined << for their pointer
41813481Sgiacomo.travaglini@arm.com      // types, if any.
41913481Sgiacomo.travaglini@arm.com      *os << p;
42013481Sgiacomo.travaglini@arm.com    } else {
42113481Sgiacomo.travaglini@arm.com      // T is a function type, so '*os << p' doesn't do what we want
42213481Sgiacomo.travaglini@arm.com      // (it just prints p as bool).  We want to print p as a const
42313481Sgiacomo.travaglini@arm.com      // void*.  However, we cannot cast it to const void* directly,
42413481Sgiacomo.travaglini@arm.com      // even using reinterpret_cast, as earlier versions of gcc
42513481Sgiacomo.travaglini@arm.com      // (e.g. 3.4.5) cannot compile the cast when p is a function
42613481Sgiacomo.travaglini@arm.com      // pointer.  Casting to UInt64 first solves the problem.
42713481Sgiacomo.travaglini@arm.com      *os << reinterpret_cast<const void*>(
42813481Sgiacomo.travaglini@arm.com          reinterpret_cast<internal::UInt64>(p));
42913481Sgiacomo.travaglini@arm.com    }
43013481Sgiacomo.travaglini@arm.com  }
43113481Sgiacomo.travaglini@arm.com}
43213481Sgiacomo.travaglini@arm.com
43313481Sgiacomo.travaglini@arm.com// Used to print a non-container, non-pointer value when the user
43413481Sgiacomo.travaglini@arm.com// doesn't define PrintTo() for it.
43513481Sgiacomo.travaglini@arm.comtemplate <typename T>
43613481Sgiacomo.travaglini@arm.comvoid DefaultPrintTo(IsNotContainer /* dummy */,
43713481Sgiacomo.travaglini@arm.com                    false_type /* is not a pointer */,
43813481Sgiacomo.travaglini@arm.com                    const T& value, ::std::ostream* os) {
43913481Sgiacomo.travaglini@arm.com  ::testing_internal::DefaultPrintNonContainerTo(value, os);
44013481Sgiacomo.travaglini@arm.com}
44113481Sgiacomo.travaglini@arm.com
44213481Sgiacomo.travaglini@arm.com// Prints the given value using the << operator if it has one;
44313481Sgiacomo.travaglini@arm.com// otherwise prints the bytes in it.  This is what
44413481Sgiacomo.travaglini@arm.com// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
44513481Sgiacomo.travaglini@arm.com// or overloaded for type T.
44613481Sgiacomo.travaglini@arm.com//
44713481Sgiacomo.travaglini@arm.com// A user can override this behavior for a class type Foo by defining
44813481Sgiacomo.travaglini@arm.com// an overload of PrintTo() in the namespace where Foo is defined.  We
44913481Sgiacomo.travaglini@arm.com// give the user this option as sometimes defining a << operator for
45013481Sgiacomo.travaglini@arm.com// Foo is not desirable (e.g. the coding style may prevent doing it,
45113481Sgiacomo.travaglini@arm.com// or there is already a << operator but it doesn't do what the user
45213481Sgiacomo.travaglini@arm.com// wants).
45313481Sgiacomo.travaglini@arm.comtemplate <typename T>
45413481Sgiacomo.travaglini@arm.comvoid PrintTo(const T& value, ::std::ostream* os) {
45513481Sgiacomo.travaglini@arm.com  // DefaultPrintTo() is overloaded.  The type of its first two
45613481Sgiacomo.travaglini@arm.com  // arguments determine which version will be picked.  If T is an
45713481Sgiacomo.travaglini@arm.com  // STL-style container, the version for container will be called; if
45813481Sgiacomo.travaglini@arm.com  // T is a pointer, the pointer version will be called; otherwise the
45913481Sgiacomo.travaglini@arm.com  // generic version will be called.
46013481Sgiacomo.travaglini@arm.com  //
46113481Sgiacomo.travaglini@arm.com  // Note that we check for container types here, prior to we check
46213481Sgiacomo.travaglini@arm.com  // for protocol message types in our operator<<.  The rationale is:
46313481Sgiacomo.travaglini@arm.com  //
46413481Sgiacomo.travaglini@arm.com  // For protocol messages, we want to give people a chance to
46513481Sgiacomo.travaglini@arm.com  // override Google Mock's format by defining a PrintTo() or
46613481Sgiacomo.travaglini@arm.com  // operator<<.  For STL containers, other formats can be
46713481Sgiacomo.travaglini@arm.com  // incompatible with Google Mock's format for the container
46813481Sgiacomo.travaglini@arm.com  // elements; therefore we check for container types here to ensure
46913481Sgiacomo.travaglini@arm.com  // that our format is used.
47013481Sgiacomo.travaglini@arm.com  //
47113481Sgiacomo.travaglini@arm.com  // The second argument of DefaultPrintTo() is needed to bypass a bug
47213481Sgiacomo.travaglini@arm.com  // in Symbian's C++ compiler that prevents it from picking the right
47313481Sgiacomo.travaglini@arm.com  // overload between:
47413481Sgiacomo.travaglini@arm.com  //
47513481Sgiacomo.travaglini@arm.com  //   PrintTo(const T& x, ...);
47613481Sgiacomo.travaglini@arm.com  //   PrintTo(T* x, ...);
47713481Sgiacomo.travaglini@arm.com  DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
47813481Sgiacomo.travaglini@arm.com}
47913481Sgiacomo.travaglini@arm.com
48013481Sgiacomo.travaglini@arm.com// The following list of PrintTo() overloads tells
48113481Sgiacomo.travaglini@arm.com// UniversalPrinter<T>::Print() how to print standard types (built-in
48213481Sgiacomo.travaglini@arm.com// types, strings, plain arrays, and pointers).
48313481Sgiacomo.travaglini@arm.com
48413481Sgiacomo.travaglini@arm.com// Overloads for various char types.
48513481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
48613481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
48713481Sgiacomo.travaglini@arm.cominline void PrintTo(char c, ::std::ostream* os) {
48813481Sgiacomo.travaglini@arm.com  // When printing a plain char, we always treat it as unsigned.  This
48913481Sgiacomo.travaglini@arm.com  // way, the output won't be affected by whether the compiler thinks
49013481Sgiacomo.travaglini@arm.com  // char is signed or not.
49113481Sgiacomo.travaglini@arm.com  PrintTo(static_cast<unsigned char>(c), os);
49213481Sgiacomo.travaglini@arm.com}
49313481Sgiacomo.travaglini@arm.com
49413481Sgiacomo.travaglini@arm.com// Overloads for other simple built-in types.
49513481Sgiacomo.travaglini@arm.cominline void PrintTo(bool x, ::std::ostream* os) {
49613481Sgiacomo.travaglini@arm.com  *os << (x ? "true" : "false");
49713481Sgiacomo.travaglini@arm.com}
49813481Sgiacomo.travaglini@arm.com
49913481Sgiacomo.travaglini@arm.com// Overload for wchar_t type.
50013481Sgiacomo.travaglini@arm.com// Prints a wchar_t as a symbol if it is printable or as its internal
50113481Sgiacomo.travaglini@arm.com// code otherwise and also as its decimal code (except for L'\0').
50213481Sgiacomo.travaglini@arm.com// The L'\0' char is printed as "L'\\0'". The decimal code is printed
50313481Sgiacomo.travaglini@arm.com// as signed integer when wchar_t is implemented by the compiler
50413481Sgiacomo.travaglini@arm.com// as a signed type and is printed as an unsigned integer when wchar_t
50513481Sgiacomo.travaglini@arm.com// is implemented as an unsigned type.
50613481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
50713481Sgiacomo.travaglini@arm.com
50813481Sgiacomo.travaglini@arm.com// Overloads for C strings.
50913481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
51013481Sgiacomo.travaglini@arm.cominline void PrintTo(char* s, ::std::ostream* os) {
51113481Sgiacomo.travaglini@arm.com  PrintTo(ImplicitCast_<const char*>(s), os);
51213481Sgiacomo.travaglini@arm.com}
51313481Sgiacomo.travaglini@arm.com
51413481Sgiacomo.travaglini@arm.com// signed/unsigned char is often used for representing binary data, so
51513481Sgiacomo.travaglini@arm.com// we print pointers to it as void* to be safe.
51613481Sgiacomo.travaglini@arm.cominline void PrintTo(const signed char* s, ::std::ostream* os) {
51713481Sgiacomo.travaglini@arm.com  PrintTo(ImplicitCast_<const void*>(s), os);
51813481Sgiacomo.travaglini@arm.com}
51913481Sgiacomo.travaglini@arm.cominline void PrintTo(signed char* s, ::std::ostream* os) {
52013481Sgiacomo.travaglini@arm.com  PrintTo(ImplicitCast_<const void*>(s), os);
52113481Sgiacomo.travaglini@arm.com}
52213481Sgiacomo.travaglini@arm.cominline void PrintTo(const unsigned char* s, ::std::ostream* os) {
52313481Sgiacomo.travaglini@arm.com  PrintTo(ImplicitCast_<const void*>(s), os);
52413481Sgiacomo.travaglini@arm.com}
52513481Sgiacomo.travaglini@arm.cominline void PrintTo(unsigned char* s, ::std::ostream* os) {
52613481Sgiacomo.travaglini@arm.com  PrintTo(ImplicitCast_<const void*>(s), os);
52713481Sgiacomo.travaglini@arm.com}
52813481Sgiacomo.travaglini@arm.com
52913481Sgiacomo.travaglini@arm.com// MSVC can be configured to define wchar_t as a typedef of unsigned
53013481Sgiacomo.travaglini@arm.com// short.  It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
53113481Sgiacomo.travaglini@arm.com// type.  When wchar_t is a typedef, defining an overload for const
53213481Sgiacomo.travaglini@arm.com// wchar_t* would cause unsigned short* be printed as a wide string,
53313481Sgiacomo.travaglini@arm.com// possibly causing invalid memory accesses.
53413481Sgiacomo.travaglini@arm.com#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
53513481Sgiacomo.travaglini@arm.com// Overloads for wide C strings
53613481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
53713481Sgiacomo.travaglini@arm.cominline void PrintTo(wchar_t* s, ::std::ostream* os) {
53813481Sgiacomo.travaglini@arm.com  PrintTo(ImplicitCast_<const wchar_t*>(s), os);
53913481Sgiacomo.travaglini@arm.com}
54013481Sgiacomo.travaglini@arm.com#endif
54113481Sgiacomo.travaglini@arm.com
54213481Sgiacomo.travaglini@arm.com// Overload for C arrays.  Multi-dimensional arrays are printed
54313481Sgiacomo.travaglini@arm.com// properly.
54413481Sgiacomo.travaglini@arm.com
54513481Sgiacomo.travaglini@arm.com// Prints the given number of elements in an array, without printing
54613481Sgiacomo.travaglini@arm.com// the curly braces.
54713481Sgiacomo.travaglini@arm.comtemplate <typename T>
54813481Sgiacomo.travaglini@arm.comvoid PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
54913481Sgiacomo.travaglini@arm.com  UniversalPrint(a[0], os);
55013481Sgiacomo.travaglini@arm.com  for (size_t i = 1; i != count; i++) {
55113481Sgiacomo.travaglini@arm.com    *os << ", ";
55213481Sgiacomo.travaglini@arm.com    UniversalPrint(a[i], os);
55313481Sgiacomo.travaglini@arm.com  }
55413481Sgiacomo.travaglini@arm.com}
55513481Sgiacomo.travaglini@arm.com
55613481Sgiacomo.travaglini@arm.com// Overloads for ::string and ::std::string.
55713481Sgiacomo.travaglini@arm.com#if GTEST_HAS_GLOBAL_STRING
55813481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os);
55913481Sgiacomo.travaglini@arm.cominline void PrintTo(const ::string& s, ::std::ostream* os) {
56013481Sgiacomo.travaglini@arm.com  PrintStringTo(s, os);
56113481Sgiacomo.travaglini@arm.com}
56213481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_GLOBAL_STRING
56313481Sgiacomo.travaglini@arm.com
56413481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
56513481Sgiacomo.travaglini@arm.cominline void PrintTo(const ::std::string& s, ::std::ostream* os) {
56613481Sgiacomo.travaglini@arm.com  PrintStringTo(s, os);
56713481Sgiacomo.travaglini@arm.com}
56813481Sgiacomo.travaglini@arm.com
56913481Sgiacomo.travaglini@arm.com// Overloads for ::wstring and ::std::wstring.
57013481Sgiacomo.travaglini@arm.com#if GTEST_HAS_GLOBAL_WSTRING
57113481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
57213481Sgiacomo.travaglini@arm.cominline void PrintTo(const ::wstring& s, ::std::ostream* os) {
57313481Sgiacomo.travaglini@arm.com  PrintWideStringTo(s, os);
57413481Sgiacomo.travaglini@arm.com}
57513481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_GLOBAL_WSTRING
57613481Sgiacomo.travaglini@arm.com
57713481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_WSTRING
57813481Sgiacomo.travaglini@arm.comGTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
57913481Sgiacomo.travaglini@arm.cominline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
58013481Sgiacomo.travaglini@arm.com  PrintWideStringTo(s, os);
58113481Sgiacomo.travaglini@arm.com}
58213481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_STD_WSTRING
58313481Sgiacomo.travaglini@arm.com
58413481Sgiacomo.travaglini@arm.com#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
58513481Sgiacomo.travaglini@arm.com// Helper function for printing a tuple.  T must be instantiated with
58613481Sgiacomo.travaglini@arm.com// a tuple type.
58713481Sgiacomo.travaglini@arm.comtemplate <typename T>
58813481Sgiacomo.travaglini@arm.comvoid PrintTupleTo(const T& t, ::std::ostream* os);
58913481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
59013481Sgiacomo.travaglini@arm.com
59113481Sgiacomo.travaglini@arm.com#if GTEST_HAS_TR1_TUPLE
59213481Sgiacomo.travaglini@arm.com// Overload for ::std::tr1::tuple.  Needed for printing function arguments,
59313481Sgiacomo.travaglini@arm.com// which are packed as tuples.
59413481Sgiacomo.travaglini@arm.com
59513481Sgiacomo.travaglini@arm.com// Overloaded PrintTo() for tuples of various arities.  We support
59613481Sgiacomo.travaglini@arm.com// tuples of up-to 10 fields.  The following implementation works
59713481Sgiacomo.travaglini@arm.com// regardless of whether tr1::tuple is implemented using the
59813481Sgiacomo.travaglini@arm.com// non-standard variadic template feature or not.
59913481Sgiacomo.travaglini@arm.com
60013481Sgiacomo.travaglini@arm.cominline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
60113481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
60213481Sgiacomo.travaglini@arm.com}
60313481Sgiacomo.travaglini@arm.com
60413481Sgiacomo.travaglini@arm.comtemplate <typename T1>
60513481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
60613481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
60713481Sgiacomo.travaglini@arm.com}
60813481Sgiacomo.travaglini@arm.com
60913481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2>
61013481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
61113481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
61213481Sgiacomo.travaglini@arm.com}
61313481Sgiacomo.travaglini@arm.com
61413481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3>
61513481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
61613481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
61713481Sgiacomo.travaglini@arm.com}
61813481Sgiacomo.travaglini@arm.com
61913481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, typename T4>
62013481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
62113481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
62213481Sgiacomo.travaglini@arm.com}
62313481Sgiacomo.travaglini@arm.com
62413481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, typename T4, typename T5>
62513481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
62613481Sgiacomo.travaglini@arm.com             ::std::ostream* os) {
62713481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
62813481Sgiacomo.travaglini@arm.com}
62913481Sgiacomo.travaglini@arm.com
63013481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, typename T4, typename T5,
63113481Sgiacomo.travaglini@arm.com          typename T6>
63213481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
63313481Sgiacomo.travaglini@arm.com             ::std::ostream* os) {
63413481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
63513481Sgiacomo.travaglini@arm.com}
63613481Sgiacomo.travaglini@arm.com
63713481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, typename T4, typename T5,
63813481Sgiacomo.travaglini@arm.com          typename T6, typename T7>
63913481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
64013481Sgiacomo.travaglini@arm.com             ::std::ostream* os) {
64113481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
64213481Sgiacomo.travaglini@arm.com}
64313481Sgiacomo.travaglini@arm.com
64413481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, typename T4, typename T5,
64513481Sgiacomo.travaglini@arm.com          typename T6, typename T7, typename T8>
64613481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
64713481Sgiacomo.travaglini@arm.com             ::std::ostream* os) {
64813481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
64913481Sgiacomo.travaglini@arm.com}
65013481Sgiacomo.travaglini@arm.com
65113481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, typename T4, typename T5,
65213481Sgiacomo.travaglini@arm.com          typename T6, typename T7, typename T8, typename T9>
65313481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
65413481Sgiacomo.travaglini@arm.com             ::std::ostream* os) {
65513481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
65613481Sgiacomo.travaglini@arm.com}
65713481Sgiacomo.travaglini@arm.com
65813481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, typename T4, typename T5,
65913481Sgiacomo.travaglini@arm.com          typename T6, typename T7, typename T8, typename T9, typename T10>
66013481Sgiacomo.travaglini@arm.comvoid PrintTo(
66113481Sgiacomo.travaglini@arm.com    const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
66213481Sgiacomo.travaglini@arm.com    ::std::ostream* os) {
66313481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
66413481Sgiacomo.travaglini@arm.com}
66513481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_TR1_TUPLE
66613481Sgiacomo.travaglini@arm.com
66713481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_TUPLE_
66813481Sgiacomo.travaglini@arm.comtemplate <typename... Types>
66913481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
67013481Sgiacomo.travaglini@arm.com  PrintTupleTo(t, os);
67113481Sgiacomo.travaglini@arm.com}
67213481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_STD_TUPLE_
67313481Sgiacomo.travaglini@arm.com
67413481Sgiacomo.travaglini@arm.com// Overload for std::pair.
67513481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2>
67613481Sgiacomo.travaglini@arm.comvoid PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
67713481Sgiacomo.travaglini@arm.com  *os << '(';
67813481Sgiacomo.travaglini@arm.com  // We cannot use UniversalPrint(value.first, os) here, as T1 may be
67913481Sgiacomo.travaglini@arm.com  // a reference type.  The same for printing value.second.
68013481Sgiacomo.travaglini@arm.com  UniversalPrinter<T1>::Print(value.first, os);
68113481Sgiacomo.travaglini@arm.com  *os << ", ";
68213481Sgiacomo.travaglini@arm.com  UniversalPrinter<T2>::Print(value.second, os);
68313481Sgiacomo.travaglini@arm.com  *os << ')';
68413481Sgiacomo.travaglini@arm.com}
68513481Sgiacomo.travaglini@arm.com
68613481Sgiacomo.travaglini@arm.com// Implements printing a non-reference type T by letting the compiler
68713481Sgiacomo.travaglini@arm.com// pick the right overload of PrintTo() for T.
68813481Sgiacomo.travaglini@arm.comtemplate <typename T>
68913481Sgiacomo.travaglini@arm.comclass UniversalPrinter {
69013481Sgiacomo.travaglini@arm.com public:
69113481Sgiacomo.travaglini@arm.com  // MSVC warns about adding const to a function type, so we want to
69213481Sgiacomo.travaglini@arm.com  // disable the warning.
69313481Sgiacomo.travaglini@arm.com  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
69413481Sgiacomo.travaglini@arm.com
69513481Sgiacomo.travaglini@arm.com  // Note: we deliberately don't call this PrintTo(), as that name
69613481Sgiacomo.travaglini@arm.com  // conflicts with ::testing::internal::PrintTo in the body of the
69713481Sgiacomo.travaglini@arm.com  // function.
69813481Sgiacomo.travaglini@arm.com  static void Print(const T& value, ::std::ostream* os) {
69913481Sgiacomo.travaglini@arm.com    // By default, ::testing::internal::PrintTo() is used for printing
70013481Sgiacomo.travaglini@arm.com    // the value.
70113481Sgiacomo.travaglini@arm.com    //
70213481Sgiacomo.travaglini@arm.com    // Thanks to Koenig look-up, if T is a class and has its own
70313481Sgiacomo.travaglini@arm.com    // PrintTo() function defined in its namespace, that function will
70413481Sgiacomo.travaglini@arm.com    // be visible here.  Since it is more specific than the generic ones
70513481Sgiacomo.travaglini@arm.com    // in ::testing::internal, it will be picked by the compiler in the
70613481Sgiacomo.travaglini@arm.com    // following statement - exactly what we want.
70713481Sgiacomo.travaglini@arm.com    PrintTo(value, os);
70813481Sgiacomo.travaglini@arm.com  }
70913481Sgiacomo.travaglini@arm.com
71013481Sgiacomo.travaglini@arm.com  GTEST_DISABLE_MSC_WARNINGS_POP_()
71113481Sgiacomo.travaglini@arm.com};
71213481Sgiacomo.travaglini@arm.com
71313481Sgiacomo.travaglini@arm.com// UniversalPrintArray(begin, len, os) prints an array of 'len'
71413481Sgiacomo.travaglini@arm.com// elements, starting at address 'begin'.
71513481Sgiacomo.travaglini@arm.comtemplate <typename T>
71613481Sgiacomo.travaglini@arm.comvoid UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
71713481Sgiacomo.travaglini@arm.com  if (len == 0) {
71813481Sgiacomo.travaglini@arm.com    *os << "{}";
71913481Sgiacomo.travaglini@arm.com  } else {
72013481Sgiacomo.travaglini@arm.com    *os << "{ ";
72113481Sgiacomo.travaglini@arm.com    const size_t kThreshold = 18;
72213481Sgiacomo.travaglini@arm.com    const size_t kChunkSize = 8;
72313481Sgiacomo.travaglini@arm.com    // If the array has more than kThreshold elements, we'll have to
72413481Sgiacomo.travaglini@arm.com    // omit some details by printing only the first and the last
72513481Sgiacomo.travaglini@arm.com    // kChunkSize elements.
72613481Sgiacomo.travaglini@arm.com    // TODO(wan@google.com): let the user control the threshold using a flag.
72713481Sgiacomo.travaglini@arm.com    if (len <= kThreshold) {
72813481Sgiacomo.travaglini@arm.com      PrintRawArrayTo(begin, len, os);
72913481Sgiacomo.travaglini@arm.com    } else {
73013481Sgiacomo.travaglini@arm.com      PrintRawArrayTo(begin, kChunkSize, os);
73113481Sgiacomo.travaglini@arm.com      *os << ", ..., ";
73213481Sgiacomo.travaglini@arm.com      PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
73313481Sgiacomo.travaglini@arm.com    }
73413481Sgiacomo.travaglini@arm.com    *os << " }";
73513481Sgiacomo.travaglini@arm.com  }
73613481Sgiacomo.travaglini@arm.com}
73713481Sgiacomo.travaglini@arm.com// This overload prints a (const) char array compactly.
73813481Sgiacomo.travaglini@arm.comGTEST_API_ void UniversalPrintArray(
73913481Sgiacomo.travaglini@arm.com    const char* begin, size_t len, ::std::ostream* os);
74013481Sgiacomo.travaglini@arm.com
74113481Sgiacomo.travaglini@arm.com// This overload prints a (const) wchar_t array compactly.
74213481Sgiacomo.travaglini@arm.comGTEST_API_ void UniversalPrintArray(
74313481Sgiacomo.travaglini@arm.com    const wchar_t* begin, size_t len, ::std::ostream* os);
74413481Sgiacomo.travaglini@arm.com
74513481Sgiacomo.travaglini@arm.com// Implements printing an array type T[N].
74613481Sgiacomo.travaglini@arm.comtemplate <typename T, size_t N>
74713481Sgiacomo.travaglini@arm.comclass UniversalPrinter<T[N]> {
74813481Sgiacomo.travaglini@arm.com public:
74913481Sgiacomo.travaglini@arm.com  // Prints the given array, omitting some elements when there are too
75013481Sgiacomo.travaglini@arm.com  // many.
75113481Sgiacomo.travaglini@arm.com  static void Print(const T (&a)[N], ::std::ostream* os) {
75213481Sgiacomo.travaglini@arm.com    UniversalPrintArray(a, N, os);
75313481Sgiacomo.travaglini@arm.com  }
75413481Sgiacomo.travaglini@arm.com};
75513481Sgiacomo.travaglini@arm.com
75613481Sgiacomo.travaglini@arm.com// Implements printing a reference type T&.
75713481Sgiacomo.travaglini@arm.comtemplate <typename T>
75813481Sgiacomo.travaglini@arm.comclass UniversalPrinter<T&> {
75913481Sgiacomo.travaglini@arm.com public:
76013481Sgiacomo.travaglini@arm.com  // MSVC warns about adding const to a function type, so we want to
76113481Sgiacomo.travaglini@arm.com  // disable the warning.
76213481Sgiacomo.travaglini@arm.com  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
76313481Sgiacomo.travaglini@arm.com
76413481Sgiacomo.travaglini@arm.com  static void Print(const T& value, ::std::ostream* os) {
76513481Sgiacomo.travaglini@arm.com    // Prints the address of the value.  We use reinterpret_cast here
76613481Sgiacomo.travaglini@arm.com    // as static_cast doesn't compile when T is a function type.
76713481Sgiacomo.travaglini@arm.com    *os << "@" << reinterpret_cast<const void*>(&value) << " ";
76813481Sgiacomo.travaglini@arm.com
76913481Sgiacomo.travaglini@arm.com    // Then prints the value itself.
77013481Sgiacomo.travaglini@arm.com    UniversalPrint(value, os);
77113481Sgiacomo.travaglini@arm.com  }
77213481Sgiacomo.travaglini@arm.com
77313481Sgiacomo.travaglini@arm.com  GTEST_DISABLE_MSC_WARNINGS_POP_()
77413481Sgiacomo.travaglini@arm.com};
77513481Sgiacomo.travaglini@arm.com
77613481Sgiacomo.travaglini@arm.com// Prints a value tersely: for a reference type, the referenced value
77713481Sgiacomo.travaglini@arm.com// (but not the address) is printed; for a (const) char pointer, the
77813481Sgiacomo.travaglini@arm.com// NUL-terminated string (but not the pointer) is printed.
77913481Sgiacomo.travaglini@arm.com
78013481Sgiacomo.travaglini@arm.comtemplate <typename T>
78113481Sgiacomo.travaglini@arm.comclass UniversalTersePrinter {
78213481Sgiacomo.travaglini@arm.com public:
78313481Sgiacomo.travaglini@arm.com  static void Print(const T& value, ::std::ostream* os) {
78413481Sgiacomo.travaglini@arm.com    UniversalPrint(value, os);
78513481Sgiacomo.travaglini@arm.com  }
78613481Sgiacomo.travaglini@arm.com};
78713481Sgiacomo.travaglini@arm.comtemplate <typename T>
78813481Sgiacomo.travaglini@arm.comclass UniversalTersePrinter<T&> {
78913481Sgiacomo.travaglini@arm.com public:
79013481Sgiacomo.travaglini@arm.com  static void Print(const T& value, ::std::ostream* os) {
79113481Sgiacomo.travaglini@arm.com    UniversalPrint(value, os);
79213481Sgiacomo.travaglini@arm.com  }
79313481Sgiacomo.travaglini@arm.com};
79413481Sgiacomo.travaglini@arm.comtemplate <typename T, size_t N>
79513481Sgiacomo.travaglini@arm.comclass UniversalTersePrinter<T[N]> {
79613481Sgiacomo.travaglini@arm.com public:
79713481Sgiacomo.travaglini@arm.com  static void Print(const T (&value)[N], ::std::ostream* os) {
79813481Sgiacomo.travaglini@arm.com    UniversalPrinter<T[N]>::Print(value, os);
79913481Sgiacomo.travaglini@arm.com  }
80013481Sgiacomo.travaglini@arm.com};
80113481Sgiacomo.travaglini@arm.comtemplate <>
80213481Sgiacomo.travaglini@arm.comclass UniversalTersePrinter<const char*> {
80313481Sgiacomo.travaglini@arm.com public:
80413481Sgiacomo.travaglini@arm.com  static void Print(const char* str, ::std::ostream* os) {
80513481Sgiacomo.travaglini@arm.com    if (str == NULL) {
80613481Sgiacomo.travaglini@arm.com      *os << "NULL";
80713481Sgiacomo.travaglini@arm.com    } else {
80813481Sgiacomo.travaglini@arm.com      UniversalPrint(string(str), os);
80913481Sgiacomo.travaglini@arm.com    }
81013481Sgiacomo.travaglini@arm.com  }
81113481Sgiacomo.travaglini@arm.com};
81213481Sgiacomo.travaglini@arm.comtemplate <>
81313481Sgiacomo.travaglini@arm.comclass UniversalTersePrinter<char*> {
81413481Sgiacomo.travaglini@arm.com public:
81513481Sgiacomo.travaglini@arm.com  static void Print(char* str, ::std::ostream* os) {
81613481Sgiacomo.travaglini@arm.com    UniversalTersePrinter<const char*>::Print(str, os);
81713481Sgiacomo.travaglini@arm.com  }
81813481Sgiacomo.travaglini@arm.com};
81913481Sgiacomo.travaglini@arm.com
82013481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_WSTRING
82113481Sgiacomo.travaglini@arm.comtemplate <>
82213481Sgiacomo.travaglini@arm.comclass UniversalTersePrinter<const wchar_t*> {
82313481Sgiacomo.travaglini@arm.com public:
82413481Sgiacomo.travaglini@arm.com  static void Print(const wchar_t* str, ::std::ostream* os) {
82513481Sgiacomo.travaglini@arm.com    if (str == NULL) {
82613481Sgiacomo.travaglini@arm.com      *os << "NULL";
82713481Sgiacomo.travaglini@arm.com    } else {
82813481Sgiacomo.travaglini@arm.com      UniversalPrint(::std::wstring(str), os);
82913481Sgiacomo.travaglini@arm.com    }
83013481Sgiacomo.travaglini@arm.com  }
83113481Sgiacomo.travaglini@arm.com};
83213481Sgiacomo.travaglini@arm.com#endif
83313481Sgiacomo.travaglini@arm.com
83413481Sgiacomo.travaglini@arm.comtemplate <>
83513481Sgiacomo.travaglini@arm.comclass UniversalTersePrinter<wchar_t*> {
83613481Sgiacomo.travaglini@arm.com public:
83713481Sgiacomo.travaglini@arm.com  static void Print(wchar_t* str, ::std::ostream* os) {
83813481Sgiacomo.travaglini@arm.com    UniversalTersePrinter<const wchar_t*>::Print(str, os);
83913481Sgiacomo.travaglini@arm.com  }
84013481Sgiacomo.travaglini@arm.com};
84113481Sgiacomo.travaglini@arm.com
84213481Sgiacomo.travaglini@arm.comtemplate <typename T>
84313481Sgiacomo.travaglini@arm.comvoid UniversalTersePrint(const T& value, ::std::ostream* os) {
84413481Sgiacomo.travaglini@arm.com  UniversalTersePrinter<T>::Print(value, os);
84513481Sgiacomo.travaglini@arm.com}
84613481Sgiacomo.travaglini@arm.com
84713481Sgiacomo.travaglini@arm.com// Prints a value using the type inferred by the compiler.  The
84813481Sgiacomo.travaglini@arm.com// difference between this and UniversalTersePrint() is that for a
84913481Sgiacomo.travaglini@arm.com// (const) char pointer, this prints both the pointer and the
85013481Sgiacomo.travaglini@arm.com// NUL-terminated string.
85113481Sgiacomo.travaglini@arm.comtemplate <typename T>
85213481Sgiacomo.travaglini@arm.comvoid UniversalPrint(const T& value, ::std::ostream* os) {
85313481Sgiacomo.travaglini@arm.com  // A workarond for the bug in VC++ 7.1 that prevents us from instantiating
85413481Sgiacomo.travaglini@arm.com  // UniversalPrinter with T directly.
85513481Sgiacomo.travaglini@arm.com  typedef T T1;
85613481Sgiacomo.travaglini@arm.com  UniversalPrinter<T1>::Print(value, os);
85713481Sgiacomo.travaglini@arm.com}
85813481Sgiacomo.travaglini@arm.com
85913481Sgiacomo.travaglini@arm.comtypedef ::std::vector<string> Strings;
86013481Sgiacomo.travaglini@arm.com
86113481Sgiacomo.travaglini@arm.com// TuplePolicy<TupleT> must provide:
86213481Sgiacomo.travaglini@arm.com// - tuple_size
86313481Sgiacomo.travaglini@arm.com//     size of tuple TupleT.
86413481Sgiacomo.travaglini@arm.com// - get<size_t I>(const TupleT& t)
86513481Sgiacomo.travaglini@arm.com//     static function extracting element I of tuple TupleT.
86613481Sgiacomo.travaglini@arm.com// - tuple_element<size_t I>::type
86713481Sgiacomo.travaglini@arm.com//     type of element I of tuple TupleT.
86813481Sgiacomo.travaglini@arm.comtemplate <typename TupleT>
86913481Sgiacomo.travaglini@arm.comstruct TuplePolicy;
87013481Sgiacomo.travaglini@arm.com
87113481Sgiacomo.travaglini@arm.com#if GTEST_HAS_TR1_TUPLE
87213481Sgiacomo.travaglini@arm.comtemplate <typename TupleT>
87313481Sgiacomo.travaglini@arm.comstruct TuplePolicy {
87413481Sgiacomo.travaglini@arm.com  typedef TupleT Tuple;
87513481Sgiacomo.travaglini@arm.com  static const size_t tuple_size = ::std::tr1::tuple_size<Tuple>::value;
87613481Sgiacomo.travaglini@arm.com
87713481Sgiacomo.travaglini@arm.com  template <size_t I>
87813481Sgiacomo.travaglini@arm.com  struct tuple_element : ::std::tr1::tuple_element<I, Tuple> {};
87913481Sgiacomo.travaglini@arm.com
88013481Sgiacomo.travaglini@arm.com  template <size_t I>
88113481Sgiacomo.travaglini@arm.com  static typename AddReference<
88213481Sgiacomo.travaglini@arm.com      const typename ::std::tr1::tuple_element<I, Tuple>::type>::type get(
88313481Sgiacomo.travaglini@arm.com      const Tuple& tuple) {
88413481Sgiacomo.travaglini@arm.com    return ::std::tr1::get<I>(tuple);
88513481Sgiacomo.travaglini@arm.com  }
88613481Sgiacomo.travaglini@arm.com};
88713481Sgiacomo.travaglini@arm.comtemplate <typename TupleT>
88813481Sgiacomo.travaglini@arm.comconst size_t TuplePolicy<TupleT>::tuple_size;
88913481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_TR1_TUPLE
89013481Sgiacomo.travaglini@arm.com
89113481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_TUPLE_
89213481Sgiacomo.travaglini@arm.comtemplate <typename... Types>
89313481Sgiacomo.travaglini@arm.comstruct TuplePolicy< ::std::tuple<Types...> > {
89413481Sgiacomo.travaglini@arm.com  typedef ::std::tuple<Types...> Tuple;
89513481Sgiacomo.travaglini@arm.com  static const size_t tuple_size = ::std::tuple_size<Tuple>::value;
89613481Sgiacomo.travaglini@arm.com
89713481Sgiacomo.travaglini@arm.com  template <size_t I>
89813481Sgiacomo.travaglini@arm.com  struct tuple_element : ::std::tuple_element<I, Tuple> {};
89913481Sgiacomo.travaglini@arm.com
90013481Sgiacomo.travaglini@arm.com  template <size_t I>
90113481Sgiacomo.travaglini@arm.com  static const typename ::std::tuple_element<I, Tuple>::type& get(
90213481Sgiacomo.travaglini@arm.com      const Tuple& tuple) {
90313481Sgiacomo.travaglini@arm.com    return ::std::get<I>(tuple);
90413481Sgiacomo.travaglini@arm.com  }
90513481Sgiacomo.travaglini@arm.com};
90613481Sgiacomo.travaglini@arm.comtemplate <typename... Types>
90713481Sgiacomo.travaglini@arm.comconst size_t TuplePolicy< ::std::tuple<Types...> >::tuple_size;
90813481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_STD_TUPLE_
90913481Sgiacomo.travaglini@arm.com
91013481Sgiacomo.travaglini@arm.com#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
91113481Sgiacomo.travaglini@arm.com// This helper template allows PrintTo() for tuples and
91213481Sgiacomo.travaglini@arm.com// UniversalTersePrintTupleFieldsToStrings() to be defined by
91313481Sgiacomo.travaglini@arm.com// induction on the number of tuple fields.  The idea is that
91413481Sgiacomo.travaglini@arm.com// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
91513481Sgiacomo.travaglini@arm.com// fields in tuple t, and can be defined in terms of
91613481Sgiacomo.travaglini@arm.com// TuplePrefixPrinter<N - 1>.
91713481Sgiacomo.travaglini@arm.com//
91813481Sgiacomo.travaglini@arm.com// The inductive case.
91913481Sgiacomo.travaglini@arm.comtemplate <size_t N>
92013481Sgiacomo.travaglini@arm.comstruct TuplePrefixPrinter {
92113481Sgiacomo.travaglini@arm.com  // Prints the first N fields of a tuple.
92213481Sgiacomo.travaglini@arm.com  template <typename Tuple>
92313481Sgiacomo.travaglini@arm.com  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
92413481Sgiacomo.travaglini@arm.com    TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
92513481Sgiacomo.travaglini@arm.com    GTEST_INTENTIONAL_CONST_COND_PUSH_()
92613481Sgiacomo.travaglini@arm.com    if (N > 1) {
92713481Sgiacomo.travaglini@arm.com    GTEST_INTENTIONAL_CONST_COND_POP_()
92813481Sgiacomo.travaglini@arm.com      *os << ", ";
92913481Sgiacomo.travaglini@arm.com    }
93013481Sgiacomo.travaglini@arm.com    UniversalPrinter<
93113481Sgiacomo.travaglini@arm.com        typename TuplePolicy<Tuple>::template tuple_element<N - 1>::type>
93213481Sgiacomo.travaglini@arm.com        ::Print(TuplePolicy<Tuple>::template get<N - 1>(t), os);
93313481Sgiacomo.travaglini@arm.com  }
93413481Sgiacomo.travaglini@arm.com
93513481Sgiacomo.travaglini@arm.com  // Tersely prints the first N fields of a tuple to a string vector,
93613481Sgiacomo.travaglini@arm.com  // one element for each field.
93713481Sgiacomo.travaglini@arm.com  template <typename Tuple>
93813481Sgiacomo.travaglini@arm.com  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
93913481Sgiacomo.travaglini@arm.com    TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
94013481Sgiacomo.travaglini@arm.com    ::std::stringstream ss;
94113481Sgiacomo.travaglini@arm.com    UniversalTersePrint(TuplePolicy<Tuple>::template get<N - 1>(t), &ss);
94213481Sgiacomo.travaglini@arm.com    strings->push_back(ss.str());
94313481Sgiacomo.travaglini@arm.com  }
94413481Sgiacomo.travaglini@arm.com};
94513481Sgiacomo.travaglini@arm.com
94613481Sgiacomo.travaglini@arm.com// Base case.
94713481Sgiacomo.travaglini@arm.comtemplate <>
94813481Sgiacomo.travaglini@arm.comstruct TuplePrefixPrinter<0> {
94913481Sgiacomo.travaglini@arm.com  template <typename Tuple>
95013481Sgiacomo.travaglini@arm.com  static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
95113481Sgiacomo.travaglini@arm.com
95213481Sgiacomo.travaglini@arm.com  template <typename Tuple>
95313481Sgiacomo.travaglini@arm.com  static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
95413481Sgiacomo.travaglini@arm.com};
95513481Sgiacomo.travaglini@arm.com
95613481Sgiacomo.travaglini@arm.com// Helper function for printing a tuple.
95713481Sgiacomo.travaglini@arm.com// Tuple must be either std::tr1::tuple or std::tuple type.
95813481Sgiacomo.travaglini@arm.comtemplate <typename Tuple>
95913481Sgiacomo.travaglini@arm.comvoid PrintTupleTo(const Tuple& t, ::std::ostream* os) {
96013481Sgiacomo.travaglini@arm.com  *os << "(";
96113481Sgiacomo.travaglini@arm.com  TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::PrintPrefixTo(t, os);
96213481Sgiacomo.travaglini@arm.com  *os << ")";
96313481Sgiacomo.travaglini@arm.com}
96413481Sgiacomo.travaglini@arm.com
96513481Sgiacomo.travaglini@arm.com// Prints the fields of a tuple tersely to a string vector, one
96613481Sgiacomo.travaglini@arm.com// element for each field.  See the comment before
96713481Sgiacomo.travaglini@arm.com// UniversalTersePrint() for how we define "tersely".
96813481Sgiacomo.travaglini@arm.comtemplate <typename Tuple>
96913481Sgiacomo.travaglini@arm.comStrings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
97013481Sgiacomo.travaglini@arm.com  Strings result;
97113481Sgiacomo.travaglini@arm.com  TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::
97213481Sgiacomo.travaglini@arm.com      TersePrintPrefixToStrings(value, &result);
97313481Sgiacomo.travaglini@arm.com  return result;
97413481Sgiacomo.travaglini@arm.com}
97513481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
97613481Sgiacomo.travaglini@arm.com
97713481Sgiacomo.travaglini@arm.com}  // namespace internal
97813481Sgiacomo.travaglini@arm.com
97913481Sgiacomo.travaglini@arm.comtemplate <typename T>
98013481Sgiacomo.travaglini@arm.com::std::string PrintToString(const T& value) {
98113481Sgiacomo.travaglini@arm.com  ::std::stringstream ss;
98213481Sgiacomo.travaglini@arm.com  internal::UniversalTersePrinter<T>::Print(value, &ss);
98313481Sgiacomo.travaglini@arm.com  return ss.str();
98413481Sgiacomo.travaglini@arm.com}
98513481Sgiacomo.travaglini@arm.com
98613481Sgiacomo.travaglini@arm.com}  // namespace testing
98713481Sgiacomo.travaglini@arm.com
98813481Sgiacomo.travaglini@arm.com// Include any custom printer added by the local installation.
98913481Sgiacomo.travaglini@arm.com// We must include this header at the end to make sure it can use the
99013481Sgiacomo.travaglini@arm.com// declarations from this file.
99113481Sgiacomo.travaglini@arm.com#include "gtest/internal/custom/gtest-printers.h"
99213481Sgiacomo.travaglini@arm.com
99313481Sgiacomo.travaglini@arm.com#endif  // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
994