1
+ #pragma once
2
+
3
+ #include " test_utility.hpp"
4
+ #include " multi_join_interval.hpp"
5
+
6
+ #include < ctime>
7
+ #include < random>
8
+ #include < cmath>
9
+ #include < functional>
10
+
11
+ class CustomIntervalTests : public ::testing::Test
12
+ {};
13
+
14
+ template <typename numerical_type, typename interval_kind_ = lib_interval_tree::closed>
15
+ struct custom_interval : public lib_interval_tree ::interval<numerical_type, interval_kind_>
16
+ {
17
+ public:
18
+ using value_type = numerical_type;
19
+ using interval_kind = interval_kind_;
20
+
21
+ using lib_interval_tree::interval<numerical_type, interval_kind_>::low_;
22
+ using lib_interval_tree::interval<numerical_type, interval_kind_>::high_;
23
+
24
+ /* *
25
+ * Constructs an custom_interval. low MUST be smaller than high.
26
+ */
27
+ custom_interval (value_type low, value_type high)
28
+ : lib_interval_tree::interval<numerical_type, interval_kind_>{low, high}
29
+ {}
30
+
31
+ std::function<bool (value_type, value_type)> on_overlaps;
32
+ bool overlaps (custom_interval const & other) const
33
+ {
34
+ if (on_overlaps)
35
+ return on_overlaps (other.low_ , other.high_ );
36
+ return interval_kind::overlaps (low_, high_, other.low_ , other.high_ );
37
+ }
38
+
39
+ std::function<bool (custom_interval const & other)> on_overlaps_exclusive_ival;
40
+ bool overlaps_exclusive (custom_interval const & other) const
41
+ {
42
+ if (on_overlaps_exclusive_ival)
43
+ return on_overlaps_exclusive_ival (other);
44
+ return low_ < other.high_ && other.low_ < high_;
45
+ }
46
+
47
+ std::function<custom_interval(custom_interval const & other)> on_join;
48
+ custom_interval join (custom_interval const & other) const
49
+ {
50
+ if (on_join)
51
+ return on_join (other);
52
+ return {std::min (low_, other.low_ ), std::max (high_, other.high_ )};
53
+ }
54
+ };
55
+
56
+ TEST_F (CustomIntervalTests, CanInsertCustomIntervalJoined)
57
+ {
58
+ lib_interval_tree::interval_tree<custom_interval<int >> tree;
59
+ tree.insert ({0 , 5 });
60
+ tree.insert_overlap ({4 , 10 });
61
+
62
+ ASSERT_EQ (tree.size (), 1 );
63
+ EXPECT_EQ (tree.begin ()->low (), 0 );
64
+ EXPECT_EQ (tree.begin ()->high (), 10 );
65
+ }
66
+
67
+ TEST_F (CustomIntervalTests, CustomJoinIsCalled)
68
+ {
69
+ lib_interval_tree::interval_tree<custom_interval<int >> tree;
70
+ auto ival1 = custom_interval<int >{0 , 5 };
71
+ auto ival2 = custom_interval<int >{4 , 10 };
72
+
73
+ bool join_called = false ;
74
+ ival1.on_join = [&](custom_interval<int > const & other) -> custom_interval<int > {
75
+ join_called = true ;
76
+ return {std::min (ival1.low_ , other.low_ ), std::max (ival1.high_ , other.high_ )};
77
+ };
78
+
79
+ tree.insert (ival1);
80
+ tree.insert_overlap (ival2);
81
+
82
+ EXPECT_TRUE (join_called);
83
+ }
84
+
85
+ TEST_F (CustomIntervalTests, CustomOverlapsIsCalled)
86
+ {
87
+ lib_interval_tree::interval_tree<custom_interval<int >> tree;
88
+ auto ival1 = custom_interval<int >{0 , 5 };
89
+ auto ival2 = custom_interval<int >{4 , 10 };
90
+
91
+ bool overlaps_called = false ;
92
+ ival1.on_overlaps = [&](int l, int h) -> bool {
93
+ overlaps_called = true ;
94
+ return custom_interval<int >::interval_kind::overlaps (ival1.low_ , ival1.high_ , l, h);
95
+ };
96
+
97
+ tree.insert (ival1);
98
+ tree.insert_overlap (ival2);
99
+
100
+ EXPECT_TRUE (overlaps_called);
101
+ }
102
+
103
+ TEST_F (CustomIntervalTests, CustomOverlapsExclusiveIvalIsCalled)
104
+ {
105
+ lib_interval_tree::interval_tree<custom_interval<int >> tree;
106
+ auto ival1 = custom_interval<int >{0 , 5 };
107
+ auto ival2 = custom_interval<int >{4 , 10 };
108
+
109
+ bool overlaps_exclusive_ival_called = false ;
110
+ ival1.on_overlaps_exclusive_ival = [&](custom_interval<int > const & other) -> bool {
111
+ overlaps_exclusive_ival_called = true ;
112
+ return ival1.low_ < other.high_ && other.low_ < ival1.high_ ;
113
+ };
114
+
115
+ tree.insert (ival1);
116
+ tree.insert_overlap (ival2, true );
117
+
118
+ EXPECT_TRUE (overlaps_exclusive_ival_called);
119
+ }
0 commit comments