@@ -193,16 +193,35 @@ namespace lib_interval_tree
193193
194194 template <typename numerical_type>
195195#ifdef LIB_INTERVAL_TREE_CONCEPTS
196- requires (!std::is_floating_point_v<numerical_type>)
196+ requires (!std::is_floating_point_v<numerical_type> && std::is_signed_v<numerical_type> )
197197 static inline numerical_type
198198#else
199- static inline typename std::enable_if<!std::is_floating_point<numerical_type>::value, numerical_type>::type
199+ static inline typename std::enable_if<
200+ !std::is_floating_point<numerical_type>::value && std::is_signed<numerical_type>::value,
201+ numerical_type>::type
200202#endif
201203 size (numerical_type low, numerical_type high)
202204 {
203205 return high - low - 1 ;
204206 }
205207
208+ template <typename numerical_type>
209+ #ifdef LIB_INTERVAL_TREE_CONCEPTS
210+ requires (!std::is_floating_point_v<numerical_type> && std::is_unsigned_v<numerical_type>)
211+ static inline numerical_type
212+ #else
213+ static inline typename std::enable_if<
214+ !std::is_floating_point<numerical_type>::value && std::is_unsigned<numerical_type>::value,
215+ numerical_type>::type
216+ #endif
217+ size (numerical_type low, numerical_type high)
218+ {
219+ if (high > low)
220+ return high - low - 1 ;
221+ else
222+ return 0 ;
223+ }
224+
206225 template <typename numerical_type>
207226#ifdef LIB_INTERVAL_TREE_CONCEPTS
208227 requires std::is_floating_point_v<numerical_type>
@@ -393,7 +412,13 @@ namespace lib_interval_tree
393412
394413 const auto highToClosed = [](auto const & ival) {
395414 if (ival.right_border () == interval_border::open)
415+ {
416+ INTERVAL_TREE_CONSTEXPR_IF (std::is_unsigned<typename interval_type::value_type>::value)
417+ {
418+ return ival.high () > 0 ? ival.high () - 1 : 0 ;
419+ }
396420 return ival.high () - 1 ;
421+ }
397422 return ival.high ();
398423 };
399424
@@ -442,11 +467,33 @@ namespace lib_interval_tree
442467 return 0 ;
443468
444469 value_type adjusted_low = ival1.left_border () == interval_border::open ? ival1.low () + 1 : ival1.low ();
445- value_type adjusted_high = ival1.right_border () == interval_border::open ? ival1.high () - 1 : ival1.high ();
470+
471+ value_type adjusted_high = [&]() {
472+ INTERVAL_TREE_CONSTEXPR_IF (std::is_unsigned<value_type>::value)
473+ {
474+ return ival1.right_border () == interval_border::open ? (ival1.high () > 0 ? ival1.high () - 1 : 0 )
475+ : ival1.high ();
476+ }
477+ else
478+ {
479+ return ival1.right_border () == interval_border::open ? ival1.high () - 1 : ival1.high ();
480+ }
481+ }();
482+
446483 value_type other_adjusted_low =
447484 ival2.left_border () == interval_border::open ? ival2.low () + 1 : ival2.low ();
448- value_type other_adjusted_high =
449- ival2.right_border () == interval_border::open ? ival2.high () - 1 : ival2.high ();
485+
486+ value_type other_adjusted_high = [&]() {
487+ INTERVAL_TREE_CONSTEXPR_IF (std::is_unsigned<value_type>::value)
488+ {
489+ return ival2.right_border () == interval_border::open ? (ival2.high () > 0 ? ival2.high () - 1 : 0 )
490+ : ival2.high ();
491+ }
492+ else
493+ {
494+ return ival2.right_border () == interval_border::open ? ival2.high () - 1 : ival2.high ();
495+ }
496+ }();
450497
451498 if (adjusted_high < other_adjusted_low)
452499 return other_adjusted_low - adjusted_high;
@@ -540,7 +587,13 @@ namespace lib_interval_tree
540587 ? &ival1
541588 : &ival2;
542589
543- const auto openAdjusted = rightOpenInterval->high () - 1 ;
590+ const auto openAdjusted = [&]() {
591+ INTERVAL_TREE_CONSTEXPR_IF (std::is_unsigned<typename interval_type::value_type>::value)
592+ {
593+ return rightOpenInterval->high () > 0 ? rightOpenInterval->high () - 1 : 0 ;
594+ }
595+ return rightOpenInterval->high () - 1 ;
596+ }();
544597
545598 if (openAdjusted == rightClosedInterval->high ())
546599 {
0 commit comments