Enables gmock's implicit_cast to work with source types that have a non-const conversion operator (by Zhanyong Wan).
This commit is contained in:
parent
a070cbd91c
commit
201ac16191
@ -99,9 +99,21 @@ namespace internal {
|
|||||||
// but the proposal was submitted too late. It will probably make
|
// but the proposal was submitted too late. It will probably make
|
||||||
// its way into the language in the future.
|
// its way into the language in the future.
|
||||||
template<typename To, typename From>
|
template<typename To, typename From>
|
||||||
inline To implicit_cast(From const &f) {
|
inline To implicit_cast(const From& f) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
// Nokia's compiler can't tell which version of implicit_cast to use when
|
||||||
|
// the source is a const, causing the compilation to fail with the error
|
||||||
|
// "ambiguous access to overloaded function". So we only support the const
|
||||||
|
// version of implicit_cast on Symbian.
|
||||||
|
#if !GTEST_OS_SYMBIAN
|
||||||
|
// This overload is needed in case the From type has a non-const type
|
||||||
|
// conversion operator to type To.
|
||||||
|
template<typename To, typename From>
|
||||||
|
inline To implicit_cast(From& f) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// When you upcast (that is, cast a pointer from type Foo to type
|
// When you upcast (that is, cast a pointer from type Foo to type
|
||||||
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
|
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
|
||||||
|
@ -36,8 +36,139 @@
|
|||||||
#include <gmock/internal/gmock-port.h>
|
#include <gmock/internal/gmock-port.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
// This file intentionally contains no tests at this moment.
|
// NOTE: if this file is left without tests for some reason, put a dummy
|
||||||
|
// test here to make references to symbols in the gtest library and avoid
|
||||||
|
// 'undefined symbol' linker errors in gmock_main:
|
||||||
|
//
|
||||||
|
// TEST(DummyTest, Dummy) {}
|
||||||
|
|
||||||
// Putting a dummy test here makes references to symbols in the gtest
|
namespace testing {
|
||||||
// library and avoids 'undefined symbol' linker errors in gmock_main.
|
namespace internal {
|
||||||
TEST(DummyTest, Dummy) {}
|
// Needed to avoid name collisions in gmock_all_test.cc.
|
||||||
|
namespace gmock_port_test {
|
||||||
|
|
||||||
|
class Base {
|
||||||
|
public:
|
||||||
|
// Copy constructor and assignment operator do exactly what we need, so we
|
||||||
|
// use them.
|
||||||
|
Base() : member_(0) {}
|
||||||
|
explicit Base(int n) : member_(n) {}
|
||||||
|
virtual ~Base() {}
|
||||||
|
int member() { return member_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int member_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Base {
|
||||||
|
public:
|
||||||
|
explicit Derived(int n) : Base(n) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ImplicitCastTest, ConvertsPointers) {
|
||||||
|
Derived derived(0);
|
||||||
|
EXPECT_TRUE(&derived == ::testing::internal::implicit_cast<Base*>(&derived));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ImplicitCastTest, CanUseInheritance) {
|
||||||
|
Derived derived(1);
|
||||||
|
Base base = ::testing::internal::implicit_cast<Base>(derived);
|
||||||
|
EXPECT_EQ(derived.member(), base.member());
|
||||||
|
}
|
||||||
|
|
||||||
|
// The non-const version is not enabled for Symbian since the Nokia compiler
|
||||||
|
// cannot decide which version of the overloaded implicit_cast method to use
|
||||||
|
// when the source is a const.
|
||||||
|
#if !GTEST_OS_SYMBIAN
|
||||||
|
class Castable {
|
||||||
|
public:
|
||||||
|
Castable(bool* converted) : converted_(converted) {}
|
||||||
|
operator Base() {
|
||||||
|
*converted_ = true;
|
||||||
|
return Base();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool* const converted_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ImplicitCastTest, CanUseNonConstCastOperator) {
|
||||||
|
bool converted = false;
|
||||||
|
Castable castable(&converted);
|
||||||
|
Base base = ::testing::internal::implicit_cast<Base>(castable);
|
||||||
|
EXPECT_TRUE(converted);
|
||||||
|
}
|
||||||
|
#endif // !GTEST_OS_SYMBIAN
|
||||||
|
|
||||||
|
class ConstCastable {
|
||||||
|
public:
|
||||||
|
ConstCastable(bool* converted) : converted_(converted) {}
|
||||||
|
operator Base() const {
|
||||||
|
*converted_ = true;
|
||||||
|
return Base();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool* const converted_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) {
|
||||||
|
bool converted = false;
|
||||||
|
const ConstCastable const_castable(&converted);
|
||||||
|
Base base = ::testing::internal::implicit_cast<Base>(const_castable);
|
||||||
|
EXPECT_TRUE(converted);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The non-const version is not enabled for Symbian since the Nokia compiler
|
||||||
|
// cannot decide which version of the overloaded implicit_cast method to use
|
||||||
|
// when the source is a const.
|
||||||
|
#if !GTEST_OS_SYMBIAN
|
||||||
|
class ConstAndNonConstCastable {
|
||||||
|
public:
|
||||||
|
ConstAndNonConstCastable(bool* converted, bool* const_converted)
|
||||||
|
: converted_(converted), const_converted_(const_converted) {}
|
||||||
|
operator Base() {
|
||||||
|
*converted_ = true;
|
||||||
|
return Base();
|
||||||
|
}
|
||||||
|
operator Base() const {
|
||||||
|
*const_converted_ = true;
|
||||||
|
return Base();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool* const converted_;
|
||||||
|
bool* const const_converted_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) {
|
||||||
|
bool converted = false;
|
||||||
|
bool const_converted = false;
|
||||||
|
ConstAndNonConstCastable castable(&converted, &const_converted);
|
||||||
|
Base base = ::testing::internal::implicit_cast<Base>(castable);
|
||||||
|
EXPECT_TRUE(converted);
|
||||||
|
EXPECT_FALSE(const_converted);
|
||||||
|
|
||||||
|
converted = false;
|
||||||
|
const_converted = false;
|
||||||
|
const ConstAndNonConstCastable const_castable(&converted, &const_converted);
|
||||||
|
base = ::testing::internal::implicit_cast<Base>(const_castable);
|
||||||
|
EXPECT_FALSE(converted);
|
||||||
|
EXPECT_TRUE(const_converted);
|
||||||
|
}
|
||||||
|
#endif // !GTEST_OS_SYMBIAN
|
||||||
|
|
||||||
|
class To {
|
||||||
|
public:
|
||||||
|
To(bool* converted) { *converted = true; } // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ImplicitCastTest, CanUseImplicitConstructor) {
|
||||||
|
bool converted = false;
|
||||||
|
To to = ::testing::internal::implicit_cast<To>(&converted);
|
||||||
|
EXPECT_TRUE(converted);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gmock_port_test
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
Loading…
Reference in New Issue
Block a user