Skip to main content

geometry_strategy/
reversal.rs

1//! Argument-order reversal for symmetric strategy concepts.
2//!
3//! Mirrors `boost::geometry::reverse_dispatch` from
4//! `core/reverse_dispatch.hpp` and the per-algorithm partial
5//! specialisations that consume it. Rust expresses the shared ordering
6//! decision as one wrapper with one impl per strategy concept.
7
8use geometry_trait::Geometry;
9
10use crate::distance::DistanceStrategy;
11use crate::intersects::IntersectsStrategy;
12
13/// Lift a strategy for `(A, B)` into the same strategy concept for `(B, A)`.
14///
15/// Mirrors `boost::geometry::reverse_dispatch<Geometry1, Geometry2>` from
16/// `core/reverse_dispatch.hpp:33-64`. Boost consults the ordering trait from
17/// each algorithm's dispatch specialisation; Rust implements each strategy
18/// concept on this single wrapper instead.
19#[derive(Debug, Default, Clone, Copy)]
20pub struct Reversed<S>(pub S);
21
22impl<A, B, S> DistanceStrategy<B, A> for Reversed<S>
23where
24    A: Geometry,
25    B: Geometry,
26    S: DistanceStrategy<A, B>,
27{
28    type Out = S::Out;
29    type Comparable = Reversed<S::Comparable>;
30
31    #[inline]
32    fn distance(&self, b: &B, a: &A) -> S::Out {
33        self.0.distance(a, b)
34    }
35
36    #[inline]
37    fn comparable(&self) -> Self::Comparable {
38        Reversed(self.0.comparable())
39    }
40}
41
42impl<A, B, S> IntersectsStrategy<B, A> for Reversed<S>
43where
44    S: IntersectsStrategy<A, B>,
45{
46    #[inline]
47    fn intersects(&self, b: &B, a: &A) -> bool {
48        self.0.intersects(a, b)
49    }
50}