-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathcustom_interval_tests.hpp
152 lines (123 loc) · 4.55 KB
/
custom_interval_tests.hpp
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#pragma once
#include "test_utility.hpp"
#include "multi_join_interval.hpp"
#include <ctime>
#include <random>
#include <cmath>
#include <functional>
class CustomIntervalTests : public ::testing::Test
{};
template <typename numerical_type, typename interval_kind_ = lib_interval_tree::closed>
struct custom_interval : public lib_interval_tree::interval<numerical_type, interval_kind_>
{
public:
using value_type = numerical_type;
using interval_kind = interval_kind_;
using lib_interval_tree::interval<numerical_type, interval_kind_>::low_;
using lib_interval_tree::interval<numerical_type, interval_kind_>::high_;
/**
* Constructs an custom_interval. low MUST be smaller than high.
*/
custom_interval(value_type low, value_type high)
: lib_interval_tree::interval<numerical_type, interval_kind_>{low, high}
{}
std::function<bool(value_type, value_type)> on_overlaps;
bool overlaps(custom_interval const& other) const
{
if (on_overlaps)
return on_overlaps(other.low_, other.high_);
return interval_kind::overlaps(low_, high_, other.low_, other.high_);
}
std::function<bool(custom_interval const& other)> on_overlaps_exclusive_ival;
bool overlaps_exclusive(custom_interval const& other) const
{
if (on_overlaps_exclusive_ival)
return on_overlaps_exclusive_ival(other);
return low_ < other.high_ && other.low_ < high_;
}
std::function<custom_interval(custom_interval const& other)> on_join;
custom_interval join(custom_interval const& other) const
{
if (on_join)
return on_join(other);
return {std::min(low_, other.low_), std::max(high_, other.high_)};
}
};
struct minimal_custom_interval : public lib_interval_tree::interval<int, lib_interval_tree::closed>
{
using lib_interval_tree::interval<int, lib_interval_tree::closed>::interval;
minimal_custom_interval join(minimal_custom_interval const& other) const
{
return {std::min(low_, other.low_), std::max(high_, other.high_)};
}
};
TEST_F(CustomIntervalTests, CanInsertCustomIntervalJoined)
{
lib_interval_tree::interval_tree<custom_interval<int>> tree;
tree.insert({0, 5});
tree.insert_overlap({4, 10});
ASSERT_EQ(tree.size(), 1);
EXPECT_EQ(tree.begin()->low(), 0);
EXPECT_EQ(tree.begin()->high(), 10);
}
TEST_F(CustomIntervalTests, CustomJoinIsCalled)
{
lib_interval_tree::interval_tree<custom_interval<int>> tree;
auto ival1 = custom_interval<int>{0, 5};
auto ival2 = custom_interval<int>{4, 10};
bool join_called = false;
ival1.on_join = [&](custom_interval<int> const& other) -> custom_interval<int> {
join_called = true;
return {std::min(ival1.low_, other.low_), std::max(ival1.high_, other.high_)};
};
tree.insert(ival1);
tree.insert_overlap(ival2);
EXPECT_TRUE(join_called);
}
TEST_F(CustomIntervalTests, CustomOverlapsIsCalled)
{
lib_interval_tree::interval_tree<custom_interval<int>> tree;
auto ival1 = custom_interval<int>{0, 5};
auto ival2 = custom_interval<int>{4, 10};
bool overlaps_called = false;
ival1.on_overlaps = [&](int l, int h) -> bool {
overlaps_called = true;
return custom_interval<int>::interval_kind::overlaps(ival1.low_, ival1.high_, l, h);
};
tree.insert(ival1);
tree.insert_overlap(ival2);
EXPECT_TRUE(overlaps_called);
}
TEST_F(CustomIntervalTests, CustomOverlapsExclusiveIvalIsCalled)
{
lib_interval_tree::interval_tree<custom_interval<int>> tree;
auto ival1 = custom_interval<int>{0, 5};
auto ival2 = custom_interval<int>{4, 10};
bool overlaps_exclusive_ival_called = false;
ival1.on_overlaps_exclusive_ival = [&](custom_interval<int> const& other) -> bool {
overlaps_exclusive_ival_called = true;
return ival1.low_ < other.high_ && other.low_ < ival1.high_;
};
tree.insert(ival1);
tree.insert_overlap(ival2, true);
EXPECT_TRUE(overlaps_exclusive_ival_called);
}
TEST_F(CustomIntervalTests, CanUseMinimalCustomInterval)
{
lib_interval_tree::interval_tree<minimal_custom_interval> tree;
tree.insert({0, 5});
tree.insert_overlap({4, 10});
tree.erase(tree.begin());
EXPECT_EQ(tree.size(), 0);
tree.insert({0, 5});
tree.insert({7, 10});
auto iter = tree.find({0, 5});
ASSERT_NE(iter, tree.end());
EXPECT_EQ(iter->low(), 0);
EXPECT_EQ(iter->high(), 5);
tree.deoverlap();
auto iter2 = tree.overlap_find({8, 12});
ASSERT_NE(iter2, tree.end());
EXPECT_EQ(iter2->low(), 7);
EXPECT_EQ(iter2->high(), 10);
}