1dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Copyright 2005, Google Inc.
2dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// All rights reserved.
3dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
4dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Redistribution and use in source and binary forms, with or without
5dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// modification, are permitted provided that the following conditions are
6dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// met:
7dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
8dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Redistributions of source code must retain the above copyright
9dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// notice, this list of conditions and the following disclaimer.
10dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Redistributions in binary form must reproduce the above
11dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// copyright notice, this list of conditions and the following disclaimer
12dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// in the documentation and/or other materials provided with the
13dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// distribution.
14dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Neither the name of Google Inc. nor the names of its
15dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// contributors may be used to endorse or promote products derived from
16dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// this software without specific prior written permission.
17dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
18dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
30dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Author: wan@google.com (Zhanyong Wan)
31dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
32dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// The Google C++ Testing Framework (Google Test)
33dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
34dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// This header file defines the Message class.
35dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
36dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
37dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// leave some internal implementation details in this header file.
38dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// They are clearly marked by comments like this:
39dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
40dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
41dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
42dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Such code is NOT meant to be used by a user directly, and is subject
43dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
44dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// program!
45dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
46dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
47dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
48dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
4946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan#include <limits>
5046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
5146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan#include "gtest/internal/gtest-string.h"
5246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan#include "gtest/internal/gtest-internal.h"
53dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
54dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixternamespace testing {
55dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
56dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// The Message class works like an ostream repeater.
57dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
58dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Typical usage:
59dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
60dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//   1. You stream a bunch of values to a Message object.
6146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan//      It will remember the text in a stringstream.
62dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//   2. Then you stream the Message object to an ostream.
63dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//      This causes the text in the Message to be streamed
64dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//      to the ostream.
65dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
66dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// For example;
67dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
68dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//   testing::Message foo;
69dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//   foo << 1 << " != " << 2;
70dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//   std::cout << foo;
71dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
72dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// will print "1 != 2".
73dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
74dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Message is not intended to be inherited from.  In particular, its
75dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// destructor is not virtual.
76dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
7746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan// Note that stringstream behaves differently in gcc and in MSVC.  You
78dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// can stream a NULL char pointer to it in the former, but not in the
79dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// latter (it causes an access violation if you do).  The Message
80dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// class hides this difference by treating a NULL char pointer as
81dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// "(null)".
8246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chanclass GTEST_API_ Message {
83dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter private:
84dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // The type of basic IO manipulators (endl, ends, and flush) for
85dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // narrow streams.
86dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
87dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
88dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter public:
89dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Constructs an empty Message.
9046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  // We allocate the stringstream separately because otherwise each use of
91dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
92dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // stack frame leading to huge stack frames in some cases; gcc does not reuse
93dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // the stack space.
9446108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  Message() : ss_(new ::std::stringstream) {
9546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    // By default, we want there to be enough precision when printing
9646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    // a double to a Message.
9746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
9846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  }
99dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
100dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Copy constructor.
10146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  Message(const Message& msg) : ss_(new ::std::stringstream) {  // NOLINT
102dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    *ss_ << msg.GetString();
103dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
104dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
105dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Constructs a Message from a C-string.
10646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  explicit Message(const char* str) : ss_(new ::std::stringstream) {
107dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    *ss_ << str;
108dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
109dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
110dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#if GTEST_OS_SYMBIAN
111dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Streams a value (either a pointer or not) to this object.
112dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  template <typename T>
113dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  inline Message& operator <<(const T& value) {
114dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    StreamHelper(typename internal::is_pointer<T>::type(), value);
115dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return *this;
116dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
117dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#else
118dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Streams a non-pointer value to this object.
119dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  template <typename T>
120dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  inline Message& operator <<(const T& val) {
12146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    ::GTestStreamToHelper(ss_.get(), val);
122dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return *this;
123dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
124dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
125dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Streams a pointer value to this object.
126dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  //
127dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // This function is an overload of the previous one.  When you
128dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // stream a pointer to a Message, this definition will be used as it
129dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // is more specialized.  (The C++ Standard, section
130dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // [temp.func.order].)  If you stream a non-pointer, then the
131dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // previous definition will be used.
132dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  //
133dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // The reason for this overload is that streaming a NULL pointer to
134dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // ostream is undefined behavior.  Depending on the compiler, you
135dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // may get "0", "(nil)", "(null)", or an access violation.  To
136dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // ensure consistent result across compilers, we always treat NULL
137dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // as "(null)".
138dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  template <typename T>
139dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  inline Message& operator <<(T* const& pointer) {  // NOLINT
140dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (pointer == NULL) {
141dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      *ss_ << "(null)";
142dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    } else {
14346108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      ::GTestStreamToHelper(ss_.get(), pointer);
144dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    }
145dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return *this;
146dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
147dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#endif  // GTEST_OS_SYMBIAN
148dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
149dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Since the basic IO manipulators are overloaded for both narrow
150dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // and wide streams, we have to provide this specialized definition
151dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // of operator <<, even though its body is the same as the
152dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // templatized version above.  Without this definition, streaming
153dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // endl or other basic IO manipulators to Message will confuse the
154dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // compiler.
155dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Message& operator <<(BasicNarrowIoManip val) {
156dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    *ss_ << val;
157dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return *this;
158dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
159dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
160dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Instead of 1/0, we want to see true/false for bool values.
161dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Message& operator <<(bool b) {
162dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return *this << (b ? "true" : "false");
163dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
164dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
165dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // These two overloads allow streaming a wide C string to a Message
166dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // using the UTF-8 encoding.
167dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Message& operator <<(const wchar_t* wide_c_str) {
168dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return *this << internal::String::ShowWideCString(wide_c_str);
169dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
170dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Message& operator <<(wchar_t* wide_c_str) {
171dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return *this << internal::String::ShowWideCString(wide_c_str);
172dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
173dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
174dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#if GTEST_HAS_STD_WSTRING
175dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Converts the given wide string to a narrow string using the UTF-8
176dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // encoding, and streams the result to this Message object.
177dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Message& operator <<(const ::std::wstring& wstr);
178dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#endif  // GTEST_HAS_STD_WSTRING
179dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
180dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#if GTEST_HAS_GLOBAL_WSTRING
181dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Converts the given wide string to a narrow string using the UTF-8
182dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // encoding, and streams the result to this Message object.
183dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  Message& operator <<(const ::wstring& wstr);
184dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#endif  // GTEST_HAS_GLOBAL_WSTRING
185dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
186dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Gets the text streamed to this object so far as a String.
187dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Each '\0' character in the buffer is replaced with "\\0".
188dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  //
189dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
190dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  internal::String GetString() const {
19146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    return internal::StringStreamToString(ss_.get());
192dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
193dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
194dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter private:
19546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan
196dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#if GTEST_OS_SYMBIAN
197dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // These are needed as the Nokia Symbian Compiler cannot decide between
198dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // const T& and const T* in a function template. The Nokia compiler _can_
199dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // decide between class template specializations for T and T*, so a
200dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // tr1::type_traits-like is_pointer works, and we can overload on that.
201dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  template <typename T>
20246108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {
203dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (pointer == NULL) {
204dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      *ss_ << "(null)";
205dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    } else {
20646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan      ::GTestStreamToHelper(ss_.get(), pointer);
207dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    }
208dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
209dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  template <typename T>
21046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {
21146108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan    ::GTestStreamToHelper(ss_.get(), value);
212dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
213dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#endif  // GTEST_OS_SYMBIAN
214dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
215dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // We'll hold the text streamed to this object here.
21646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan  const internal::scoped_ptr< ::std::stringstream> ss_;
217dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
218dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // We declare (but don't implement) this to prevent the compiler
219dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // from implementing the assignment operator.
220dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  void operator=(const Message&);
221dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter};
222dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
223dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Streams a Message to an ostream.
224dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterinline std::ostream& operator <<(std::ostream& os, const Message& sb) {
225dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  return os << sb.GetString();
226dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter}
227dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
228dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter}  // namespace testing
229dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
230dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
231