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