blob: 28e904c33c962f926e72f47e4f77788eacaff8a1 [file] [log] [blame]
shiqiane35fdd92008-12-10 05:08:54 +00001// Copyright 2007, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Author: wan@google.com (Zhanyong Wan)
31
32// Google Mock - a framework for writing C++ mock classes.
33//
34// This file implements a universal value printer that can print a
35// value of any type T:
36//
37// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
38//
39// It uses the << operator when possible, and prints the bytes in the
40// object otherwise. A user can override its behavior for a class
41// type Foo by defining either operator<<(::std::ostream&, const Foo&)
42// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
43// defines Foo. If both are defined, PrintTo() takes precedence.
zhanyong.wan4a5330d2009-02-19 00:36:44 +000044//
45// To aid debugging: when T is a reference type, the address of the
46// value is also printed; when T is a (const) char pointer, both the
47// pointer value and the NUL-terminated string it points to are
shiqiane35fdd92008-12-10 05:08:54 +000048// printed.
49//
zhanyong.wance198ff2009-02-12 01:34:27 +000050// We also provide some convenient wrappers:
shiqiane35fdd92008-12-10 05:08:54 +000051//
zhanyong.wan4a5330d2009-02-19 00:36:44 +000052// // Prints a value as the given type to a string.
53// string ::testing::internal::UniversalPrinter<T>::PrintToString(value);
54//
55// // Prints a value tersely: for a reference type, the referenced
56// // value (but not the address) is printed; for a (const) char
57// // pointer, the NUL-terminated string (but not the pointer) is
58// // printed.
59// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
60//
61// // Prints the fields of a tuple tersely to a string vector, one
62// // element for each field.
63// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
64// const Tuple& value);
shiqiane35fdd92008-12-10 05:08:54 +000065
66#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
67#define GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_
68
69#include <ostream> // NOLINT
zhanyong.wan4a5330d2009-02-19 00:36:44 +000070#include <sstream>
shiqiane35fdd92008-12-10 05:08:54 +000071#include <string>
72#include <utility>
zhanyong.wan4a5330d2009-02-19 00:36:44 +000073#include <vector>
shiqiane35fdd92008-12-10 05:08:54 +000074
75#include <gmock/internal/gmock-internal-utils.h>
76#include <gmock/internal/gmock-port.h>
77#include <gtest/gtest.h>
78
79// Makes sure there is at least one << operator declared in the global
80// namespace. This has no implementation and won't be called
81// anywhere. We just need the declaration such that we can say "using
82// ::operator <<;" in the definition of PrintTo() below.
83void operator<<(::testing::internal::Unused, int);
84
85namespace testing {
86
87// Definitions in the 'internal' and 'internal2' name spaces are
88// subject to change without notice. DO NOT USE THEM IN USER CODE!
89namespace internal2 {
90
91// Prints the given number of bytes in the given object to the given
92// ostream.
93void PrintBytesInObjectTo(const unsigned char* obj_bytes,
94 size_t count,
95 ::std::ostream* os);
96
97// TypeWithoutFormatter<T, kIsProto>::PrintValue(value, os) is called
98// by the universal printer to print a value of type T when neither
99// operator<< nor PrintTo() is defined for type T. When T is
100// ProtocolMessage, proto2::Message, or a subclass of those, kIsProto
101// will be true and the short debug string of the protocol message
102// value will be printed; otherwise kIsProto will be false and the
103// bytes in the value will be printed.
104template <typename T, bool kIsProto>
105class TypeWithoutFormatter {
106 public:
107 static void PrintValue(const T& value, ::std::ostream* os) {
108 PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
109 sizeof(value), os);
110 }
111};
112template <typename T>
113class TypeWithoutFormatter<T, true> {
114 public:
115 static void PrintValue(const T& value, ::std::ostream* os) {
116 // Both ProtocolMessage and proto2::Message have the
117 // ShortDebugString() method, so the same implementation works for
118 // both.
119 ::std::operator<<(*os, "<" + value.ShortDebugString() + ">");
120 }
121};
122
123// Prints the given value to the given ostream. If the value is a
124// protocol message, its short debug string is printed; otherwise the
125// bytes in the value are printed. This is what
126// UniversalPrinter<T>::Print() does when it knows nothing about type
127// T and T has no << operator.
128//
129// A user can override this behavior for a class type Foo by defining
130// a << operator in the namespace where Foo is defined.
131//
132// We put this operator in namespace 'internal2' instead of 'internal'
133// to simplify the implementation, as much code in 'internal' needs to
134// use << in STL, which would conflict with our own << were it defined
135// in 'internal'.
zhanyong.wan2f0849f2009-02-11 18:06:37 +0000136//
137// Note that this operator<< takes a generic std::basic_ostream<Char,
138// CharTraits> type instead of the more restricted std::ostream. If
139// we define it to take an std::ostream instead, we'll get an
140// "ambiguous overloads" compiler error when trying to print a type
141// Foo that supports streaming to std::basic_ostream<Char,
142// CharTraits>, as the compiler cannot tell whether
143// operator<<(std::ostream&, const T&) or
144// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
145// specific.
146template <typename Char, typename CharTraits, typename T>
147::std::basic_ostream<Char, CharTraits>& operator<<(
148 ::std::basic_ostream<Char, CharTraits>& os, const T& x) {
shiqiane35fdd92008-12-10 05:08:54 +0000149 TypeWithoutFormatter<T, ::testing::internal::IsAProtocolMessage<T>::value>::
150 PrintValue(x, &os);
151 return os;
152}
153
154} // namespace internal2
155
156namespace internal {
157
158// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
159// value to the given ostream. The caller must ensure that
160// 'ostream_ptr' is not NULL, or the behavior is undefined.
161//
162// We define UniversalPrinter as a class template (as opposed to a
163// function template), as we need to partially specialize it for
164// reference types, which cannot be done with function templates.
165template <typename T>
166class UniversalPrinter;
167
168// Used to print an STL-style container when the user doesn't define
169// a PrintTo() for it.
170template <typename C>
171void DefaultPrintTo(IsContainer, const C& container, ::std::ostream* os) {
172 const size_t kMaxCount = 32; // The maximum number of elements to print.
173 *os << '{';
174 size_t count = 0;
175 for (typename C::const_iterator it = container.begin();
176 it != container.end(); ++it, ++count) {
177 if (count > 0) {
178 *os << ',';
179 if (count == kMaxCount) { // Enough has been printed.
180 *os << " ...";
181 break;
182 }
183 }
184 *os << ' ';
185 PrintTo(*it, os);
186 }
187
188 if (count > 0) {
189 *os << ' ';
190 }
191 *os << '}';
192}
193
194// Used to print a value when the user doesn't define PrintTo() for it.
195template <typename T>
196void DefaultPrintTo(IsNotContainer, const T& value, ::std::ostream* os) {
197 // If T has its << operator defined in the global namespace, which
198 // is not recommended but sometimes unavoidable (as in
199 // util/gtl/stl_logging-inl.h), the following statement makes it
200 // visible in this function.
201 //
202 // Without the statement, << in the global namespace would be hidden
203 // by the one in ::testing::internal2, due to the next using
204 // statement.
205 using ::operator <<;
206
207 // When T doesn't come with a << operator, we want to fall back to
208 // the one defined in ::testing::internal2, which prints the bytes in
209 // the value.
210 using ::testing::internal2::operator <<;
211
212 // Thanks to Koenig look-up, if type T has its own << operator
213 // defined in its namespace, which is the recommended way, that
214 // operator will be visible here. Since it is more specific than
215 // the generic one, it will be picked by the compiler in the
216 // following statement - exactly what we want.
217 *os << value;
218}
219
220// Prints the given value using the << operator if it has one;
221// otherwise prints the bytes in it. This is what
222// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
223// or overloaded for type T.
224//
225// A user can override this behavior for a class type Foo by defining
226// an overload of PrintTo() in the namespace where Foo is defined. We
227// give the user this option as sometimes defining a << operator for
228// Foo is not desirable (e.g. the coding style may prevent doing it,
229// or there is already a << operator but it doesn't do what the user
230// wants).
231template <typename T>
232void PrintTo(const T& value, ::std::ostream* os) {
233 // DefaultPrintTo() is overloaded. The type of its first argument
234 // determines which version will be picked. If T is an STL-style
235 // container, the version for container will be called. Otherwise
236 // the generic version will be called.
237 //
238 // Note that we check for container types here, prior to we check
239 // for protocol message types in our operator<<. The rationale is:
240 //
241 // For protocol messages, we want to give people a chance to
242 // override Google Mock's format by defining a PrintTo() or
243 // operator<<. For STL containers, we believe the Google Mock's
244 // format is superior to what util/gtl/stl-logging.h offers.
245 // Therefore we don't want it to be accidentally overridden by the
246 // latter (even if the user includes stl-logging.h through other
247 // headers indirectly, Google Mock's format will still be used).
248 DefaultPrintTo(IsContainerTest<T>(0), value, os);
249}
250
251// The following list of PrintTo() overloads tells
252// UniversalPrinter<T>::Print() how to print standard types (built-in
253// types, strings, plain arrays, and pointers).
254
255// Overloads for various char types.
256void PrintCharTo(char c, int char_code, ::std::ostream* os);
257inline void PrintTo(unsigned char c, ::std::ostream* os) {
258 PrintCharTo(c, c, os);
259}
260inline void PrintTo(signed char c, ::std::ostream* os) {
261 PrintCharTo(c, c, os);
262}
263inline void PrintTo(char c, ::std::ostream* os) {
264 // When printing a plain char, we always treat it as unsigned. This
265 // way, the output won't be affected by whether the compiler thinks
266 // char is signed or not.
267 PrintTo(static_cast<unsigned char>(c), os);
268}
269
270// Overloads for other simple built-in types.
271inline void PrintTo(bool x, ::std::ostream* os) {
272 *os << (x ? "true" : "false");
273}
274
275// Overload for wchar_t type.
276// Prints a wchar_t as a symbol if it is printable or as its internal
277// code otherwise and also as its decimal code (except for L'\0').
278// The L'\0' char is printed as "L'\\0'". The decimal code is printed
279// as signed integer when wchar_t is implemented by the compiler
280// as a signed type and is printed as an unsigned integer when wchar_t
281// is implemented as an unsigned type.
282void PrintTo(wchar_t wc, ::std::ostream* os);
283
284// Overloads for C strings.
285void PrintTo(const char* s, ::std::ostream* os);
286inline void PrintTo(char* s, ::std::ostream* os) {
287 PrintTo(implicit_cast<const char*>(s), os);
288}
289
290// MSVC compiler can be configured to define whar_t as a typedef
291// of unsigned short. Defining an overload for const wchar_t* in that case
292// would cause pointers to unsigned shorts be printed as wide strings,
293// possibly accessing more memory than intended and causing invalid
294// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
295// wchar_t is implemented as a native type.
296#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
297// Overloads for wide C strings
298void PrintTo(const wchar_t* s, ::std::ostream* os);
299inline void PrintTo(wchar_t* s, ::std::ostream* os) {
300 PrintTo(implicit_cast<const wchar_t*>(s), os);
301}
302#endif
303
304// Overload for pointers that are neither char pointers nor member
305// pointers. (A member variable pointer or member function pointer
306// doesn't really points to a location in the address space. Their
307// representation is implementation-defined. Therefore they will be
308// printed as raw bytes.)
309template <typename T>
310void PrintTo(T* p, ::std::ostream* os) {
311 if (p == NULL) {
312 *os << "NULL";
313 } else {
314 // We cannot use implicit_cast or static_cast here, as they don't
315 // work when p is a function pointer.
316 *os << reinterpret_cast<const void*>(p);
317 }
318}
319
320// Overload for C arrays. Multi-dimensional arrays are printed
321// properly.
322
323// Prints the given number of elements in an array, without printing
324// the curly braces.
325template <typename T>
326void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
327 UniversalPrinter<T>::Print(a[0], os);
328 for (size_t i = 1; i != count; i++) {
329 *os << ", ";
330 UniversalPrinter<T>::Print(a[i], os);
331 }
332}
333
334// Overloads for ::string and ::std::string.
335#if GTEST_HAS_GLOBAL_STRING
336void PrintStringTo(const ::string&s, ::std::ostream* os);
337inline void PrintTo(const ::string& s, ::std::ostream* os) {
338 PrintStringTo(s, os);
339}
340#endif // GTEST_HAS_GLOBAL_STRING
341
342#if GTEST_HAS_STD_STRING
343void PrintStringTo(const ::std::string&s, ::std::ostream* os);
344inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
345 PrintStringTo(s, os);
346}
347#endif // GTEST_HAS_STD_STRING
348
349// Overloads for ::wstring and ::std::wstring.
350#if GTEST_HAS_GLOBAL_WSTRING
351void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
352inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
353 PrintWideStringTo(s, os);
354}
355#endif // GTEST_HAS_GLOBAL_WSTRING
356
357#if GTEST_HAS_STD_WSTRING
358void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
359inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
360 PrintWideStringTo(s, os);
361}
362#endif // GTEST_HAS_STD_WSTRING
363
364// Overload for ::std::tr1::tuple. Needed for printing function
365// arguments, which are packed as tuples.
366
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000367typedef ::std::vector<string> Strings;
368
369// This helper template allows PrintTo() for tuples and
370// UniversalTersePrintTupleFieldsToStrings() to be defined by
shiqiane35fdd92008-12-10 05:08:54 +0000371// induction on the number of tuple fields. The idea is that
372// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
373// fields in tuple t, and can be defined in terms of
374// TuplePrefixPrinter<N - 1>.
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000375
376// The inductive case.
shiqiane35fdd92008-12-10 05:08:54 +0000377template <size_t N>
378struct TuplePrefixPrinter {
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000379 // Prints the first N fields of a tuple.
shiqiane35fdd92008-12-10 05:08:54 +0000380 template <typename Tuple>
381 static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
382 TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
383 *os << ", ";
384 UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
385 ::Print(::std::tr1::get<N - 1>(t), os);
386 }
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000387
388 // Tersely prints the first N fields of a tuple to a string vector,
389 // one element for each field.
390 template <typename Tuple>
391 static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
392 TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
393 ::std::stringstream ss;
394 UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss);
395 strings->push_back(ss.str());
396 }
shiqiane35fdd92008-12-10 05:08:54 +0000397};
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000398
399// Base cases.
shiqiane35fdd92008-12-10 05:08:54 +0000400template <>
401struct TuplePrefixPrinter<0> {
402 template <typename Tuple>
403 static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000404
405 template <typename Tuple>
406 static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
shiqiane35fdd92008-12-10 05:08:54 +0000407};
408template <>
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000409template <typename Tuple>
410void TuplePrefixPrinter<1>::PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
411 UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
412 Print(::std::tr1::get<0>(t), os);
413}
shiqiane35fdd92008-12-10 05:08:54 +0000414
shiqianc97f2f52008-12-11 17:22:59 +0000415// Helper function for printing a tuple. T must be instantiated with
416// a tuple type.
417template <typename T>
418void PrintTupleTo(const T& t, ::std::ostream* os) {
419 *os << "(";
420 TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>::
421 PrintPrefixTo(t, os);
422 *os << ")";
423}
424
425// Overloaded PrintTo() for tuples of various arities. We support
426// tuples of up-to 10 fields. The following implementation works
427// regardless of whether tr1::tuple is implemented using the
428// non-standard variadic template feature or not.
429
430inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
431 PrintTupleTo(t, os);
432}
433
434template <typename T1>
435void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
436 PrintTupleTo(t, os);
437}
438
439template <typename T1, typename T2>
440void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
441 PrintTupleTo(t, os);
442}
443
444template <typename T1, typename T2, typename T3>
445void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
446 PrintTupleTo(t, os);
447}
448
449template <typename T1, typename T2, typename T3, typename T4>
450void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
451 PrintTupleTo(t, os);
452}
453
454template <typename T1, typename T2, typename T3, typename T4, typename T5>
455void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
456 ::std::ostream* os) {
457 PrintTupleTo(t, os);
458}
459
460template <typename T1, typename T2, typename T3, typename T4, typename T5,
461 typename T6>
462void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
463 ::std::ostream* os) {
464 PrintTupleTo(t, os);
465}
466
467template <typename T1, typename T2, typename T3, typename T4, typename T5,
468 typename T6, typename T7>
469void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
470 ::std::ostream* os) {
471 PrintTupleTo(t, os);
472}
473
474template <typename T1, typename T2, typename T3, typename T4, typename T5,
475 typename T6, typename T7, typename T8>
476void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
477 ::std::ostream* os) {
478 PrintTupleTo(t, os);
479}
480
481template <typename T1, typename T2, typename T3, typename T4, typename T5,
482 typename T6, typename T7, typename T8, typename T9>
483void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
484 ::std::ostream* os) {
485 PrintTupleTo(t, os);
486}
487
shiqiane35fdd92008-12-10 05:08:54 +0000488template <typename T1, typename T2, typename T3, typename T4, typename T5,
489 typename T6, typename T7, typename T8, typename T9, typename T10>
490void PrintTo(
491 const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
492 ::std::ostream* os) {
shiqianc97f2f52008-12-11 17:22:59 +0000493 PrintTupleTo(t, os);
shiqiane35fdd92008-12-10 05:08:54 +0000494}
495
496// Overload for std::pair.
497template <typename T1, typename T2>
498void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
499 *os << '(';
500 UniversalPrinter<T1>::Print(value.first, os);
501 *os << ", ";
502 UniversalPrinter<T2>::Print(value.second, os);
503 *os << ')';
504}
505
506// Implements printing a non-reference type T by letting the compiler
507// pick the right overload of PrintTo() for T.
508template <typename T>
509class UniversalPrinter {
510 public:
511 // MSVC warns about adding const to a function type, so we want to
512 // disable the warning.
513#ifdef _MSC_VER
514#pragma warning(push) // Saves the current warning state.
515#pragma warning(disable:4180) // Temporarily disables warning 4180.
516#endif // _MSC_VER
517
518 // Note: we deliberately don't call this PrintTo(), as that name
519 // conflicts with ::testing::internal::PrintTo in the body of the
520 // function.
521 static void Print(const T& value, ::std::ostream* os) {
522 // By default, ::testing::internal::PrintTo() is used for printing
523 // the value.
524 //
525 // Thanks to Koenig look-up, if T is a class and has its own
526 // PrintTo() function defined in its namespace, that function will
527 // be visible here. Since it is more specific than the generic ones
528 // in ::testing::internal, it will be picked by the compiler in the
529 // following statement - exactly what we want.
530 PrintTo(value, os);
531 }
532
533 // A convenient wrapper for Print() that returns the print-out as a
534 // string.
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000535 static string PrintToString(const T& value) {
shiqiane35fdd92008-12-10 05:08:54 +0000536 ::std::stringstream ss;
537 Print(value, &ss);
538 return ss.str();
539 }
540
541#ifdef _MSC_VER
542#pragma warning(pop) // Restores the warning state.
543#endif // _MSC_VER
544};
545
546// Implements printing an array type T[N].
547template <typename T, size_t N>
548class UniversalPrinter<T[N]> {
549 public:
550 // Prints the given array, omitting some elements when there are too
551 // many.
552 static void Print(const T (&a)[N], ::std::ostream* os) {
553 // Prints a char array as a C string. Note that we compare 'const
554 // T' with 'const char' instead of comparing T with char, in case
555 // that T is already a const type.
556 if (internal::type_equals<const T, const char>::value) {
557 UniversalPrinter<const T*>::Print(a, os);
558 return;
559 }
560
561 if (N == 0) {
562 *os << "{}";
563 } else {
564 *os << "{ ";
565 const size_t kThreshold = 18;
566 const size_t kChunkSize = 8;
567 // If the array has more than kThreshold elements, we'll have to
568 // omit some details by printing only the first and the last
569 // kChunkSize elements.
570 // TODO(wan): let the user control the threshold using a flag.
571 if (N <= kThreshold) {
572 PrintRawArrayTo(a, N, os);
573 } else {
574 PrintRawArrayTo(a, kChunkSize, os);
575 *os << ", ..., ";
576 PrintRawArrayTo(a + N - kChunkSize, kChunkSize, os);
577 }
578 *os << " }";
579 }
580 }
581
582 // A convenient wrapper for Print() that returns the print-out as a
583 // string.
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000584 static string PrintToString(const T (&a)[N]) {
shiqiane35fdd92008-12-10 05:08:54 +0000585 ::std::stringstream ss;
586 Print(a, &ss);
587 return ss.str();
588 }
589};
590
591// Implements printing a reference type T&.
592template <typename T>
593class UniversalPrinter<T&> {
594 public:
595 // MSVC warns about adding const to a function type, so we want to
596 // disable the warning.
597#ifdef _MSC_VER
598#pragma warning(push) // Saves the current warning state.
599#pragma warning(disable:4180) // Temporarily disables warning 4180.
600#endif // _MSC_VER
601
602 static void Print(const T& value, ::std::ostream* os) {
603 // Prints the address of the value. We use reinterpret_cast here
604 // as static_cast doesn't compile when T is a function type.
605 *os << "@" << reinterpret_cast<const void*>(&value) << " ";
606
607 // Then prints the value itself.
608 UniversalPrinter<T>::Print(value, os);
609 }
610
611 // A convenient wrapper for Print() that returns the print-out as a
612 // string.
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000613 static string PrintToString(const T& value) {
shiqiane35fdd92008-12-10 05:08:54 +0000614 ::std::stringstream ss;
615 Print(value, &ss);
616 return ss.str();
617 }
618
619#ifdef _MSC_VER
620#pragma warning(pop) // Restores the warning state.
621#endif // _MSC_VER
622};
623
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000624// Prints a value tersely: for a reference type, the referenced value
625// (but not the address) is printed; for a (const) char pointer, the
626// NUL-terminated string (but not the pointer) is printed.
zhanyong.wance198ff2009-02-12 01:34:27 +0000627template <typename T>
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000628void UniversalTersePrint(const T& value, ::std::ostream* os) {
zhanyong.wance198ff2009-02-12 01:34:27 +0000629 UniversalPrinter<T>::Print(value, os);
630}
zhanyong.wan4a5330d2009-02-19 00:36:44 +0000631inline void UniversalTersePrint(const char* str, ::std::ostream* os) {
632 if (str == NULL) {
633 *os << "NULL";
634 } else {
635 UniversalPrinter<string>::Print(string(str), os);
636 }
637}
638inline void UniversalTersePrint(char* str, ::std::ostream* os) {
639 UniversalTersePrint(static_cast<const char*>(str), os);
640}
641
642// Prints the fields of a tuple tersely to a string vector, one
643// element for each field. See the comment before
644// UniversalTersePrint() for how we define "tersely".
645template <typename Tuple>
646Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
647 Strings result;
648 TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
649 TersePrintPrefixToStrings(value, &result);
650 return result;
651}
zhanyong.wance198ff2009-02-12 01:34:27 +0000652
shiqiane35fdd92008-12-10 05:08:54 +0000653} // namespace internal
654} // namespace testing
655
656#endif // GMOCK_INCLUDE_GMOCK_GMOCK_PRINTERS_H_