3
3
#include " interval_tree_fwd.hpp"
4
4
#include " interval_types.hpp"
5
5
#include " tree_hooks.hpp"
6
+ #include " feature_test.hpp"
6
7
7
8
#include < string>
8
9
#include < memory>
@@ -26,8 +27,8 @@ namespace lib_interval_tree
26
27
// ############################################################################################################
27
28
using default_interval_value_type = int ;
28
29
// ############################################################################################################
29
- template <typename numerical_type, typename interval_kind_ = closed >
30
- struct interval
30
+ template <typename numerical_type, typename interval_kind_>
31
+ struct interval_base
31
32
{
32
33
public:
33
34
using value_type = numerical_type;
@@ -40,7 +41,7 @@ namespace lib_interval_tree
40
41
# if __cplusplus >= 201703L
41
42
constexpr
42
43
# endif
43
- interval (value_type low, value_type high)
44
+ interval_base (value_type low, value_type high)
44
45
: low_{low}
45
46
, high_{high}
46
47
{
@@ -51,52 +52,86 @@ namespace lib_interval_tree
51
52
# if __cplusplus >= 201703L
52
53
constexpr
53
54
# endif
54
- interval (value_type low, value_type high)
55
+ interval_base (value_type low, value_type high)
55
56
: low_{std::min (low, high)}
56
57
, high_{std::max (low, high)}
57
58
{}
58
59
#endif
59
- virtual ~interval () = default ;
60
+ virtual ~interval_base () = default ;
60
61
61
62
/* *
62
- * Returns if both intervals equal.
63
+ * Returns the lower bound of the interval
63
64
*/
64
- friend bool operator ==(interval const & lhs, interval const & other)
65
+ value_type low () const
65
66
{
66
- return lhs. low_ == other. low_ && lhs. high_ == other. high_ ;
67
+ return low_;
67
68
}
68
69
69
70
/* *
70
- * Returns if both intervals are different.
71
+ * Returns the upper bound of the interval
71
72
*/
72
- friend bool operator !=(interval const & lhs, interval const & other)
73
+ value_type high () const
73
74
{
74
- return lhs. low_ != other. low_ || lhs. high_ != other. high_ ;
75
+ return high_;
75
76
}
76
77
78
+ protected:
79
+ value_type low_;
80
+ value_type high_;
81
+ };
82
+ // ############################################################################################################
83
+ template <typename numerical_type, typename interval_kind_ = closed>
84
+ struct interval : public interval_base <numerical_type, interval_kind_>
85
+ {
86
+ public:
87
+ using value_type = typename interval_base<numerical_type, interval_kind_>::value_type;
88
+ using interval_kind = typename interval_base<numerical_type, interval_kind_>::interval_kind;
89
+
90
+ using interval_base<numerical_type, interval_kind_>::low;
91
+ using interval_base<numerical_type, interval_kind_>::high;
92
+
93
+ using interval_base<numerical_type, interval_kind_>::low_;
94
+ using interval_base<numerical_type, interval_kind_>::high_;
95
+
77
96
/* *
78
- * Returns the lower bound of the interval
97
+ * Constructs an interval. low MUST be smaller than high.
79
98
*/
80
- value_type low () const
99
+ #if __cplusplus >= 201703L
100
+ constexpr
101
+ #endif
102
+ interval (value_type low, value_type high)
103
+ : interval_base<numerical_type, interval_kind_>{low, high}
104
+ {}
105
+
106
+ /* *
107
+ * Returns true if both intervals equal.
108
+ */
109
+ friend bool operator ==(
110
+ interval<numerical_type, interval_kind_> const & lhs,
111
+ interval<numerical_type, interval_kind_> const & rhs
112
+ )
81
113
{
82
- return low_;
114
+ return lhs. low_ == rhs. low_ && lhs. high_ == rhs. high_ ;
83
115
}
84
116
85
117
/* *
86
- * Returns the upper bound of the interval
118
+ * Returns true if both intervals are different.
87
119
*/
88
- value_type high () const
120
+ friend bool operator !=(
121
+ interval<numerical_type, interval_kind_> const & lhs,
122
+ interval<numerical_type, interval_kind_> const & rhs
123
+ )
89
124
{
90
- return high_;
125
+ return lhs. low_ != rhs. low_ || lhs. high_ != rhs. high_ ;
91
126
}
92
127
93
128
/* *
94
129
* Returns whether the intervals overlap.
95
130
* For when both intervals are closed.
96
131
*/
97
- bool overlaps (value_type l, value_type h) const
132
+ LIB_INTERVAL_TREE_DEPRECATED bool overlaps (value_type l, value_type h) const
98
133
{
99
- return low_ <= h && l <= high_ ;
134
+ return interval_kind::overlaps ( low_, high_, l, h) ;
100
135
}
101
136
102
137
/* *
@@ -113,7 +148,7 @@ namespace lib_interval_tree
113
148
*/
114
149
bool overlaps (interval const & other) const
115
150
{
116
- return overlaps (other.low_ , other.high_ );
151
+ return interval_kind:: overlaps (low_, high_, other.low_ , other.high_ );
117
152
}
118
153
119
154
/* *
@@ -137,7 +172,7 @@ namespace lib_interval_tree
137
172
*/
138
173
bool within (interval const & other) const
139
174
{
140
- return low_ <= other.low_ && high_ >= other.high_ ;
175
+ return within ( other.low_ ) && within ( other.high_ ) ;
141
176
}
142
177
143
178
/* *
@@ -148,18 +183,113 @@ namespace lib_interval_tree
148
183
{
149
184
if (overlaps (other))
150
185
return 0 ;
151
- if (high_ < other.low_ )
186
+ if (high_ <= other.low_ )
152
187
return other.low_ - high_;
153
188
else
154
189
return low_ - other.high_ ;
155
190
}
156
191
192
+ /* *
193
+ * Creates a new interval from this and other, that contains both intervals and whatever
194
+ * is between.
195
+ */
196
+ interval join (interval const & other) const
197
+ {
198
+ return {std::min (low_, other.low_ ), std::max (high_, other.high_ )};
199
+ }
200
+
157
201
/* *
158
202
* Returns the size of the interval.
159
203
*/
160
204
value_type size () const
161
205
{
162
- return high_ - low_;
206
+ return interval_kind::size (low_, high_);
207
+ }
208
+ };
209
+
210
+ template <typename numerical_type>
211
+ struct interval <numerical_type, dynamic> : public interval_base<numerical_type, dynamic>
212
+ {
213
+ public:
214
+ using value_type = typename interval_base<numerical_type, dynamic>::value_type;
215
+ using interval_kind = dynamic;
216
+
217
+ /* *
218
+ * Constructs an interval. low MUST be smaller than high.
219
+ */
220
+ #if __cplusplus >= 201703L
221
+ constexpr
222
+ #endif
223
+ interval (value_type low, value_type high, interval_border leftBorder, interval_border rightBorder)
224
+ : interval_base<numerical_type, interval_kind>{low, high}
225
+ , left_border_{leftBorder}
226
+ , right_border_{rightBorder}
227
+ {}
228
+
229
+ /* *
230
+ * Returns true if both intervals equal.
231
+ */
232
+ friend bool
233
+ operator ==(interval<numerical_type, dynamic> const & lhs, interval<numerical_type, dynamic> const & other)
234
+ {
235
+ return lhs.low_ == other.low_ && lhs.high_ == other.high_ && lhs.left_border_ == other.left_border_ &&
236
+ lhs.right_border_ == other.right_border_ ;
237
+ }
238
+
239
+ /* *
240
+ * Returns true if both intervals are different.
241
+ */
242
+ friend bool
243
+ operator !=(interval<numerical_type, dynamic> const & lhs, interval<numerical_type, dynamic> const & other)
244
+ {
245
+ return lhs.low_ != other.low_ || lhs.high_ != other.high_ || lhs.left_border_ != other.left_border_ ||
246
+ lhs.right_border_ != other.right_border_ ;
247
+ }
248
+
249
+ using interval_base<numerical_type, interval_kind>::low;
250
+ using interval_base<numerical_type, interval_kind>::high;
251
+ using interval_base<numerical_type, interval_kind>::low_;
252
+ using interval_base<numerical_type, interval_kind>::high_;
253
+
254
+ /* *
255
+ * Returns whether the intervals overlap
256
+ */
257
+ bool overlaps (interval const & other) const
258
+ {
259
+ return interval_kind::overlaps (*this , other);
260
+ }
261
+
262
+ /* *
263
+ * Returns whether the intervals overlap exclusively, independent of border.
264
+ */
265
+ bool overlaps_exclusive (interval const & other) const
266
+ {
267
+ return low_ < other.high_ && other.low_ < high_;
268
+ }
269
+
270
+ /* *
271
+ * Returns whether the given value is in this.
272
+ */
273
+ bool within (value_type value) const
274
+ {
275
+ return interval_kind::within (*this , value);
276
+ }
277
+
278
+ /* *
279
+ * Returns whether the given interval is in this.
280
+ */
281
+ bool within (interval const & other) const
282
+ {
283
+ return within (other.low_ ) && within (other.high_ );
284
+ }
285
+
286
+ /* *
287
+ * Calculates the distance between the two intervals.
288
+ * Overlapping intervals have 0 distance.
289
+ */
290
+ value_type operator -(interval const & other) const
291
+ {
292
+ interval_kind::distance (*this , other);
163
293
}
164
294
165
295
/* *
@@ -168,13 +298,40 @@ namespace lib_interval_tree
168
298
*/
169
299
interval join (interval const & other) const
170
300
{
171
- return {std::min (low_, other.low_ ), std::max (high_, other.high_ )};
301
+ return interval_kind::join (*this , other);
302
+ }
303
+
304
+ /* *
305
+ * Returns the size of the interval.
306
+ */
307
+ value_type size () const
308
+ {
309
+ return interval_kind::size (*this );
310
+ }
311
+
312
+ /* *
313
+ * @brief Returns the left border type of the interval.
314
+ *
315
+ */
316
+ interval_border left_border () const
317
+ {
318
+ return left_border_;
319
+ }
320
+
321
+ /* *
322
+ * @brief Returns the right border type of the interval.
323
+ *
324
+ */
325
+ interval_border right_border () const
326
+ {
327
+ return right_border_;
172
328
}
173
329
174
330
protected:
175
- value_type low_ ;
176
- value_type high_ ;
331
+ interval_border left_border_ ;
332
+ interval_border right_border_ ;
177
333
};
334
+
178
335
// ############################################################################################################
179
336
/* *
180
337
* Creates a safe interval that puts the lower bound left automatically.
0 commit comments