Fixes compatibility with Borland C++Builder. Original patch by Josh
Kelley. Simplified by Zhanyong Wan.
This commit is contained in:
parent
66ac4909ae
commit
603533a0a4
|
@ -308,7 +308,10 @@ void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||||
} else {
|
} else {
|
||||||
// C++ doesn't allow casting from a function pointer to any object
|
// C++ doesn't allow casting from a function pointer to any object
|
||||||
// pointer.
|
// pointer.
|
||||||
if (ImplicitlyConvertible<T*, const void*>::value) {
|
//
|
||||||
|
// IsTrue() silences warnings: "Condition is always true",
|
||||||
|
// "unreachable code".
|
||||||
|
if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {
|
||||||
// T is not a function type. We just call << to print p,
|
// T is not a function type. We just call << to print p,
|
||||||
// relying on ADL to pick up user-defined << for their pointer
|
// relying on ADL to pick up user-defined << for their pointer
|
||||||
// types, if any.
|
// types, if any.
|
||||||
|
@ -736,12 +739,25 @@ struct TuplePrefixPrinter<0> {
|
||||||
template <typename Tuple>
|
template <typename Tuple>
|
||||||
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
|
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
|
||||||
};
|
};
|
||||||
|
// We have to specialize the entire TuplePrefixPrinter<> class
|
||||||
|
// template here, even though the definition of
|
||||||
|
// TersePrintPrefixToStrings() is the same as the generic version, as
|
||||||
|
// Borland C++ doesn't support specializing a method.
|
||||||
template <>
|
template <>
|
||||||
template <typename Tuple>
|
struct TuplePrefixPrinter<1> {
|
||||||
void TuplePrefixPrinter<1>::PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
template <typename Tuple>
|
||||||
UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
|
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||||
Print(::std::tr1::get<0>(t), os);
|
UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
|
||||||
}
|
Print(::std::tr1::get<0>(t), os);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tuple>
|
||||||
|
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
|
||||||
|
::std::stringstream ss;
|
||||||
|
UniversalTersePrint(::std::tr1::get<0>(t), &ss);
|
||||||
|
strings->push_back(ss.str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Helper function for printing a tuple. T must be instantiated with
|
// Helper function for printing a tuple. T must be instantiated with
|
||||||
// a tuple type.
|
// a tuple type.
|
||||||
|
|
|
@ -1296,7 +1296,9 @@ namespace internal {
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
String FormatForComparisonFailureMessage(const T1& value,
|
String FormatForComparisonFailureMessage(const T1& value,
|
||||||
const T2& /* other_operand */) {
|
const T2& /* other_operand */) {
|
||||||
return PrintToString(value);
|
// C++Builder compiles this incorrectly if the namespace isn't explicitly
|
||||||
|
// given.
|
||||||
|
return ::testing::PrintToString(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The helper function for {ASSERT|EXPECT}_EQ.
|
// The helper function for {ASSERT|EXPECT}_EQ.
|
||||||
|
|
|
@ -873,6 +873,11 @@ class ImplicitlyConvertible {
|
||||||
static const bool value =
|
static const bool value =
|
||||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||||
# pragma warning(pop) // Restores the warning state.
|
# pragma warning(pop) // Restores the warning state.
|
||||||
|
#elif defined(__BORLANDC__)
|
||||||
|
// C++Builder cannot use member overload resolution during template
|
||||||
|
// instantiation. The simplest workaround is to use its C++0x type traits
|
||||||
|
// functions (C++Builder 2009 and above only).
|
||||||
|
static const bool value = __is_convertible(From, To);
|
||||||
#else
|
#else
|
||||||
static const bool value =
|
static const bool value =
|
||||||
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
|
||||||
|
|
|
@ -296,7 +296,7 @@ class GTEST_API_ String {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Constructs a non-NULL String from the given content. This
|
// Constructs a non-NULL String from the given content. This
|
||||||
// function can only be called when data_ has not been allocated.
|
// function can only be called when c_str_ has not been allocated.
|
||||||
// ConstructNonNull(NULL, 0) results in an empty string ("").
|
// ConstructNonNull(NULL, 0) results in an empty string ("").
|
||||||
// ConstructNonNull(NULL, non_zero) is undefined behavior.
|
// ConstructNonNull(NULL, non_zero) is undefined behavior.
|
||||||
void ConstructNonNull(const char* buffer, size_t a_length) {
|
void ConstructNonNull(const char* buffer, size_t a_length) {
|
||||||
|
|
|
@ -4349,7 +4349,7 @@ bool ShouldShard(const char* total_shards_env,
|
||||||
// Parses the environment variable var as an Int32. If it is unset,
|
// Parses the environment variable var as an Int32. If it is unset,
|
||||||
// returns default_val. If it is not an Int32, prints an error
|
// returns default_val. If it is not an Int32, prints an error
|
||||||
// and aborts.
|
// and aborts.
|
||||||
Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) {
|
Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) {
|
||||||
const char* str_val = posix::GetEnv(var);
|
const char* str_val = posix::GetEnv(var);
|
||||||
if (str_val == NULL) {
|
if (str_val == NULL) {
|
||||||
return default_val;
|
return default_val;
|
||||||
|
|
|
@ -1416,8 +1416,8 @@ static int global_var = 0;
|
||||||
#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++
|
#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++
|
||||||
|
|
||||||
TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
|
TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
|
||||||
#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
|
#ifndef __BORLANDC__
|
||||||
// ICE's in C++Builder 2007.
|
// ICE's in C++Builder.
|
||||||
EXPECT_FATAL_FAILURE({
|
EXPECT_FATAL_FAILURE({
|
||||||
GTEST_USE_UNPROTECTED_COMMA_;
|
GTEST_USE_UNPROTECTED_COMMA_;
|
||||||
AddFatalFailure();
|
AddFatalFailure();
|
||||||
|
@ -3550,8 +3550,8 @@ TEST(AssertionTest, ASSERT_TRUE) {
|
||||||
// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
|
// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
|
||||||
TEST(AssertionTest, AssertTrueWithAssertionResult) {
|
TEST(AssertionTest, AssertTrueWithAssertionResult) {
|
||||||
ASSERT_TRUE(ResultIsEven(2));
|
ASSERT_TRUE(ResultIsEven(2));
|
||||||
#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
|
#ifndef __BORLANDC__
|
||||||
// ICE's in C++Builder 2007.
|
// ICE's in C++Builder.
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
|
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
|
||||||
"Value of: ResultIsEven(3)\n"
|
"Value of: ResultIsEven(3)\n"
|
||||||
" Actual: false (3 is odd)\n"
|
" Actual: false (3 is odd)\n"
|
||||||
|
@ -3576,8 +3576,8 @@ TEST(AssertionTest, ASSERT_FALSE) {
|
||||||
// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
|
// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
|
||||||
TEST(AssertionTest, AssertFalseWithAssertionResult) {
|
TEST(AssertionTest, AssertFalseWithAssertionResult) {
|
||||||
ASSERT_FALSE(ResultIsEven(3));
|
ASSERT_FALSE(ResultIsEven(3));
|
||||||
#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
|
#ifndef __BORLANDC__
|
||||||
// ICE's in C++Builder 2007.
|
// ICE's in C++Builder.
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
|
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
|
||||||
"Value of: ResultIsEven(2)\n"
|
"Value of: ResultIsEven(2)\n"
|
||||||
" Actual: true (2 is even)\n"
|
" Actual: true (2 is even)\n"
|
||||||
|
@ -3877,10 +3877,16 @@ TEST(AssertionTest, AnonymousEnum) {
|
||||||
ASSERT_LE(kCaseA, kCaseB);
|
ASSERT_LE(kCaseA, kCaseB);
|
||||||
ASSERT_GT(kCaseB, kCaseA);
|
ASSERT_GT(kCaseB, kCaseA);
|
||||||
ASSERT_GE(kCaseA, kCaseA);
|
ASSERT_GE(kCaseA, kCaseA);
|
||||||
|
|
||||||
|
# ifndef __BORLANDC__
|
||||||
|
|
||||||
|
// ICE's in C++Builder.
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB),
|
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB),
|
||||||
"Value of: kCaseB");
|
"Value of: kCaseB");
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
|
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
|
||||||
"Actual: 42");
|
"Actual: 42");
|
||||||
|
# endif
|
||||||
|
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
|
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
|
||||||
"Which is: -1");
|
"Which is: -1");
|
||||||
}
|
}
|
||||||
|
@ -4791,10 +4797,13 @@ TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) {
|
||||||
|
|
||||||
// Code tested by EXPECT_FATAL_FAILURE cannot reference local
|
// Code tested by EXPECT_FATAL_FAILURE cannot reference local
|
||||||
// variables, so we have to write UnprintableChar('x') instead of x.
|
// variables, so we have to write UnprintableChar('x') instead of x.
|
||||||
|
#ifndef __BORLANDC__
|
||||||
|
// ICE's in C++Builder.
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')),
|
EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')),
|
||||||
"1-byte object <78>");
|
"1-byte object <78>");
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
|
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
|
||||||
"1-byte object <78>");
|
"1-byte object <78>");
|
||||||
|
#endif
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
|
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
|
||||||
"1-byte object <79>");
|
"1-byte object <79>");
|
||||||
EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')),
|
EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')),
|
||||||
|
@ -7213,8 +7222,10 @@ TEST(CopyArrayTest, WorksForDegeneratedArrays) {
|
||||||
TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
|
TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
|
||||||
const char a[3] = "hi";
|
const char a[3] = "hi";
|
||||||
int b[3];
|
int b[3];
|
||||||
|
#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions.
|
||||||
CopyArray(a, &b);
|
CopyArray(a, &b);
|
||||||
EXPECT_TRUE(ArrayEq(a, b));
|
EXPECT_TRUE(ArrayEq(a, b));
|
||||||
|
#endif
|
||||||
|
|
||||||
int c[3];
|
int c[3];
|
||||||
CopyArray(a, 3, c);
|
CopyArray(a, 3, c);
|
||||||
|
@ -7224,8 +7235,10 @@ TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
|
||||||
TEST(CopyArrayTest, WorksForTwoDimensionalArrays) {
|
TEST(CopyArrayTest, WorksForTwoDimensionalArrays) {
|
||||||
const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
|
const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
|
||||||
int b[2][3];
|
int b[2][3];
|
||||||
|
#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions.
|
||||||
CopyArray(a, &b);
|
CopyArray(a, &b);
|
||||||
EXPECT_TRUE(ArrayEq(a, b));
|
EXPECT_TRUE(ArrayEq(a, b));
|
||||||
|
#endif
|
||||||
|
|
||||||
int c[2][3];
|
int c[2][3];
|
||||||
CopyArray(a, 2, c);
|
CopyArray(a, 2, c);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user