Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
6a036a5c
Commit
6a036a5c
authored
Feb 28, 2013
by
zhanyong.wan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes a nasty issue in gtest's template instantiation.
parent
b3ed14ac
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
85 additions
and
96 deletions
+85
-96
gtest-message.h
include/gtest/gtest-message.h
+46
-26
gtest.h
include/gtest/gtest.h
+0
-12
gtest-internal.h
include/gtest/internal/gtest-internal.h
+1
-45
gtest-port.h
include/gtest/internal/gtest-port.h
+9
-0
gtest-string.h
include/gtest/internal/gtest-string.h
+0
-11
gtest-type-util.h
include/gtest/internal/gtest-type-util.h
+0
-1
gtest-type-util.h.pump
include/gtest/internal/gtest-type-util.h.pump
+0
-1
gtest-filepath.cc
src/gtest-filepath.cc
+1
-0
gtest.cc
src/gtest.cc
+28
-0
No files found.
include/gtest/gtest-message.h
View file @
6a036a5c
...
@@ -48,8 +48,11 @@
...
@@ -48,8 +48,11 @@
#include <limits>
#include <limits>
#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-internal.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
{
namespace
testing
{
...
@@ -87,15 +90,7 @@ class GTEST_API_ Message {
...
@@ -87,15 +90,7 @@ class GTEST_API_ Message {
public
:
public
:
// Constructs an empty Message.
// Constructs an empty Message.
// We allocate the stringstream separately because otherwise each use of
Message
();
// 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
);
}
// Copy constructor.
// Copy constructor.
Message
(
const
Message
&
msg
)
:
ss_
(
new
::
std
::
stringstream
)
{
// NOLINT
Message
(
const
Message
&
msg
)
:
ss_
(
new
::
std
::
stringstream
)
{
// NOLINT
...
@@ -118,7 +113,22 @@ class GTEST_API_ Message {
...
@@ -118,7 +113,22 @@ class GTEST_API_ Message {
// Streams a non-pointer value to this object.
// Streams a non-pointer value to this object.
template
<
typename
T
>
template
<
typename
T
>
inline
Message
&
operator
<<
(
const
T
&
val
)
{
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
;
return
*
this
;
}
}
...
@@ -140,7 +150,7 @@ class GTEST_API_ Message {
...
@@ -140,7 +150,7 @@ class GTEST_API_ Message {
if
(
pointer
==
NULL
)
{
if
(
pointer
==
NULL
)
{
*
ss_
<<
"(null)"
;
*
ss_
<<
"(null)"
;
}
else
{
}
else
{
::
GTestStreamToHelper
(
ss_
.
get
(),
pointer
)
;
*
ss_
<<
pointer
;
}
}
return
*
this
;
return
*
this
;
}
}
...
@@ -164,12 +174,8 @@ class GTEST_API_ Message {
...
@@ -164,12 +174,8 @@ class GTEST_API_ Message {
// These two overloads allow streaming a wide C string to a Message
// These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding.
// using the UTF-8 encoding.
Message
&
operator
<<
(
const
wchar_t
*
wide_c_str
)
{
Message
&
operator
<<
(
const
wchar_t
*
wide_c_str
);
return
*
this
<<
internal
::
String
::
ShowWideCString
(
wide_c_str
);
Message
&
operator
<<
(
wchar_t
*
wide_c_str
);
}
Message
&
operator
<<
(
wchar_t
*
wide_c_str
)
{
return
*
this
<<
internal
::
String
::
ShowWideCString
(
wide_c_str
);
}
#if GTEST_HAS_STD_WSTRING
#if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// Converts the given wide string to a narrow string using the UTF-8
...
@@ -187,9 +193,7 @@ class GTEST_API_ Message {
...
@@ -187,9 +193,7 @@ class GTEST_API_ Message {
// Each '\0' character in the buffer is replaced with "\\0".
// Each '\0' character in the buffer is replaced with "\\0".
//
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
std
::
string
GetString
()
const
{
std
::
string
GetString
()
const
;
return
internal
::
StringStreamToString
(
ss_
.
get
());
}
private
:
private
:
...
@@ -199,16 +203,20 @@ class GTEST_API_ Message {
...
@@ -199,16 +203,20 @@ class GTEST_API_ Message {
// decide between class template specializations for T and T*, so a
// decide between class template specializations for T and T*, so a
// tr1::type_traits-like is_pointer works, and we can overload on that.
// tr1::type_traits-like is_pointer works, and we can overload on that.
template
<
typename
T
>
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
)
{
if
(
pointer
==
NULL
)
{
*
ss_
<<
"(null)"
;
*
ss_
<<
"(null)"
;
}
else
{
}
else
{
::
GTestStreamToHelper
(
ss_
.
get
(),
pointer
)
;
*
ss_
<<
pointer
;
}
}
}
}
template
<
typename
T
>
template
<
typename
T
>
inline
void
StreamHelper
(
internal
::
false_type
/*dummy*/
,
const
T
&
value
)
{
inline
void
StreamHelper
(
internal
::
false_type
/*is_pointer*/
,
::
GTestStreamToHelper
(
ss_
.
get
(),
value
);
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
#endif // GTEST_OS_SYMBIAN
...
@@ -225,6 +233,18 @@ inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
...
@@ -225,6 +233,18 @@ inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
return
os
<<
sb
.
GetString
();
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
}
// namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
include/gtest/gtest.h
View file @
6a036a5c
...
@@ -163,18 +163,6 @@ class UnitTestImpl* GetUnitTestImpl();
...
@@ -163,18 +163,6 @@ class UnitTestImpl* GetUnitTestImpl();
void
ReportFailureInUnknownLocation
(
TestPartResult
::
Type
result_type
,
void
ReportFailureInUnknownLocation
(
TestPartResult
::
Type
result_type
,
const
std
::
string
&
message
);
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
}
// namespace internal
// The friend relationship of some of these classes is cyclic.
// The friend relationship of some of these classes is cyclic.
...
...
include/gtest/internal/gtest-internal.h
View file @
6a036a5c
...
@@ -56,6 +56,7 @@
...
@@ -56,6 +56,7 @@
#include <limits>
#include <limits>
#include <set>
#include <set>
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-type-util.h"
#include "gtest/internal/gtest-type-util.h"
...
@@ -71,36 +72,6 @@
...
@@ -71,36 +72,6 @@
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) 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
;
class
ProtocolMessage
;
namespace
proto2
{
class
Message
;
}
namespace
proto2
{
class
Message
;
}
...
@@ -132,11 +103,6 @@ GTEST_API_ extern int g_init_gtest_count;
...
@@ -132,11 +103,6 @@ GTEST_API_ extern int g_init_gtest_count;
// stack trace.
// stack trace.
GTEST_API_
extern
const
char
kStackTraceMarker
[];
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
// Two overloaded helpers for checking at compile time whether an
// expression is a null pointer literal (i.e. NULL or any 0-valued
// expression is a null pointer literal (i.e. NULL or any 0-valued
// compile-time integral constant). Their return values have
// compile-time integral constant). Their return values have
...
@@ -204,16 +170,6 @@ class GTEST_API_ ScopedTrace {
...
@@ -204,16 +170,6 @@ class GTEST_API_ ScopedTrace {
// c'tor and d'tor. Therefore it doesn't
// c'tor and d'tor. Therefore it doesn't
// need to be used otherwise.
// 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
// Constructs and returns the message for an equality assertion
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
//
//
...
...
include/gtest/internal/gtest-port.h
View file @
6a036a5c
...
@@ -32,6 +32,10 @@
...
@@ -32,6 +32,10 @@
// Low-level types and utilities for porting Google Test to various
// Low-level types and utilities for porting Google Test to various
// platforms. They are subject to change without notice. DO NOT USE
// platforms. They are subject to change without notice. DO NOT USE
// THEM IN USER CODE.
// 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_
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
...
@@ -784,6 +788,11 @@ class Message;
...
@@ -784,6 +788,11 @@ class Message;
namespace
internal
{
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
// 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
// expression is true. For example, you could use it to verify the
// size of a static array:
// size of a static array:
...
...
include/gtest/internal/gtest-string.h
View file @
6a036a5c
...
@@ -161,17 +161,6 @@ class GTEST_API_ String {
...
@@ -161,17 +161,6 @@ class GTEST_API_ String {
// character in the buffer is replaced with "\\0".
// character in the buffer is replaced with "\\0".
GTEST_API_
std
::
string
StringStreamToString
(
::
std
::
stringstream
*
stream
);
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 internal
}
// namespace testing
}
// namespace testing
...
...
include/gtest/internal/gtest-type-util.h
View file @
6a036a5c
...
@@ -45,7 +45,6 @@
...
@@ -45,7 +45,6 @@
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.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
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
// 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.
...
@@ -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_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.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
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
// libstdc++ (which is where cxxabi.h comes from).
...
...
src/gtest-filepath.cc
View file @
6a036a5c
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
//
//
// Authors: keith.ray@gmail.com (Keith Ray)
// Authors: keith.ray@gmail.com (Keith Ray)
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-port.h"
...
...
src/gtest.cc
View file @
6a036a5c
...
@@ -44,6 +44,8 @@
...
@@ -44,6 +44,8 @@
#include <wctype.h>
#include <wctype.h>
#include <algorithm>
#include <algorithm>
#include <iomanip>
#include <limits>
#include <ostream> // NOLINT
#include <ostream> // NOLINT
#include <sstream>
#include <sstream>
#include <vector>
#include <vector>
...
@@ -886,6 +888,26 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
...
@@ -886,6 +888,26 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,
}
// namespace internal
}
// 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
#if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
// encoding, and streams the result to this Message object.
...
@@ -904,6 +926,12 @@ Message& Message::operator <<(const ::wstring& wstr) {
...
@@ -904,6 +926,12 @@ Message& Message::operator <<(const ::wstring& wstr) {
}
}
#endif // GTEST_HAS_GLOBAL_WSTRING
#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.
// AssertionResult constructors.
// Used in EXPECT_TRUE/FALSE(assertion_result).
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult
::
AssertionResult
(
const
AssertionResult
&
other
)
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