Merge pull request #2597 from kuzkry:remove-workaround_Nokia-Sybian-SafeMatcherCastImpl
PiperOrigin-RevId: 282581402
This commit is contained in:
		@@ -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.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user