Fixes a nasty issue in gtest's template instantiation.
This commit is contained in:
		@@ -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_
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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).
 | 
			
		||||
 
 | 
			
		||||
@@ -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).
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								src/gtest.cc
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/gtest.cc
									
									
									
									
									
								
							@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user