Skip to content

Commit b1d8a7b

Browse files
committed
Improved interval types
1 parent 5ee73f1 commit b1d8a7b

File tree

1 file changed

+189
-10
lines changed

1 file changed

+189
-10
lines changed

include/interval-tree/interval_types.hpp

Lines changed: 189 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ namespace lib_interval_tree
2929
{
3030
return high - low;
3131
}
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+
}
3244
};
3345
// [)
3446
struct right_open
@@ -50,6 +62,18 @@ namespace lib_interval_tree
5062
{
5163
return high - low;
5264
}
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+
}
5377
};
5478
// []
5579
struct closed
@@ -67,7 +91,12 @@ namespace lib_interval_tree
6791
}
6892

6993
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
71100
size(numerical_type low, numerical_type high)
72101
{
73102
return high - low + 1;
@@ -84,6 +113,68 @@ namespace lib_interval_tree
84113
{
85114
return high - low;
86115
}
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+
}
87178
};
88179
// ()
89180
struct open
@@ -101,7 +192,12 @@ namespace lib_interval_tree
101192
}
102193

103194
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
104199
static inline typename std::enable_if<!std::is_floating_point<numerical_type>::value, numerical_type>::type
200+
#endif
105201
size(numerical_type low, numerical_type high)
106202
{
107203
return high - low - 1;
@@ -118,36 +214,99 @@ namespace lib_interval_tree
118214
{
119215
return high - low;
120216
}
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+
}
121229
};
122230
/// [] and adjacent counts as overlapping
123231
struct closed_adjacent
124232
{
125233
template <typename numerical_type>
126234
#ifdef LIB_INTERVAL_TREE_CONCEPTS
127235
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
128239
#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)
130241
{
131242
return (low <= p) && (p <= high);
132243
}
133244

134245
template <typename numerical_type>
135246
#ifdef LIB_INTERVAL_TREE_CONCEPTS
136247
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
137251
#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)
139253
{
140-
return (l1 <= (h2 + 1)) && ((l2 - 1) <= h1);
254+
return (l1 <= (h2 + 1)) && (l2 <= (h1 + 1));
141255
}
142256

143257
template <typename numerical_type>
144258
#ifdef LIB_INTERVAL_TREE_CONCEPTS
145259
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
146263
#endif
147-
static inline numerical_type size(numerical_type low, numerical_type high)
264+
size(numerical_type low, numerical_type high)
148265
{
149266
return high - low + 1;
150267
}
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+
}
151310
};
152311

153312
enum class interval_border
@@ -166,8 +325,11 @@ namespace lib_interval_tree
166325
template <typename interval_type>
167326
#ifdef LIB_INTERVAL_TREE_CONCEPTS
168327
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
169331
#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)
171333
{
172334
switch (ival.left_border())
173335
{
@@ -217,8 +379,11 @@ namespace lib_interval_tree
217379
template <typename interval_type>
218380
#ifdef LIB_INTERVAL_TREE_CONCEPTS
219381
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
220385
#endif
221-
static inline bool overlaps(interval_type const& ival1, interval_type const& ival2)
386+
overlaps(interval_type const& ival1, interval_type const& ival2)
222387
{
223388
const auto lowToClosed = [](auto const& ival) {
224389
if (ival.left_border() == interval_border::open)
@@ -263,8 +428,13 @@ namespace lib_interval_tree
263428
template <typename interval_type>
264429
#ifdef LIB_INTERVAL_TREE_CONCEPTS
265430
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
266436
#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)
268438
{
269439
using value_type = typename interval_type::value_type;
270440

@@ -303,8 +473,12 @@ namespace lib_interval_tree
303473
template <typename interval_type>
304474
#ifdef LIB_INTERVAL_TREE_CONCEPTS
305475
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
306480
#endif
307-
static interval_type join(interval_type const& ival1, interval_type const& ival2)
481+
join(interval_type const& ival1, interval_type const& ival2)
308482
{
309483
typename interval_type::value_type low;
310484
typename interval_type::value_type high;
@@ -391,8 +565,13 @@ namespace lib_interval_tree
391565
template <typename interval_type>
392566
#ifdef LIB_INTERVAL_TREE_CONCEPTS
393567
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
394573
#endif
395-
typename interval_type::value_type size(interval_type const& ival)
574+
size(interval_type const& ival)
396575
{
397576
auto left = ival.left_border();
398577
if (left == interval_border::closed_adjacent)

0 commit comments

Comments
 (0)