Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
6a036a5c
Commit
6a036a5c
authored
Feb 28, 2013
by
zhanyong.wan
Browse files
Fixes a nasty issue in gtest's template instantiation.
parent
b3ed14ac
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
85 additions
and
96 deletions
+85
-96
include/gtest/gtest-message.h
include/gtest/gtest-message.h
+46
-26
include/gtest/gtest.h
include/gtest/gtest.h
+0
-12
include/gtest/internal/gtest-internal.h
include/gtest/internal/gtest-internal.h
+1
-45
include/gtest/internal/gtest-port.h
include/gtest/internal/gtest-port.h
+9
-0
include/gtest/internal/gtest-string.h
include/gtest/internal/gtest-string.h
+0
-11
include/gtest/internal/gtest-type-util.h
include/gtest/internal/gtest-type-util.h
+0
-1
include/gtest/internal/gtest-type-util.h.pump
include/gtest/internal/gtest-type-util.h.pump
+0
-1
src/gtest-filepath.cc
src/gtest-filepath.cc
+1
-0
src/gtest.cc
src/gtest.cc
+28
-0
No files found.
include/gtest/gtest-message.h
View file @
6a036a5c
...
...
@@ -48,8 +48,11 @@
#include <limits>
#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
// Ensures that there is at least one operator<< in the global namespace.
// See Message& operator<<(...) below for why.
void
operator
<<
(
const
testing
::
internal
::
Secret
&
,
int
);
namespace
testing
{
...
...
@@ -87,15 +90,7 @@ class GTEST_API_ Message {
public:
// Constructs an empty Message.
// We allocate the stringstream separately because otherwise each use of
// 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.
Message
()
:
ss_
(
new
::
std
::
stringstream
)
{
// 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
);
}
Message
();
// Copy constructor.
Message
(
const
Message
&
msg
)
:
ss_
(
new
::
std
::
stringstream
)
{
// NOLINT
...
...
@@ -118,7 +113,22 @@ class GTEST_API_ Message {
// Streams a non-pointer value to this object.
template
<
typename
T
>
inline
Message
&
operator
<<
(
const
T
&
val
)
{
::
GTestStreamToHelper
(
ss_
.
get
(),
val
);
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
// overloads are visible in either the std namespace or the global
// namespace, but not other namespaces, including the testing
// namespace which Google Test's Message class is in.
//
// To allow STL containers (and other types that has a << operator
// defined in the global namespace) to be used in Google Test
// assertions, testing::Message must access the custom << operator
// from the global namespace. With this using declaration,
// overloads of << defined in the global namespace and those
// visible via Koenig lookup are both exposed in this function.
using
::
operator
<<
;
*
ss_
<<
val
;
return
*
this
;
}
...
...
@@ -140,7 +150,7 @@ class GTEST_API_ Message {
if
(
pointer
==
NULL
)
{
*
ss_
<<
"(null)"
;
}
else
{
::
GTestStreamToHelper
(
ss_
.
get
(),
pointer
)
;
*
ss_
<<
pointer
;
}
return
*
this
;
}
...
...
@@ -164,12 +174,8 @@ class GTEST_API_ Message {
// 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
);
}
Message
&
operator
<<
(
const
wchar_t
*
wide_c_str
);
Message
&
operator
<<
(
wchar_t
*
wide_c_str
);
#if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
...
...
@@ -187,9 +193,7 @@ class GTEST_API_ Message {
// Each '\0' character in the buffer is replaced with "\\0".
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
std
::
string
GetString
()
const
{
return
internal
::
StringStreamToString
(
ss_
.
get
());
}
std
::
string
GetString
()
const
;
private:
...
...
@@ -199,16 +203,20 @@ class GTEST_API_ Message {
// 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
>
inline
void
StreamHelper
(
internal
::
true_type
/*
dummy
*/
,
T
*
pointer
)
{
inline
void
StreamHelper
(
internal
::
true_type
/*
is_pointer
*/
,
T
*
pointer
)
{
if
(
pointer
==
NULL
)
{
*
ss_
<<
"(null)"
;
}
else
{
::
GTestStreamToHelper
(
ss_
.
get
(),
pointer
)
;
*
ss_
<<
pointer
;
}
}
template
<
typename
T
>
inline
void
StreamHelper
(
internal
::
false_type
/*dummy*/
,
const
T
&
value
)
{
::
GTestStreamToHelper
(
ss_
.
get
(),
value
);
inline
void
StreamHelper
(
internal
::
false_type
/*is_pointer*/
,
const
T
&
value
)
{
// See the comments in Message& operator <<(const T&) above for why
// we need this using statement.
using
::
operator
<<
;
*
ss_
<<
value
;
}
#endif // GTEST_OS_SYMBIAN
...
...
@@ -225,6 +233,18 @@ inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
return
os
<<
sb
.
GetString
();
}
namespace
internal
{
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
template
<
typename
T
>
std
::
string
StreamableToString
(
const
T
&
streamable
)
{
return
(
Message
()
<<
streamable
).
GetString
();
}
}
// namespace internal
}
// namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
include/gtest/gtest.h
View file @
6a036a5c
...
...
@@ -163,18 +163,6 @@ class UnitTestImpl* GetUnitTestImpl();
void
ReportFailureInUnknownLocation
(
TestPartResult
::
Type
result_type
,
const
std
::
string
&
message
);
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
// Declared in gtest-internal.h but defined here, so that it has access
// to the definition of the Message class, required by the ARM
// compiler.
template
<
typename
T
>
std
::
string
StreamableToString
(
const
T
&
streamable
)
{
return
(
Message
()
<<
streamable
).
GetString
();
}
}
// namespace internal
// The friend relationship of some of these classes is cyclic.
...
...
include/gtest/internal/gtest-internal.h
View file @
6a036a5c
...
...
@@ -56,6 +56,7 @@
#include <limits>
#include <set>
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-type-util.h"
...
...
@@ -71,36 +72,6 @@
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
// Google Test defines the testing::Message class to allow construction of
// test messages via the << operator. The idea is that anything
// streamable to std::ostream can be streamed to a testing::Message.
// This allows a user to use his own types in Google Test assertions by
// overloading the << operator.
//
// util/gtl/stl_logging.h overloads << for STL containers. These
// overloads cannot be defined in the std namespace, as that will be
// undefined behavior. Therefore, they are defined in the global
// namespace instead.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
// overloads are visible in either the std namespace or the global
// namespace, but not other namespaces, including the testing
// namespace which Google Test's Message class is in.
//
// To allow STL containers (and other types that has a << operator
// defined in the global namespace) to be used in Google Test assertions,
// testing::Message must access the custom << operator from the global
// namespace. Hence this helper function.
//
// Note: Jeffrey Yasskin suggested an alternative fix by "using
// ::operator<<;" in the definition of Message's operator<<. That fix
// doesn't require a helper function, but unfortunately doesn't
// compile with MSVC.
template
<
typename
T
>
inline
void
GTestStreamToHelper
(
std
::
ostream
*
os
,
const
T
&
val
)
{
*
os
<<
val
;
}
class
ProtocolMessage
;
namespace
proto2
{
class
Message
;
}
...
...
@@ -132,11 +103,6 @@ GTEST_API_ extern int g_init_gtest_count;
// stack trace.
GTEST_API_
extern
const
char
kStackTraceMarker
[];
// A secret type that Google Test users don't know about. It has no
// definition on purpose. Therefore it's impossible to create a
// Secret object, which is what we want.
class
Secret
;
// Two overloaded helpers for checking at compile time whether an
// expression is a null pointer literal (i.e. NULL or any 0-valued
// compile-time integral constant). Their return values have
...
...
@@ -204,16 +170,6 @@ class GTEST_API_ ScopedTrace {
// c'tor and d'tor. Therefore it doesn't
// need to be used otherwise.
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
// Declared here but defined in gtest.h, so that it has access
// to the definition of the Message class, required by the ARM
// compiler.
template
<
typename
T
>
std
::
string
StreamableToString
(
const
T
&
streamable
);
// Constructs and returns the message for an equality assertion
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
//
...
...
include/gtest/internal/gtest-port.h
View file @
6a036a5c
...
...
@@ -32,6 +32,10 @@
// Low-level types and utilities for porting Google Test to various
// platforms. They are subject to change without notice. DO NOT USE
// THEM IN USER CODE.
//
// This file is fundamental to Google Test. All other Google Test source
// files are expected to #include this. Therefore, it cannot #include
// any other Google Test header.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
...
...
@@ -784,6 +788,11 @@ class Message;
namespace
internal
{
// A secret type that Google Test users don't know about. It has no
// definition on purpose. Therefore it's impossible to create a
// Secret object, which is what we want.
class
Secret
;
// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time
// expression is true. For example, you could use it to verify the
// size of a static array:
...
...
include/gtest/internal/gtest-string.h
View file @
6a036a5c
...
...
@@ -161,17 +161,6 @@ class GTEST_API_ String {
// character in the buffer is replaced with "\\0".
GTEST_API_
std
::
string
StringStreamToString
(
::
std
::
stringstream
*
stream
);
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
// Declared here but defined in gtest.h, so that it has access
// to the definition of the Message class, required by the ARM
// compiler.
template
<
typename
T
>
std
::
string
StreamableToString
(
const
T
&
streamable
);
}
// namespace internal
}
// namespace testing
...
...
include/gtest/internal/gtest-type-util.h
View file @
6a036a5c
...
...
@@ -45,7 +45,6 @@
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-string.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
...
...
include/gtest/internal/gtest-type-util.h.pump
View file @
6a036a5c
...
...
@@ -43,7 +43,6 @@ $var n = 50 $$ Maximum length of type lists we want to support.
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-string.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
...
...
src/gtest-filepath.cc
View file @
6a036a5c
...
...
@@ -29,6 +29,7 @@
//
// Authors: keith.ray@gmail.com (Keith Ray)
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-port.h"
...
...
src/gtest.cc
View file @
6a036a5c
...
...
@@ -44,6 +44,8 @@
#include <wctype.h>
#include <algorithm>
#include <iomanip>
#include <limits>
#include <ostream> // NOLINT
#include <sstream>
#include <vector>
...
...
@@ -886,6 +888,26 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
}
// namespace internal
// Constructs an empty Message.
// We allocate the stringstream separately because otherwise each use of
// 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.
Message
::
Message
()
:
ss_
(
new
::
std
::
stringstream
)
{
// 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
);
}
// These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding.
Message
&
Message
::
operator
<<
(
const
wchar_t
*
wide_c_str
)
{
return
*
this
<<
internal
::
String
::
ShowWideCString
(
wide_c_str
);
}
Message
&
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.
...
...
@@ -904,6 +926,12 @@ Message& Message::operator <<(const ::wstring& wstr) {
}
#endif // GTEST_HAS_GLOBAL_WSTRING
// Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0".
std
::
string
Message
::
GetString
()
const
{
return
internal
::
StringStreamToString
(
ss_
.
get
());
}
// AssertionResult constructors.
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult
::
AssertionResult
(
const
AssertionResult
&
other
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment