@@ -2855,6 +2855,54 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
28552855 }
28562856};
28572857
2858+ // Implements DistanceFrom(target, get_distance, distance_matcher) for the given
2859+ // argument types:
2860+ // * V is the type of the value to be matched.
2861+ // * T is the type of the target value.
2862+ // * Distance is the type of the distance between V and T.
2863+ // * GetDistance is the type of the functor for computing the distance between
2864+ // V and T.
2865+ template <typename V, typename T, typename Distance, typename GetDistance>
2866+ class DistanceFromMatcherImpl : public MatcherInterface <V> {
2867+ public:
2868+ // Arguments:
2869+ // * target: the target value.
2870+ // * get_distance: the functor for computing the distance between the value
2871+ // being matched and target.
2872+ // * distance_matcher: the matcher for checking the distance.
2873+ DistanceFromMatcherImpl (T target, GetDistance get_distance,
2874+ Matcher<const Distance&> distance_matcher)
2875+ : target_(std::move(target)),
2876+ get_distance_ (std::move(get_distance)),
2877+ distance_matcher_(std::move(distance_matcher)) {}
2878+
2879+ // Describes what this matcher does.
2880+ void DescribeTo (::std::ostream* os) const override {
2881+ distance_matcher_.DescribeTo (os);
2882+ *os << " away from " << PrintToString (target_);
2883+ }
2884+
2885+ void DescribeNegationTo (::std::ostream* os) const override {
2886+ distance_matcher_.DescribeNegationTo (os);
2887+ *os << " away from " << PrintToString (target_);
2888+ }
2889+
2890+ bool MatchAndExplain (V value, MatchResultListener* listener) const override {
2891+ const auto distance = get_distance_ (value, target_);
2892+ const bool match = distance_matcher_.Matches (distance);
2893+ if (!match && listener->IsInterested ()) {
2894+ *listener << " which is " << PrintToString (distance) << " away from "
2895+ << PrintToString (target_);
2896+ }
2897+ return match;
2898+ }
2899+
2900+ private:
2901+ const T target_;
2902+ const GetDistance get_distance_;
2903+ const Matcher<const Distance&> distance_matcher_;
2904+ };
2905+
28582906// Implements Each(element_matcher) for the given argument type Container.
28592907// Symmetric to ContainsMatcherImpl.
28602908template <typename Container>
@@ -2990,6 +3038,50 @@ auto Second(T& x, Rank1) -> decltype((x.second)) { // NOLINT
29903038}
29913039} // namespace pair_getters
29923040
3041+ // Default functor for computing the distance between two values.
3042+ struct DefaultGetDistance {
3043+ template <typename T, typename U>
3044+ auto operator ()(const T& lhs, const U& rhs) const {
3045+ return std::abs (lhs - rhs);
3046+ }
3047+ };
3048+
3049+ // Implements polymorphic DistanceFrom(target, get_distance, distance_matcher)
3050+ // matcher. Template arguments:
3051+ // * T is the type of the target value.
3052+ // * GetDistance is the type of the functor for computing the distance between
3053+ // the value being matched and the target.
3054+ // * DistanceMatcher is the type of the matcher for checking the distance.
3055+ template <typename T, typename GetDistance, typename DistanceMatcher>
3056+ class DistanceFromMatcher {
3057+ public:
3058+ // Arguments:
3059+ // * target: the target value.
3060+ // * get_distance: the functor for computing the distance between the value
3061+ // being matched and target.
3062+ // * distance_matcher: the matcher for checking the distance.
3063+ DistanceFromMatcher (T target, GetDistance get_distance,
3064+ DistanceMatcher distance_matcher)
3065+ : target_(std::move(target)),
3066+ get_distance_ (std::move(get_distance)),
3067+ distance_matcher_(std::move(distance_matcher)) {}
3068+
3069+ DistanceFromMatcher (const DistanceFromMatcher& other) = default;
3070+
3071+ // Implicitly converts to a monomorphic matcher of the given type.
3072+ template <typename V>
3073+ operator Matcher<V>() const { // NOLINT
3074+ using Distance = decltype (get_distance_ (std::declval<V>(), target_));
3075+ return Matcher<V>(new DistanceFromMatcherImpl<V, T, Distance, GetDistance>(
3076+ target_, get_distance_, distance_matcher_));
3077+ }
3078+
3079+ private:
3080+ const T target_;
3081+ const GetDistance get_distance_;
3082+ const DistanceMatcher distance_matcher_;
3083+ };
3084+
29933085// Implements Key(inner_matcher) for the given argument pair type.
29943086// Key(inner_matcher) matches an std::pair whose 'first' field matches
29953087// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
@@ -4372,6 +4464,42 @@ inline internal::FloatingEqMatcher<double> DoubleNear(double rhs,
43724464 return internal::FloatingEqMatcher<double >(rhs, false , max_abs_error);
43734465}
43744466
4467+ // The DistanceFrom(target, get_distance, m) and DistanceFrom(target, m)
4468+ // matchers work on arbitrary types that have the "distance" concept. What they
4469+ // do:
4470+ //
4471+ // 1. compute the distance between the value and the target using
4472+ // get_distance(value, target) if get_distance is provided; otherwise compute
4473+ // the distance as std::abs(value - target).
4474+ // 2. match the distance against the user-provided matcher m; if the match
4475+ // succeeds, the DistanceFrom() match succeeds.
4476+ //
4477+ // Examples:
4478+ //
4479+ // // 0.5's distance from 0.6 should be <= 0.2.
4480+ // EXPECT_THAT(0.5, DistanceFrom(0.6, Le(0.2)));
4481+ //
4482+ // Vector2D v1(3.0, 4.0), v2(3.2, 6.0);
4483+ // // v1's distance from v2, as computed by EuclideanDistance(v1, v2),
4484+ // // should be >= 1.0.
4485+ // EXPECT_THAT(v1, DistanceFrom(v2, EuclideanDistance, Ge(1.0)));
4486+
4487+ template <typename T, typename GetDistance, typename DistanceMatcher>
4488+ inline internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>
4489+ DistanceFrom (T target, GetDistance get_distance,
4490+ DistanceMatcher distance_matcher) {
4491+ return internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>(
4492+ std::move (target), std::move (get_distance), std::move (distance_matcher));
4493+ }
4494+
4495+ template <typename T, typename DistanceMatcher>
4496+ inline internal::DistanceFromMatcher<T, internal::DefaultGetDistance,
4497+ DistanceMatcher>
4498+ DistanceFrom (T target, DistanceMatcher distance_matcher) {
4499+ return DistanceFrom (std::move (target), internal::DefaultGetDistance (),
4500+ std::move (distance_matcher));
4501+ }
4502+
43754503// Creates a matcher that matches any double argument approximately equal to
43764504// rhs, up to the specified max absolute error bound, including NaN values when
43774505// rhs is NaN. The max absolute error bound must be non-negative.
0 commit comments