Skip to main content

geometry_algorithm/
clear.rs

1//! `clear(&mut g)` — empty the backing storage in place.
2//!
3//! Mirrors `boost::geometry::clear` from
4//! `boost/geometry/algorithms/clear.hpp`. Per-kind:
5//!
6//! * `Linestring`, `Ring`, `MultiPoint` → `Vec::clear` on the backing.
7//! * `Polygon` → clear the outer ring and drop every inner ring.
8//! * `MultiLinestring`, `MultiPolygon` → `Vec::clear` on the member
9//!   vector.
10//! * `Point`, `Box`, `Segment` → no impl (fixed-size storage — there
11//!   is nothing to clear).
12//!
13//! Boost ships the fixed-size case as a silent no-op fall-through
14//! (`clear.hpp`); the Rust port instead simply provides no [`Clear`]
15//! impl for `Point` / `Box` / `Segment`, so `clear(&mut point)` is a
16//! compile error — the type system says "call this on something that
17//! *has* clearable storage."
18
19use geometry_model::{Linestring, MultiLinestring, MultiPoint, MultiPolygon, Polygon, Ring};
20
21/// Empty the backing storage of `g` in place.
22///
23/// Mirrors `boost::geometry::clear(g)` from
24/// `boost/geometry/algorithms/clear.hpp`. Not defined for `Point`,
25/// `Box`, or `Segment` (fixed-size storage — see the module docs).
26pub fn clear<G: Clear>(g: &mut G) {
27    g.clear();
28}
29
30/// Per-kind clear dispatch. Implemented only for the variable-length
31/// kinds; fixed-size kinds (`Point`, `Box`, `Segment`) are
32/// intentionally absent so clearing them fails to compile.
33#[doc(hidden)]
34pub trait Clear {
35    fn clear(&mut self);
36}
37
38impl<P: geometry_trait::Point> Clear for Linestring<P> {
39    fn clear(&mut self) {
40        self.0.clear();
41    }
42}
43
44impl<P: geometry_trait::Point, const CW: bool, const CL: bool> Clear for Ring<P, CW, CL> {
45    fn clear(&mut self) {
46        self.0.clear();
47    }
48}
49
50impl<P: geometry_trait::Point, const CW: bool, const CL: bool> Clear for Polygon<P, CW, CL> {
51    fn clear(&mut self) {
52        self.outer.0.clear();
53        self.inners.clear();
54    }
55}
56
57impl<P: geometry_trait::Point> Clear for MultiPoint<P> {
58    fn clear(&mut self) {
59        self.0.clear();
60    }
61}
62
63impl<L: geometry_trait::Linestring> Clear for MultiLinestring<L> {
64    fn clear(&mut self) {
65        self.0.clear();
66    }
67}
68
69impl<Pg: geometry_trait::Polygon> Clear for MultiPolygon<Pg> {
70    fn clear(&mut self) {
71        self.0.clear();
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    //! Behaviour cross-checked against
78    //! [`crate::is_empty`]: a cleared geometry reports
79    //! empty, and `Polygon::clear` drops both the outer ring's points
80    //! and every inner ring.
81
82    use super::clear;
83    use crate::is_empty::is_empty;
84    use geometry_cs::Cartesian;
85    use geometry_model::{Linestring, MultiPoint, Point2D, Polygon, linestring, polygon};
86
87    type Pt = Point2D<f64, Cartesian>;
88
89    #[test]
90    fn clear_linestring() {
91        let mut ls: Linestring<Pt> = linestring![(0., 0.), (1., 1.), (2., 2.)];
92        clear(&mut ls);
93        assert!(is_empty(&ls));
94    }
95
96    #[test]
97    fn clear_polygon_drops_both_rings_and_holes() {
98        let mut pg: Polygon<Pt> = polygon![
99            [(0., 0.), (5., 0.), (5., 5.), (0., 0.)],
100            [(1., 1.), (2., 1.), (2., 2.), (1., 1.)],
101        ];
102        clear(&mut pg);
103        assert!(is_empty(&pg));
104        assert_eq!(pg.inners.len(), 0);
105    }
106
107    #[test]
108    fn clear_multi_point() {
109        let mut mp = MultiPoint(alloc::vec![Pt::new(0., 0.), Pt::new(1., 1.)]);
110        clear(&mut mp);
111        assert_eq!(mp.0.len(), 0);
112    }
113}