Googletest export
Change Matcher<T> to allow binding an implementation by value directly: - Drop the requirement of MatcherInterface. Doing manual type erasure avoid extra layers in many cases. - Avoid the adaptor for `MatcherInterface<T>` and `MatcherInterface<const T&>` mismatch. - Use a small object optimization when possible. This makes things like `_` and `Eq(1)` really cheap and do not require memory allocations. - Migrate some matchers to the new model to speed them up and to test the new framework. More matchers to come in future changes. PiperOrigin-RevId: 350580998
This commit is contained in:
		@@ -735,31 +735,25 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {
 | 
			
		||||
  return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implements A<T>().
 | 
			
		||||
template <typename T>
 | 
			
		||||
class AnyMatcherImpl : public MatcherInterface<const T&> {
 | 
			
		||||
 public:
 | 
			
		||||
  bool MatchAndExplain(const T& /* x */,
 | 
			
		||||
                       MatchResultListener* /* listener */) const override {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  void DescribeTo(::std::ostream* os) const override { *os << "is anything"; }
 | 
			
		||||
  void DescribeNegationTo(::std::ostream* os) const override {
 | 
			
		||||
    // This is mostly for completeness' safe, as it's not very useful
 | 
			
		||||
    // to write Not(A<bool>()).  However we cannot completely rule out
 | 
			
		||||
    // such a possibility, and it doesn't hurt to be prepared.
 | 
			
		||||
    *os << "never matches";
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implements _, a matcher that matches any value of any
 | 
			
		||||
// type.  This is a polymorphic matcher, so we need a template type
 | 
			
		||||
// conversion operator to make it appearing as a Matcher<T> for any
 | 
			
		||||
// type T.
 | 
			
		||||
class AnythingMatcher {
 | 
			
		||||
 public:
 | 
			
		||||
  using is_gtest_matcher = void;
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  operator Matcher<T>() const { return A<T>(); }
 | 
			
		||||
  bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  void DescribeTo(std::ostream* os) const { *os << "is anything"; }
 | 
			
		||||
  void DescribeNegationTo(::std::ostream* os) const {
 | 
			
		||||
    // This is mostly for completeness' sake, as it's not very useful
 | 
			
		||||
    // to write Not(A<bool>()).  However we cannot completely rule out
 | 
			
		||||
    // such a possibility, and it doesn't hurt to be prepared.
 | 
			
		||||
    *os << "never matches";
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implements the polymorphic IsNull() matcher, which matches any raw or smart
 | 
			
		||||
@@ -3443,7 +3437,9 @@ class UnorderedElementsAreMatcherImpl
 | 
			
		||||
      : UnorderedElementsAreMatcherImplBase(matcher_flags) {
 | 
			
		||||
    for (; first != last; ++first) {
 | 
			
		||||
      matchers_.push_back(MatcherCast<const Element&>(*first));
 | 
			
		||||
      matcher_describers().push_back(matchers_.back().GetDescriber());
 | 
			
		||||
    }
 | 
			
		||||
    for (const auto& m : matchers_) {
 | 
			
		||||
      matcher_describers().push_back(m.GetDescriber());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -4068,12 +4064,14 @@ const internal::AnythingMatcher _ = {};
 | 
			
		||||
// Creates a matcher that matches any value of the given type T.
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline Matcher<T> A() {
 | 
			
		||||
  return Matcher<T>(new internal::AnyMatcherImpl<T>());
 | 
			
		||||
  return _;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Creates a matcher that matches any value of the given type T.
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline Matcher<T> An() { return A<T>(); }
 | 
			
		||||
inline Matcher<T> An() {
 | 
			
		||||
  return _;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, typename M>
 | 
			
		||||
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user