Merge pull request #2597 from kuzkry:remove-workaround_Nokia-Sybian-SafeMatcherCastImpl
PiperOrigin-RevId: 282581402
This commit is contained in:
commit
db13ff1f0b
@ -247,56 +247,43 @@ inline Matcher<T> MatcherCast(const M& matcher) {
|
|||||||
return internal::MatcherCastImpl<T, M>::Cast(matcher);
|
return internal::MatcherCastImpl<T, M>::Cast(matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements SafeMatcherCast().
|
// This overload handles polymorphic matchers and values only since
|
||||||
//
|
// monomorphic matchers are handled by the next one.
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename M>
|
template <typename T, typename M>
|
||||||
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) {
|
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {
|
||||||
return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher);
|
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.
|
// A<T>() returns a matcher that matches any value of type T.
|
||||||
|
Loading…
Reference in New Issue
Block a user