@@ -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