@@ -2855,6 +2855,54 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
2855
2855
}
2856
2856
};
2857
2857
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
+
2858
2906
// Implements Each(element_matcher) for the given argument type Container.
2859
2907
// Symmetric to ContainsMatcherImpl.
2860
2908
template <typename Container>
@@ -2990,6 +3038,50 @@ auto Second(T& x, Rank1) -> decltype((x.second)) { // NOLINT
2990
3038
}
2991
3039
} // namespace pair_getters
2992
3040
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
+
2993
3085
// Implements Key(inner_matcher) for the given argument pair type.
2994
3086
// Key(inner_matcher) matches an std::pair whose 'first' field matches
2995
3087
// 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,
4372
4464
return internal::FloatingEqMatcher<double >(rhs, false , max_abs_error);
4373
4465
}
4374
4466
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
+
4375
4503
// Creates a matcher that matches any double argument approximately equal to
4376
4504
// rhs, up to the specified max absolute error bound, including NaN values when
4377
4505
// rhs is NaN. The max absolute error bound must be non-negative.
0 commit comments