gmock-matchers merging -2
This commit is contained in:
		@@ -179,6 +179,35 @@ class MatcherInterface : public MatcherDescriberInterface {
 | 
			
		||||
  //   virtual void DescribeNegationTo(::std::ostream* os) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace internal {
 | 
			
		||||
 | 
			
		||||
// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
 | 
			
		||||
template <typename T>
 | 
			
		||||
class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
 | 
			
		||||
      : impl_(impl) {}
 | 
			
		||||
  virtual ~MatcherInterfaceAdapter() { delete impl_; }
 | 
			
		||||
 | 
			
		||||
  virtual void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
 | 
			
		||||
 | 
			
		||||
  virtual void DescribeNegationTo(::std::ostream* os) const {
 | 
			
		||||
    impl_->DescribeNegationTo(os);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual bool MatchAndExplain(const T& x,
 | 
			
		||||
                               MatchResultListener* listener) const {
 | 
			
		||||
    return impl_->MatchAndExplain(x, listener);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const MatcherInterface<T>* const impl_;
 | 
			
		||||
 | 
			
		||||
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace internal
 | 
			
		||||
 | 
			
		||||
// A match result listener that stores the explanation in a string.
 | 
			
		||||
class StringMatchResultListener : public MatchResultListener {
 | 
			
		||||
 public:
 | 
			
		||||
@@ -290,6 +319,14 @@ class MatcherBase {
 | 
			
		||||
  explicit MatcherBase(const MatcherInterface<T>* impl)
 | 
			
		||||
      : impl_(impl) {}
 | 
			
		||||
 | 
			
		||||
  template <typename U>
 | 
			
		||||
  explicit MatcherBase(
 | 
			
		||||
      const MatcherInterface<U>* impl,
 | 
			
		||||
      typename internal::EnableIf<
 | 
			
		||||
          !internal::IsSame<U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* =
 | 
			
		||||
          NULL)
 | 
			
		||||
      : impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
 | 
			
		||||
 | 
			
		||||
  virtual ~MatcherBase() {}
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
@@ -551,21 +588,18 @@ class MatcherCastImpl {
 | 
			
		||||
    return CastImpl(
 | 
			
		||||
        polymorphic_matcher_or_value,
 | 
			
		||||
        BooleanConstant<
 | 
			
		||||
            internal::ImplicitlyConvertible<M, Matcher<T> >::value>());
 | 
			
		||||
            internal::ImplicitlyConvertible<M, Matcher<T> >::value>(),
 | 
			
		||||
        BooleanConstant<
 | 
			
		||||
            internal::ImplicitlyConvertible<M, T>::value>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  static Matcher<T> CastImpl(const M& value, BooleanConstant<false>) {
 | 
			
		||||
    // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
 | 
			
		||||
    // matcher.  It must be a value then.  Use direct initialization to create
 | 
			
		||||
    // a matcher.
 | 
			
		||||
    return Matcher<T>(ImplicitCast_<T>(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <bool Ignore>
 | 
			
		||||
  static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
 | 
			
		||||
                             BooleanConstant<true>) {
 | 
			
		||||
                             BooleanConstant<true> /* convertible_to_matcher */,
 | 
			
		||||
                             BooleanConstant<Ignore>) {
 | 
			
		||||
    // M is implicitly convertible to Matcher<T>, which means that either
 | 
			
		||||
    // M is a polymorhpic matcher or Matcher<T> has an implicit constructor
 | 
			
		||||
    // M is a polymorphic matcher or Matcher<T> has an implicit constructor
 | 
			
		||||
    // from M.  In both cases using the implicit conversion will produce a
 | 
			
		||||
    // matcher.
 | 
			
		||||
    //
 | 
			
		||||
@@ -574,6 +608,29 @@ class MatcherCastImpl {
 | 
			
		||||
    // (first to create T from M and then to create Matcher<T> from T).
 | 
			
		||||
    return polymorphic_matcher_or_value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
 | 
			
		||||
  // matcher. It's a value of a type implicitly convertible to T. Use direct
 | 
			
		||||
  // initialization to create a matcher.
 | 
			
		||||
  static Matcher<T> CastImpl(
 | 
			
		||||
      const M& value, BooleanConstant<false> /* convertible_to_matcher */,
 | 
			
		||||
      BooleanConstant<true> /* convertible_to_T */) {
 | 
			
		||||
    return Matcher<T>(ImplicitCast_<T>(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // M can't be implicitly converted to either Matcher<T> or T. Attempt to use
 | 
			
		||||
  // polymorphic matcher Eq(value) in this case.
 | 
			
		||||
  //
 | 
			
		||||
  // Note that we first attempt to perform an implicit cast on the value and
 | 
			
		||||
  // only fall back to the polymorphic Eq() matcher afterwards because the
 | 
			
		||||
  // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end
 | 
			
		||||
  // which might be undefined even when Rhs is implicitly convertible to Lhs
 | 
			
		||||
  // (e.g. std::pair<const int, int> vs. std::pair<int, int>).
 | 
			
		||||
  //
 | 
			
		||||
  // We don't define this method inline as we need the declaration of Eq().
 | 
			
		||||
  static Matcher<T> CastImpl(
 | 
			
		||||
      const M& value, BooleanConstant<false> /* convertible_to_matcher */,
 | 
			
		||||
      BooleanConstant<false> /* convertible_to_T */);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This more specialized version is used when MatcherCast()'s argument
 | 
			
		||||
@@ -2057,6 +2114,78 @@ class FloatingEqMatcher {
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// A 2-tuple ("binary") wrapper around FloatingEqMatcher:
 | 
			
		||||
// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)
 | 
			
		||||
// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)
 | 
			
		||||
// against y. The former implements "Eq", the latter "Near". At present, there
 | 
			
		||||
// is no version that compares NaNs as equal.
 | 
			
		||||
template <typename FloatType>
 | 
			
		||||
class FloatingEq2Matcher {
 | 
			
		||||
 public:
 | 
			
		||||
  FloatingEq2Matcher() : FloatingEq2Matcher(-1, false) {}
 | 
			
		||||
 | 
			
		||||
  explicit FloatingEq2Matcher(bool nan_eq_nan)
 | 
			
		||||
      : FloatingEq2Matcher(-1, nan_eq_nan) {}
 | 
			
		||||
 | 
			
		||||
  explicit FloatingEq2Matcher(FloatType max_abs_error)
 | 
			
		||||
      : FloatingEq2Matcher(max_abs_error, false) {}
 | 
			
		||||
 | 
			
		||||
  FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan)
 | 
			
		||||
      : max_abs_error_(max_abs_error),
 | 
			
		||||
        nan_eq_nan_(nan_eq_nan) {}
 | 
			
		||||
 | 
			
		||||
  template <typename T1, typename T2>
 | 
			
		||||
  operator Matcher< ::testing::tuple<T1, T2> >() const {
 | 
			
		||||
    return MakeMatcher(
 | 
			
		||||
        new Impl< ::testing::tuple<T1, T2> >(max_abs_error_, nan_eq_nan_));
 | 
			
		||||
  }
 | 
			
		||||
  template <typename T1, typename T2>
 | 
			
		||||
  operator Matcher<const ::testing::tuple<T1, T2>&>() const {
 | 
			
		||||
    return MakeMatcher(
 | 
			
		||||
        new Impl<const ::testing::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT
 | 
			
		||||
    return os << "an almost-equal pair";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename Tuple>
 | 
			
		||||
  class Impl : public MatcherInterface<Tuple> {
 | 
			
		||||
   public:
 | 
			
		||||
    Impl(FloatType max_abs_error, bool nan_eq_nan) :
 | 
			
		||||
        max_abs_error_(max_abs_error),
 | 
			
		||||
        nan_eq_nan_(nan_eq_nan) {}
 | 
			
		||||
 | 
			
		||||
    virtual bool MatchAndExplain(Tuple args,
 | 
			
		||||
                                 MatchResultListener* listener) const {
 | 
			
		||||
      if (max_abs_error_ == -1) {
 | 
			
		||||
        FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_);
 | 
			
		||||
        return static_cast<Matcher<FloatType> >(fm).MatchAndExplain(
 | 
			
		||||
            ::testing::get<1>(args), listener);
 | 
			
		||||
      } else {
 | 
			
		||||
        FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_,
 | 
			
		||||
                                        max_abs_error_);
 | 
			
		||||
        return static_cast<Matcher<FloatType> >(fm).MatchAndExplain(
 | 
			
		||||
            ::testing::get<1>(args), listener);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    virtual void DescribeTo(::std::ostream* os) const {
 | 
			
		||||
      *os << "are " << GetDesc;
 | 
			
		||||
    }
 | 
			
		||||
    virtual void DescribeNegationTo(::std::ostream* os) const {
 | 
			
		||||
      *os << "aren't " << GetDesc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
    FloatType max_abs_error_;
 | 
			
		||||
    const bool nan_eq_nan_;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  FloatType max_abs_error_;
 | 
			
		||||
  const bool nan_eq_nan_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implements the Pointee(m) matcher for matching a pointer whose
 | 
			
		||||
// pointee matches matcher m.  The pointer can be either raw or smart.
 | 
			
		||||
template <typename InnerMatcher>
 | 
			
		||||
@@ -2953,6 +3082,50 @@ class EachMatcher {
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(EachMatcher);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Rank1 {};
 | 
			
		||||
struct Rank0 : Rank1 {};
 | 
			
		||||
 | 
			
		||||
namespace pair_getters {
 | 
			
		||||
#if GTEST_LANG_CXX11
 | 
			
		||||
using std::get;
 | 
			
		||||
template <typename T>
 | 
			
		||||
auto First(T& x, Rank1) -> decltype(get<0>(x)) {  // NOLINT
 | 
			
		||||
  return get<0>(x);
 | 
			
		||||
}
 | 
			
		||||
template <typename T>
 | 
			
		||||
auto First(T& x, Rank0) -> decltype((x.first)) {  // NOLINT
 | 
			
		||||
  return x.first;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
auto Second(T& x, Rank1) -> decltype(get<1>(x)) {  // NOLINT
 | 
			
		||||
  return get<1>(x);
 | 
			
		||||
}
 | 
			
		||||
template <typename T>
 | 
			
		||||
auto Second(T& x, Rank0) -> decltype((x.second)) {  // NOLINT
 | 
			
		||||
  return x.second;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
template <typename T>
 | 
			
		||||
typename T::first_type& First(T& x, Rank0) {  // NOLINT
 | 
			
		||||
  return x.first;
 | 
			
		||||
}
 | 
			
		||||
template <typename T>
 | 
			
		||||
const typename T::first_type& First(const T& x, Rank0) {
 | 
			
		||||
  return x.first;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
typename T::second_type& Second(T& x, Rank0) {  // NOLINT
 | 
			
		||||
  return x.second;
 | 
			
		||||
}
 | 
			
		||||
template <typename T>
 | 
			
		||||
const typename T::second_type& Second(const T& x, Rank0) {
 | 
			
		||||
  return x.second;
 | 
			
		||||
}
 | 
			
		||||
#endif  // GTEST_LANG_CXX11
 | 
			
		||||
}  // namespace pair_getters
 | 
			
		||||
 | 
			
		||||
// Implements Key(inner_matcher) for the given argument pair type.
 | 
			
		||||
// Key(inner_matcher) matches an std::pair whose 'first' field matches
 | 
			
		||||
// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an
 | 
			
		||||
@@ -3717,6 +3890,65 @@ class VariantMatcher {
 | 
			
		||||
 | 
			
		||||
}  // namespace variant_matcher
 | 
			
		||||
 | 
			
		||||
namespace any_cast_matcher {
 | 
			
		||||
 | 
			
		||||
// Overloads to allow AnyCastMatcher to do proper ADL lookup.
 | 
			
		||||
template <typename T>
 | 
			
		||||
void any_cast() {}
 | 
			
		||||
 | 
			
		||||
// Implements a matcher that any_casts the value.
 | 
			
		||||
template <typename T>
 | 
			
		||||
class AnyCastMatcher {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)
 | 
			
		||||
      : matcher_(matcher) {}
 | 
			
		||||
 | 
			
		||||
  template <typename AnyType>
 | 
			
		||||
  bool MatchAndExplain(const AnyType& value,
 | 
			
		||||
                       ::testing::MatchResultListener* listener) const {
 | 
			
		||||
    if (!listener->IsInterested()) {
 | 
			
		||||
      const T* ptr = any_cast<T>(&value);
 | 
			
		||||
      return ptr != NULL && matcher_.Matches(*ptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const T* elem = any_cast<T>(&value);
 | 
			
		||||
    if (elem == NULL) {
 | 
			
		||||
      *listener << "whose value is not of type '" << GetTypeName() << "'";
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    StringMatchResultListener elem_listener;
 | 
			
		||||
    const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);
 | 
			
		||||
    *listener << "whose value " << PrintToString(*elem)
 | 
			
		||||
              << (match ? " matches" : " doesn't match");
 | 
			
		||||
    PrintIfNotEmpty(elem_listener.str(), listener->stream());
 | 
			
		||||
    return match;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void DescribeTo(std::ostream* os) const {
 | 
			
		||||
    *os << "is an 'any' type with value of type '" << GetTypeName()
 | 
			
		||||
        << "' and the value ";
 | 
			
		||||
    matcher_.DescribeTo(os);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void DescribeNegationTo(std::ostream* os) const {
 | 
			
		||||
    *os << "is an 'any' type with value of type other than '" << GetTypeName()
 | 
			
		||||
        << "' or the value ";
 | 
			
		||||
    matcher_.DescribeNegationTo(os);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  static std::string GetTypeName() {
 | 
			
		||||
#if GTEST_HAS_RTTI
 | 
			
		||||
    return internal::GetTypeName<T>();
 | 
			
		||||
#endif
 | 
			
		||||
    return "the element type";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const ::testing::Matcher<const T&> matcher_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace any_cast_matcher
 | 
			
		||||
}  // namespace internal
 | 
			
		||||
 | 
			
		||||
// ElementsAreArray(iterator_first, iterator_last)
 | 
			
		||||
@@ -3848,6 +4080,14 @@ inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
 | 
			
		||||
template <typename T>
 | 
			
		||||
Matcher<T>::Matcher(T value) { *this = Eq(value); }
 | 
			
		||||
 | 
			
		||||
template <typename T, typename M>
 | 
			
		||||
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
 | 
			
		||||
    const M& value,
 | 
			
		||||
    internal::BooleanConstant<false> /* convertible_to_matcher */,
 | 
			
		||||
    internal::BooleanConstant<false> /* convertible_to_T */) {
 | 
			
		||||
  return Eq(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Creates a monomorphic matcher that matches anything with type Lhs
 | 
			
		||||
// and equal to rhs.  A user may need to use this instead of Eq(...)
 | 
			
		||||
// in order to resolve an overloading ambiguity.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user