1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use common_range_tools::{CpCmp, IncDecCpCmp, Intersector, RiFactory};
#[derive(Clone, Copy, Debug)]
struct Point {
p: i32,
}
const MIN: Point = Point { p: 0 };
const MAX: Point = Point { p: 8 };
struct CustomIncDecCpCmp {}
impl CpCmp<Point> for CustomIncDecCpCmp {
// a way to copy or clone the current struct is required!
fn cp(&self, v: &Point) -> Point {
return v.clone();
}
// All compare operations can be derived from either lt or gt.
// The only compare method that is required to be implemented
// for this trait is the lt operator.
fn lt(&self, a: &Point, b: &Point) -> bool {
a.p < b.p
}
fn min(&self) -> Point {
return MIN;
}
fn max(&self) -> Point {
return MAX;
}
fn min_ref(&self) -> &Point {
&MIN
}
fn max_ref(&self) -> &Point {
&MAX
}
}
impl IncDecCpCmp<Point, Point> for CustomIncDecCpCmp {
fn inc(&self, a: &Point, b: &Point) -> Option<Point> {
match a.p.checked_add(b.p) {
Some(x) => Some(Point { p: x }),
None => None,
}
}
fn dec(&self, a: &Point, b: &Point) -> Option<Point> {
match a.p.checked_sub(b.p) {
Some(x) => Some(Point { p: x }),
None => None,
}
}
fn cp_v(&self, v: &Point) -> Point {
return *v;
}
}
fn main() {
let t = CustomIncDecCpCmp {};
let mut isec = Intersector::new(
Vec::new(), // Container for our internal ranges
Point { p: 1 }, // step
Point { p: 1 }, // Rebound value
t, // our compare instance
RiFactory::new(), // Factory used to construct new ranges
);
// Note: an internal RangeInclusive instance is
// generated for every range that is successfully added.
// This means it is safe to drop the orginal range values
// after they are loaded into the Intersector instance.
isec.add_range(&(..Point { p: 2 }));
isec.add_range(&(Point { p: 1 }..Point { p: 3 }));
isec.add_range(&(Point { p: 3 }..=Point { p: 4 }));
isec.add_range(&(Point { p: 3 }..));
for r in isec.into_iter() {
println!("X: {:?}, Y: {:?}", r.start(), r.end());
}
// Output will be:
// X: Point { p: 0 }, Y: Point { p: 0 }
// X: Point { p: 1 }, Y: Point { p: 1 }
// X: Point { p: 2 }, Y: Point { p: 2 }
// X: Point { p: 3 }, Y: Point { p: 4 }
// X: Point { p: 5 }, Y: Point { p: 8 }
}