Allows EXPECT_EQ to accept arguments that don't have operator << (by Zhanyong Wan).
Allows a user to customize how the universal printer prints a pointer of a specific type by overloading << (by Zhanyong Wan). Works around a bug in Cymbian's C++ compiler (by Vlad Losev).
This commit is contained in:
@@ -280,12 +280,23 @@ void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||
if (p == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
// We want to print p as a const void*. However, we cannot cast
|
||||
// it to const void* directly, even using reinterpret_cast, as
|
||||
// earlier versions of gcc (e.g. 3.4.5) cannot compile the cast
|
||||
// when p is a function pointer. Casting to UInt64 first solves
|
||||
// the problem.
|
||||
*os << reinterpret_cast<const void*>(reinterpret_cast<internal::UInt64>(p));
|
||||
// C++ doesn't allow casting from a function pointer to any object
|
||||
// pointer.
|
||||
if (ImplicitlyConvertible<T*, const void*>::value) {
|
||||
// T is not a function type. We just call << to print p,
|
||||
// relying on ADL to pick up user-defined << for their pointer
|
||||
// types, if any.
|
||||
*os << p;
|
||||
} else {
|
||||
// T is a function type, so '*os << p' doesn't do what we want
|
||||
// (it just prints p as bool). We want to print p as a const
|
||||
// void*. However, we cannot cast it to const void* directly,
|
||||
// even using reinterpret_cast, as earlier versions of gcc
|
||||
// (e.g. 3.4.5) cannot compile the cast when p is a function
|
||||
// pointer. Casting to UInt64 first solves the problem.
|
||||
*os << reinterpret_cast<const void*>(
|
||||
reinterpret_cast<internal::UInt64>(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,13 +352,8 @@ void PrintTo(const T& value, ::std::ostream* os) {
|
||||
// types, strings, plain arrays, and pointers).
|
||||
|
||||
// Overloads for various char types.
|
||||
GTEST_API_ void PrintCharTo(char c, int char_code, ::std::ostream* os);
|
||||
inline void PrintTo(unsigned char c, ::std::ostream* os) {
|
||||
PrintCharTo(c, c, os);
|
||||
}
|
||||
inline void PrintTo(signed char c, ::std::ostream* os) {
|
||||
PrintCharTo(c, c, os);
|
||||
}
|
||||
GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
|
||||
GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
|
||||
inline void PrintTo(char c, ::std::ostream* os) {
|
||||
// When printing a plain char, we always treat it as unsigned. This
|
||||
// way, the output won't be affected by whether the compiler thinks
|
||||
@@ -375,6 +381,21 @@ inline void PrintTo(char* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const char*>(s), os);
|
||||
}
|
||||
|
||||
// signed/unsigned char is often used for representing binary data, so
|
||||
// we print pointers to it as void* to be safe.
|
||||
inline void PrintTo(const signed char* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const void*>(s), os);
|
||||
}
|
||||
inline void PrintTo(signed char* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const void*>(s), os);
|
||||
}
|
||||
inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const void*>(s), os);
|
||||
}
|
||||
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
|
||||
PrintTo(implicit_cast<const void*>(s), os);
|
||||
}
|
||||
|
||||
// MSVC can be configured to define wchar_t as a typedef of unsigned
|
||||
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
|
||||
// type. When wchar_t is a typedef, defining an overload for const
|
||||
|
||||
@@ -1207,30 +1207,6 @@ GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
|
||||
|
||||
namespace internal {
|
||||
|
||||
// These overloaded versions handle ::std::string and ::std::wstring.
|
||||
GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) {
|
||||
return (Message() << '"' << str << '"').GetString();
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) {
|
||||
return (Message() << "L\"" << wstr << '"').GetString();
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// These overloaded versions handle ::string and ::wstring.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
GTEST_API_ inline String FormatForFailureMessage(const ::string& str) {
|
||||
return (Message() << '"' << str << '"').GetString();
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) {
|
||||
return (Message() << "L\"" << wstr << '"').GetString();
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
|
||||
// operand to be used in a failure message. The type (but not value)
|
||||
// of the other operand may affect the format. This allows us to
|
||||
@@ -1246,7 +1222,7 @@ GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) {
|
||||
template <typename T1, typename T2>
|
||||
String FormatForComparisonFailureMessage(const T1& value,
|
||||
const T2& /* other_operand */) {
|
||||
return FormatForFailureMessage(value);
|
||||
return PrintToString(value);
|
||||
}
|
||||
|
||||
// The helper function for {ASSERT|EXPECT}_EQ.
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace proto2 { class Message; }
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Forward declaration of classes.
|
||||
// Forward declarations.
|
||||
|
||||
class AssertionResult; // Result of an assertion.
|
||||
class Message; // Represents a failure message.
|
||||
@@ -111,6 +111,9 @@ class TestInfo; // Information about a test.
|
||||
class TestPartResult; // Result of a test part.
|
||||
class UnitTest; // A collection of test cases.
|
||||
|
||||
template <typename T>
|
||||
::std::string PrintToString(const T& value);
|
||||
|
||||
namespace internal {
|
||||
|
||||
struct TraceInfo; // Information about a trace point.
|
||||
@@ -192,72 +195,23 @@ class GTEST_API_ ScopedTrace {
|
||||
template <typename T>
|
||||
String StreamableToString(const T& streamable);
|
||||
|
||||
// Formats a value to be used in a failure message.
|
||||
|
||||
#ifdef GTEST_NEEDS_IS_POINTER_
|
||||
|
||||
// These are needed as the Nokia Symbian and IBM XL C/C++ compilers
|
||||
// cannot decide between const T& and const T* in a function template.
|
||||
// These compilers _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.
|
||||
|
||||
// This overload makes sure that all pointers (including
|
||||
// those to char or wchar_t) are printed as raw pointers.
|
||||
template <typename T>
|
||||
inline String FormatValueForFailureMessage(internal::true_type /*dummy*/,
|
||||
T* pointer) {
|
||||
return StreamableToString(static_cast<const void*>(pointer));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline String FormatValueForFailureMessage(internal::false_type /*dummy*/,
|
||||
const T& value) {
|
||||
return StreamableToString(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline String FormatForFailureMessage(const T& value) {
|
||||
return FormatValueForFailureMessage(
|
||||
typename internal::is_pointer<T>::type(), value);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// These are needed as the above solution using is_pointer has the
|
||||
// limitation that T cannot be a type without external linkage, when
|
||||
// compiled using MSVC.
|
||||
|
||||
template <typename T>
|
||||
inline String FormatForFailureMessage(const T& value) {
|
||||
return StreamableToString(value);
|
||||
}
|
||||
|
||||
// This overload makes sure that all pointers (including
|
||||
// those to char or wchar_t) are printed as raw pointers.
|
||||
template <typename T>
|
||||
inline String FormatForFailureMessage(T* pointer) {
|
||||
return StreamableToString(static_cast<const void*>(pointer));
|
||||
}
|
||||
|
||||
#endif // GTEST_NEEDS_IS_POINTER_
|
||||
|
||||
// These overloaded versions handle narrow and wide characters.
|
||||
GTEST_API_ String FormatForFailureMessage(char ch);
|
||||
GTEST_API_ String FormatForFailureMessage(wchar_t wchar);
|
||||
|
||||
// When this operand is a const char* or char*, and the other operand
|
||||
// When this operand is a const char* or char*, if the other operand
|
||||
// is a ::std::string or ::string, we print this operand as a C string
|
||||
// rather than a pointer. We do the same for wide strings.
|
||||
// rather than a pointer (we do the same for wide strings); otherwise
|
||||
// we print it as a pointer to be safe.
|
||||
|
||||
// This internal macro is used to avoid duplicated code.
|
||||
// Making the first operand const reference works around a bug in the
|
||||
// Symbian compiler which is unable to select the correct specialization of
|
||||
// FormatForComparisonFailureMessage.
|
||||
#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\
|
||||
inline String FormatForComparisonFailureMessage(\
|
||||
operand2_type::value_type* str, const operand2_type& /*operand2*/) {\
|
||||
operand2_type::value_type* const& str, const operand2_type& /*operand2*/) {\
|
||||
return operand1_printer(str);\
|
||||
}\
|
||||
inline String FormatForComparisonFailureMessage(\
|
||||
const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\
|
||||
const operand2_type::value_type* const& str, \
|
||||
const operand2_type& /*operand2*/) {\
|
||||
return operand1_printer(str);\
|
||||
}
|
||||
|
||||
@@ -275,6 +229,27 @@ GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted)
|
||||
|
||||
#undef GTEST_FORMAT_IMPL_
|
||||
|
||||
// The next four overloads handle the case where the operand being
|
||||
// printed is a char/wchar_t pointer and the other operand is not a
|
||||
// string/wstring object. In such cases, we just print the operand as
|
||||
// a pointer to be safe.
|
||||
//
|
||||
// Making the first operand const reference works around a bug in the
|
||||
// Symbian compiler which is unable to select the correct specialization of
|
||||
// FormatForComparisonFailureMessage.
|
||||
#define GTEST_FORMAT_CHAR_PTR_IMPL_(CharType) \
|
||||
template <typename T> \
|
||||
String FormatForComparisonFailureMessage(CharType* const& p, const T&) { \
|
||||
return PrintToString(static_cast<const void*>(p)); \
|
||||
}
|
||||
|
||||
GTEST_FORMAT_CHAR_PTR_IMPL_(char)
|
||||
GTEST_FORMAT_CHAR_PTR_IMPL_(const char)
|
||||
GTEST_FORMAT_CHAR_PTR_IMPL_(wchar_t)
|
||||
GTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t)
|
||||
|
||||
#undef GTEST_FORMAT_CHAR_PTR_IMPL_
|
||||
|
||||
// Constructs and returns the message for an equality assertion
|
||||
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user