|
|
|
@ -247,56 +247,43 @@ inline Matcher<T> MatcherCast(const M& matcher) { |
|
|
|
|
return internal::MatcherCastImpl<T, M>::Cast(matcher); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Implements SafeMatcherCast().
|
|
|
|
|
//
|
|
|
|
|
// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a
|
|
|
|
|
// workaround for a compiler bug, and can now be removed.
|
|
|
|
|
template <typename T> |
|
|
|
|
class SafeMatcherCastImpl { |
|
|
|
|
public: |
|
|
|
|
// This overload handles polymorphic matchers and values only since
|
|
|
|
|
// monomorphic matchers are handled by the next one.
|
|
|
|
|
template <typename M> |
|
|
|
|
static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) { |
|
|
|
|
return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This overload handles monomorphic matchers.
|
|
|
|
|
//
|
|
|
|
|
// In general, if type T can be implicitly converted to type U, we can
|
|
|
|
|
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
|
|
|
|
|
// contravariant): just keep a copy of the original Matcher<U>, convert the
|
|
|
|
|
// argument from type T to U, and then pass it to the underlying Matcher<U>.
|
|
|
|
|
// The only exception is when U is a reference and T is not, as the
|
|
|
|
|
// underlying Matcher<U> may be interested in the argument's address, which
|
|
|
|
|
// is not preserved in the conversion from T to U.
|
|
|
|
|
template <typename U> |
|
|
|
|
static inline Matcher<T> Cast(const Matcher<U>& matcher) { |
|
|
|
|
// Enforce that T can be implicitly converted to U.
|
|
|
|
|
GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value), |
|
|
|
|
"T must be implicitly convertible to U"); |
|
|
|
|
// Enforce that we are not converting a non-reference type T to a reference
|
|
|
|
|
// type U.
|
|
|
|
|
GTEST_COMPILE_ASSERT_( |
|
|
|
|
std::is_reference<T>::value || !std::is_reference<U>::value, |
|
|
|
|
cannot_convert_non_reference_arg_to_reference); |
|
|
|
|
// In case both T and U are arithmetic types, enforce that the
|
|
|
|
|
// conversion is not lossy.
|
|
|
|
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; |
|
|
|
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; |
|
|
|
|
const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; |
|
|
|
|
const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; |
|
|
|
|
GTEST_COMPILE_ASSERT_( |
|
|
|
|
kTIsOther || kUIsOther || |
|
|
|
|
(internal::LosslessArithmeticConvertible<RawT, RawU>::value), |
|
|
|
|
conversion_of_arithmetic_types_must_be_lossless); |
|
|
|
|
return MatcherCast<T>(matcher); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// This overload handles polymorphic matchers and values only since
|
|
|
|
|
// monomorphic matchers are handled by the next one.
|
|
|
|
|
template <typename T, typename M> |
|
|
|
|
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) { |
|
|
|
|
return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher); |
|
|
|
|
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) { |
|
|
|
|
return MatcherCast<T>(polymorphic_matcher_or_value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This overload handles monomorphic matchers.
|
|
|
|
|
//
|
|
|
|
|
// In general, if type T can be implicitly converted to type U, we can
|
|
|
|
|
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
|
|
|
|
|
// contravariant): just keep a copy of the original Matcher<U>, convert the
|
|
|
|
|
// argument from type T to U, and then pass it to the underlying Matcher<U>.
|
|
|
|
|
// The only exception is when U is a reference and T is not, as the
|
|
|
|
|
// underlying Matcher<U> may be interested in the argument's address, which
|
|
|
|
|
// is not preserved in the conversion from T to U.
|
|
|
|
|
template <typename T, typename U> |
|
|
|
|
inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) { |
|
|
|
|
// Enforce that T can be implicitly converted to U.
|
|
|
|
|
GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value), |
|
|
|
|
"T must be implicitly convertible to U"); |
|
|
|
|
// Enforce that we are not converting a non-reference type T to a reference
|
|
|
|
|
// type U.
|
|
|
|
|
GTEST_COMPILE_ASSERT_( |
|
|
|
|
std::is_reference<T>::value || !std::is_reference<U>::value, |
|
|
|
|
cannot_convert_non_reference_arg_to_reference); |
|
|
|
|
// In case both T and U are arithmetic types, enforce that the
|
|
|
|
|
// conversion is not lossy.
|
|
|
|
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; |
|
|
|
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; |
|
|
|
|
constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; |
|
|
|
|
constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; |
|
|
|
|
GTEST_COMPILE_ASSERT_( |
|
|
|
|
kTIsOther || kUIsOther || |
|
|
|
|
(internal::LosslessArithmeticConvertible<RawT, RawU>::value), |
|
|
|
|
conversion_of_arithmetic_types_must_be_lossless); |
|
|
|
|
return MatcherCast<T>(matcher); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// A<T>() returns a matcher that matches any value of type T.
|
|
|
|
|