Merge pull request #2597 from kuzkry:remove-workaround_Nokia-Sybian-SafeMatcherCastImpl

PiperOrigin-RevId: 282581402
This commit is contained in:
Gennadiy Rozental 2019-11-26 15:47:21 -05:00
commit db13ff1f0b

View File

@ -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.