@@ -29,6 +29,18 @@ namespace lib_interval_tree
29
29
{
30
30
return high - low;
31
31
}
32
+
33
+ template <typename numerical_type>
34
+ static inline numerical_type left_slice_upper_bound (numerical_type value)
35
+ {
36
+ return value;
37
+ }
38
+
39
+ template <typename numerical_type>
40
+ static inline numerical_type right_slice_lower_bound (numerical_type value)
41
+ {
42
+ return value;
43
+ }
32
44
};
33
45
// [)
34
46
struct right_open
@@ -50,6 +62,18 @@ namespace lib_interval_tree
50
62
{
51
63
return high - low;
52
64
}
65
+
66
+ template <typename numerical_type>
67
+ static inline numerical_type left_slice_upper_bound (numerical_type high)
68
+ {
69
+ return high;
70
+ }
71
+
72
+ template <typename numerical_type>
73
+ static inline numerical_type right_slice_lower_bound (numerical_type value)
74
+ {
75
+ return value;
76
+ }
53
77
};
54
78
// []
55
79
struct closed
@@ -67,7 +91,12 @@ namespace lib_interval_tree
67
91
}
68
92
69
93
template <typename numerical_type>
70
- static inline typename std::enable_if<!std::is_floating_point<numerical_type>::value, numerical_type>::type
94
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
95
+ requires std::is_integral_v<numerical_type>
96
+ static inline numerical_type
97
+ #else
98
+ static inline typename std::enable_if<std::is_integral<numerical_type>::value, numerical_type>::type
99
+ #endif
71
100
size (numerical_type low, numerical_type high)
72
101
{
73
102
return high - low + 1 ;
@@ -84,6 +113,68 @@ namespace lib_interval_tree
84
113
{
85
114
return high - low;
86
115
}
116
+
117
+ template <typename numerical_type>
118
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
119
+ requires (std::is_signed_v<numerical_type> && !std::is_floating_point_v<numerical_type>)
120
+ static inline numerical_type
121
+ #else
122
+ static inline typename std::enable_if<
123
+ std::is_signed<numerical_type>::value && !std::is_floating_point<numerical_type>::value,
124
+ numerical_type>::type
125
+ #endif
126
+ left_slice_upper_bound (numerical_type value)
127
+ {
128
+ return value - 1 ;
129
+ }
130
+
131
+ template <typename numerical_type>
132
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
133
+ requires (std::is_floating_point_v<numerical_type>)
134
+ static inline numerical_type
135
+ #else
136
+ static inline typename std::enable_if<std::is_floating_point<numerical_type>::value, numerical_type>::type
137
+ #endif
138
+ left_slice_upper_bound (numerical_type value)
139
+ {
140
+ return value;
141
+ }
142
+
143
+ template <typename numerical_type>
144
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
145
+ requires std::is_unsigned_v<numerical_type>
146
+ static inline numerical_type
147
+ #else
148
+ static inline typename std::enable_if<std::is_unsigned<numerical_type>::value, numerical_type>::type
149
+ #endif
150
+ left_slice_upper_bound (numerical_type value)
151
+ {
152
+ return value > 0 ? value - 1 : 0 ;
153
+ }
154
+
155
+ template <typename numerical_type>
156
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
157
+ requires (!std::is_floating_point_v<numerical_type>)
158
+ static inline numerical_type
159
+ #else
160
+ static inline typename std::enable_if<!std::is_floating_point<numerical_type>::value, numerical_type>::type
161
+ #endif
162
+ right_slice_lower_bound (numerical_type value)
163
+ {
164
+ return value + 1 ;
165
+ }
166
+
167
+ template <typename numerical_type>
168
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
169
+ requires std::is_floating_point_v<numerical_type>
170
+ static inline numerical_type
171
+ #else
172
+ static inline typename std::enable_if<std::is_floating_point<numerical_type>::value, numerical_type>::type
173
+ #endif
174
+ right_slice_lower_bound (numerical_type value)
175
+ {
176
+ return value;
177
+ }
87
178
};
88
179
// ()
89
180
struct open
@@ -101,7 +192,12 @@ namespace lib_interval_tree
101
192
}
102
193
103
194
template <typename numerical_type>
195
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
196
+ requires (!std::is_floating_point_v<numerical_type>)
197
+ static inline numerical_type
198
+ #else
104
199
static inline typename std::enable_if<!std::is_floating_point<numerical_type>::value, numerical_type>::type
200
+ #endif
105
201
size (numerical_type low, numerical_type high)
106
202
{
107
203
return high - low - 1 ;
@@ -118,36 +214,99 @@ namespace lib_interval_tree
118
214
{
119
215
return high - low;
120
216
}
217
+
218
+ template <typename numerical_type>
219
+ static inline numerical_type left_slice_upper_bound (numerical_type high)
220
+ {
221
+ return high;
222
+ }
223
+
224
+ template <typename numerical_type>
225
+ static inline numerical_type right_slice_lower_bound (numerical_type high)
226
+ {
227
+ return high;
228
+ }
121
229
};
122
230
// / [] and adjacent counts as overlapping
123
231
struct closed_adjacent
124
232
{
125
233
template <typename numerical_type>
126
234
#ifdef LIB_INTERVAL_TREE_CONCEPTS
127
235
requires std::is_integral_v<numerical_type>
236
+ static inline bool
237
+ #else
238
+ static inline typename std::enable_if<std::is_integral<numerical_type>::value, bool >::type
128
239
#endif
129
- static inline bool within (numerical_type low, numerical_type high, numerical_type p)
240
+ within (numerical_type low, numerical_type high, numerical_type p)
130
241
{
131
242
return (low <= p) && (p <= high);
132
243
}
133
244
134
245
template <typename numerical_type>
135
246
#ifdef LIB_INTERVAL_TREE_CONCEPTS
136
247
requires std::is_integral_v<numerical_type>
248
+ static inline bool
249
+ #else
250
+ static inline typename std::enable_if<std::is_integral<numerical_type>::value, bool >::type
137
251
#endif
138
- static inline bool overlaps (numerical_type l1, numerical_type h1, numerical_type l2, numerical_type h2)
252
+ overlaps (numerical_type l1, numerical_type h1, numerical_type l2, numerical_type h2)
139
253
{
140
- return (l1 <= (h2 + 1 )) && (( l2 - 1 ) <= h1 );
254
+ return (l1 <= (h2 + 1 )) && (l2 <= (h1 + 1 ) );
141
255
}
142
256
143
257
template <typename numerical_type>
144
258
#ifdef LIB_INTERVAL_TREE_CONCEPTS
145
259
requires std::is_integral_v<numerical_type>
260
+ static inline numerical_type
261
+ #else
262
+ static inline typename std::enable_if<std::is_integral<numerical_type>::value, numerical_type>::type
146
263
#endif
147
- static inline numerical_type size (numerical_type low, numerical_type high)
264
+ size (numerical_type low, numerical_type high)
148
265
{
149
266
return high - low + 1 ;
150
267
}
268
+
269
+ template <typename numerical_type>
270
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
271
+ requires std::is_floating_point_v<numerical_type>
272
+ static inline numerical_type
273
+ #else
274
+ static inline typename std::enable_if<std::is_floating_point<numerical_type>::value, numerical_type>::type
275
+ #endif
276
+ size (numerical_type low, numerical_type high)
277
+ {
278
+ return high - low;
279
+ }
280
+
281
+ template <typename numerical_type>
282
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
283
+ requires std::is_signed_v<numerical_type>
284
+ static inline numerical_type
285
+ #else
286
+ static inline typename std::enable_if<std::is_signed<numerical_type>::value, numerical_type>::type
287
+ #endif
288
+ left_slice_upper_bound (numerical_type value)
289
+ {
290
+ return value - 1 ;
291
+ }
292
+
293
+ template <typename numerical_type>
294
+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
295
+ requires std::is_unsigned_v<numerical_type>
296
+ static inline numerical_type
297
+ #else
298
+ static inline typename std::enable_if<std::is_unsigned<numerical_type>::value, numerical_type>::type
299
+ #endif
300
+ left_slice_upper_bound (numerical_type value)
301
+ {
302
+ return value > 0 ? value - 1 : 0 ;
303
+ }
304
+
305
+ template <typename numerical_type>
306
+ static inline numerical_type right_slice_lower_bound (numerical_type value)
307
+ {
308
+ return value + 1 ;
309
+ }
151
310
};
152
311
153
312
enum class interval_border
@@ -166,8 +325,11 @@ namespace lib_interval_tree
166
325
template <typename interval_type>
167
326
#ifdef LIB_INTERVAL_TREE_CONCEPTS
168
327
requires std::is_integral_v<typename interval_type::value_type>
328
+ static inline bool
329
+ #else
330
+ static inline typename std::enable_if<std::is_integral<typename interval_type::value_type>::value, bool >::type
169
331
#endif
170
- static inline bool within (interval_type const & ival, typename interval_type::value_type p)
332
+ within (interval_type const & ival, typename interval_type::value_type p)
171
333
{
172
334
switch (ival.left_border ())
173
335
{
@@ -217,8 +379,11 @@ namespace lib_interval_tree
217
379
template <typename interval_type>
218
380
#ifdef LIB_INTERVAL_TREE_CONCEPTS
219
381
requires std::is_integral_v<typename interval_type::value_type>
382
+ static inline bool
383
+ #else
384
+ static inline typename std::enable_if<std::is_integral<typename interval_type::value_type>::value, bool >::type
220
385
#endif
221
- static inline bool overlaps (interval_type const & ival1, interval_type const & ival2)
386
+ overlaps (interval_type const & ival1, interval_type const & ival2)
222
387
{
223
388
const auto lowToClosed = [](auto const & ival) {
224
389
if (ival.left_border () == interval_border::open)
@@ -263,8 +428,13 @@ namespace lib_interval_tree
263
428
template <typename interval_type>
264
429
#ifdef LIB_INTERVAL_TREE_CONCEPTS
265
430
requires std::is_integral_v<typename interval_type::value_type>
431
+ static inline typename interval_type::value_type
432
+ #else
433
+ static inline typename std::enable_if<
434
+ std::is_integral<typename interval_type::value_type>::value,
435
+ typename interval_type::value_type>::type
266
436
#endif
267
- static typename interval_type::value_type distance (interval_type const & ival1, interval_type const & ival2)
437
+ distance (interval_type const & ival1, interval_type const & ival2)
268
438
{
269
439
using value_type = typename interval_type::value_type;
270
440
@@ -303,8 +473,12 @@ namespace lib_interval_tree
303
473
template <typename interval_type>
304
474
#ifdef LIB_INTERVAL_TREE_CONCEPTS
305
475
requires std::is_integral_v<typename interval_type::value_type>
476
+ static inline interval_type
477
+ #else
478
+ static inline
479
+ typename std::enable_if<std::is_integral<typename interval_type::value_type>::value, interval_type>::type
306
480
#endif
307
- static interval_type join (interval_type const & ival1, interval_type const & ival2)
481
+ join (interval_type const & ival1, interval_type const & ival2)
308
482
{
309
483
typename interval_type::value_type low;
310
484
typename interval_type::value_type high;
@@ -391,8 +565,13 @@ namespace lib_interval_tree
391
565
template <typename interval_type>
392
566
#ifdef LIB_INTERVAL_TREE_CONCEPTS
393
567
requires std::is_integral_v<typename interval_type::value_type>
568
+ static inline typename interval_type::value_type
569
+ #else
570
+ static inline typename std::enable_if<
571
+ std::is_integral<typename interval_type::value_type>::value,
572
+ typename interval_type::value_type>::type
394
573
#endif
395
- typename interval_type::value_type size (interval_type const & ival)
574
+ size (interval_type const & ival)
396
575
{
397
576
auto left = ival.left_border ();
398
577
if (left == interval_border::closed_adjacent)
0 commit comments