gtest-message.h 8.2 KB
Newer Older
shiqian's avatar
shiqian committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines the Message class.
//
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
// leave some internal implementation details in this header file.
// They are clearly marked by comments like this:
//
//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
//
// Such code is NOT meant to be used by a user directly, and is subject
// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
// program!

#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_

49
50
#include <limits>

51
52
#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-internal.h"
shiqian's avatar
shiqian committed
53
54
55
56
57
58
59
60

namespace testing {

// The Message class works like an ostream repeater.
//
// Typical usage:
//
//   1. You stream a bunch of values to a Message object.
61
//      It will remember the text in a stringstream.
shiqian's avatar
shiqian committed
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//   2. Then you stream the Message object to an ostream.
//      This causes the text in the Message to be streamed
//      to the ostream.
//
// For example;
//
//   testing::Message foo;
//   foo << 1 << " != " << 2;
//   std::cout << foo;
//
// will print "1 != 2".
//
// Message is not intended to be inherited from.  In particular, its
// destructor is not virtual.
//
77
// Note that stringstream behaves differently in gcc and in MSVC.  You
shiqian's avatar
shiqian committed
78
79
80
81
// can stream a NULL char pointer to it in the former, but not in the
// latter (it causes an access violation if you do).  The Message
// class hides this difference by treating a NULL char pointer as
// "(null)".
82
class GTEST_API_ Message {
shiqian's avatar
shiqian committed
83
84
85
86
87
88
89
 private:
  // The type of basic IO manipulators (endl, ends, and flush) for
  // narrow streams.
  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);

 public:
  // Constructs an empty Message.
90
  // We allocate the stringstream separately because otherwise each use of
shiqian's avatar
shiqian committed
91
92
93
  // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
  // stack frame leading to huge stack frames in some cases; gcc does not reuse
  // the stack space.
94
  Message() : ss_(new ::std::stringstream) {
95
96
97
98
    // By default, we want there to be enough precision when printing
    // a double to a Message.
    *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
  }
shiqian's avatar
shiqian committed
99
100

  // Copy constructor.
101
  Message(const Message& msg) : ss_(new ::std::stringstream) {  // NOLINT
shiqian's avatar
shiqian committed
102
103
104
105
    *ss_ << msg.GetString();
  }

  // Constructs a Message from a C-string.
106
  explicit Message(const char* str) : ss_(new ::std::stringstream) {
shiqian's avatar
shiqian committed
107
108
109
    *ss_ << str;
  }

zhanyong.wan's avatar
zhanyong.wan committed
110
#if GTEST_OS_SYMBIAN
shiqian's avatar
shiqian committed
111
112
113
114
115
116
117
118
119
120
  // Streams a value (either a pointer or not) to this object.
  template <typename T>
  inline Message& operator <<(const T& value) {
    StreamHelper(typename internal::is_pointer<T>::type(), value);
    return *this;
  }
#else
  // Streams a non-pointer value to this object.
  template <typename T>
  inline Message& operator <<(const T& val) {
121
    ::GTestStreamToHelper(ss_.get(), val);
shiqian's avatar
shiqian committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    return *this;
  }

  // Streams a pointer value to this object.
  //
  // This function is an overload of the previous one.  When you
  // stream a pointer to a Message, this definition will be used as it
  // is more specialized.  (The C++ Standard, section
  // [temp.func.order].)  If you stream a non-pointer, then the
  // previous definition will be used.
  //
  // The reason for this overload is that streaming a NULL pointer to
  // ostream is undefined behavior.  Depending on the compiler, you
  // may get "0", "(nil)", "(null)", or an access violation.  To
  // ensure consistent result across compilers, we always treat NULL
  // as "(null)".
  template <typename T>
  inline Message& operator <<(T* const& pointer) {  // NOLINT
    if (pointer == NULL) {
      *ss_ << "(null)";
    } else {
143
      ::GTestStreamToHelper(ss_.get(), pointer);
shiqian's avatar
shiqian committed
144
145
146
    }
    return *this;
  }
shiqian's avatar
shiqian committed
147
#endif  // GTEST_OS_SYMBIAN
shiqian's avatar
shiqian committed
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

  // Since the basic IO manipulators are overloaded for both narrow
  // and wide streams, we have to provide this specialized definition
  // of operator <<, even though its body is the same as the
  // templatized version above.  Without this definition, streaming
  // endl or other basic IO manipulators to Message will confuse the
  // compiler.
  Message& operator <<(BasicNarrowIoManip val) {
    *ss_ << val;
    return *this;
  }

  // Instead of 1/0, we want to see true/false for bool values.
  Message& operator <<(bool b) {
    return *this << (b ? "true" : "false");
  }

  // These two overloads allow streaming a wide C string to a Message
  // using the UTF-8 encoding.
  Message& operator <<(const wchar_t* wide_c_str) {
    return *this << internal::String::ShowWideCString(wide_c_str);
  }
  Message& operator <<(wchar_t* wide_c_str) {
    return *this << internal::String::ShowWideCString(wide_c_str);
  }

#if GTEST_HAS_STD_WSTRING
  // Converts the given wide string to a narrow string using the UTF-8
  // encoding, and streams the result to this Message object.
  Message& operator <<(const ::std::wstring& wstr);
#endif  // GTEST_HAS_STD_WSTRING

#if GTEST_HAS_GLOBAL_WSTRING
  // Converts the given wide string to a narrow string using the UTF-8
  // encoding, and streams the result to this Message object.
  Message& operator <<(const ::wstring& wstr);
#endif  // GTEST_HAS_GLOBAL_WSTRING

186
  // Gets the text streamed to this object so far as an std::string.
shiqian's avatar
shiqian committed
187
188
189
  // Each '\0' character in the buffer is replaced with "\\0".
  //
  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
190
  std::string GetString() const {
191
    return internal::StringStreamToString(ss_.get());
shiqian's avatar
shiqian committed
192
193
194
  }

 private:
195

zhanyong.wan's avatar
zhanyong.wan committed
196
#if GTEST_OS_SYMBIAN
shiqian's avatar
shiqian committed
197
198
199
200
201
  // These are needed as the Nokia Symbian Compiler cannot decide between
  // const T& and const T* in a function template. The Nokia compiler _can_
  // decide between class template specializations for T and T*, so a
  // tr1::type_traits-like is_pointer works, and we can overload on that.
  template <typename T>
202
  inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {
shiqian's avatar
shiqian committed
203
204
205
    if (pointer == NULL) {
      *ss_ << "(null)";
    } else {
206
      ::GTestStreamToHelper(ss_.get(), pointer);
shiqian's avatar
shiqian committed
207
208
209
    }
  }
  template <typename T>
210
  inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {
211
    ::GTestStreamToHelper(ss_.get(), value);
shiqian's avatar
shiqian committed
212
  }
shiqian's avatar
shiqian committed
213
#endif  // GTEST_OS_SYMBIAN
shiqian's avatar
shiqian committed
214
215

  // We'll hold the text streamed to this object here.
216
  const internal::scoped_ptr< ::std::stringstream> ss_;
shiqian's avatar
shiqian committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230

  // We declare (but don't implement) this to prevent the compiler
  // from implementing the assignment operator.
  void operator=(const Message&);
};

// Streams a Message to an ostream.
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
  return os << sb.GetString();
}

}  // namespace testing

#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_