1use crate::UIntPlusOne;
2#[cfg(feature = "from_slice")]
3use crate::{RangeSetBlaze, from_slice::FromSliceIter};
4use core::hash::Hash;
5use core::net::{Ipv4Addr, Ipv6Addr};
6use core::ops::{AddAssign, SubAssign};
7use core::panic;
8use core::{fmt, ops::RangeInclusive};
9use num_traits::ops::overflowing::OverflowingSub;
10
11#[cfg(feature = "from_slice")]
12#[allow(clippy::redundant_pub_crate)]
13pub(crate) const LANES: usize = 16;
14
15#[allow(unused_imports)]
16use num_traits::Zero;
17
18pub trait Integer: Copy + PartialEq + PartialOrd + Ord + fmt::Debug + Send + Sync {
26 fn checked_add_one(self) -> Option<Self>;
28
29 #[must_use]
38 fn add_one(self) -> Self;
39
40 #[must_use]
49 fn sub_one(self) -> Self;
50
51 fn assign_sub_one(&mut self);
53
54 #[must_use]
65 fn exhausted_range() -> RangeInclusive<Self> {
66 Self::max_value()..=Self::min_value()
67 }
68
69 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self>;
73
74 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self>;
78
79 #[must_use]
88 fn min_value() -> Self;
89
90 #[must_use]
99 fn max_value() -> Self;
100
101 #[cfg(feature = "from_slice")]
102 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self>;
106
107 type SafeLen: Hash
120 + Copy
121 + PartialEq
122 + PartialOrd
123 + num_traits::Zero
124 + num_traits::One
125 + AddAssign
126 + SubAssign;
127
128 fn safe_len(range: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen;
137
138 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen;
142
143 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64;
145
146 #[must_use]
148 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self;
149
150 #[must_use]
152 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self;
153}
154
155macro_rules! impl_integer_ops {
157 ($type:ty, $type2:ty) => {
158 #[inline]
159 fn checked_add_one(self) -> Option<Self> {
160 self.checked_add(1)
161 }
162
163 #[inline]
164 fn add_one(self) -> Self {
165 self + 1
166 }
167
168 #[inline]
169 fn sub_one(self) -> Self {
170 self - 1
171 }
172
173 #[inline]
174 fn assign_sub_one(&mut self) {
175 *self -= 1;
176 }
177
178 #[inline]
179 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self> {
180 range.next()
181 }
182
183 #[inline]
184 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self> {
185 range.next_back()
186 }
187
188 #[inline]
189 fn min_value() -> Self {
190 Self::MIN
191 }
192
193 #[inline]
194 fn max_value() -> Self {
195 Self::MAX
196 }
197
198 #[cfg(feature = "from_slice")]
199 #[inline]
200 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self> {
201 FromSliceIter::<Self, LANES>::new(slice.as_ref()).collect()
202 }
203
204 #[allow(clippy::cast_sign_loss)]
205 fn safe_len(r: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen {
206 debug_assert!(r.start() <= r.end(), "start ≤ end required");
208
209 let delta_wide: $type2 = r.end().overflowing_sub(r.start()).0 as $type2;
212
213 <<Self as Integer>::SafeLen>::try_from(delta_wide)
216 .expect("$type2 ⊆ SafeLen; optimizer drops this in release")
217 + 1 }
219
220 #[allow(clippy::cast_precision_loss, clippy::cast_lossless)]
221 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64 {
222 len as f64
223 }
224
225 #[allow(clippy::cast_sign_loss)]
226 #[allow(clippy::cast_precision_loss)]
227 #[allow(clippy::cast_possible_truncation)]
228 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen {
229 f as Self::SafeLen
230 }
231
232 #[allow(clippy::cast_possible_truncation)]
233 #[allow(clippy::cast_possible_wrap)]
234 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self {
235 #[cfg(debug_assertions)]
236 {
237 let max_len = Self::safe_len(&(self..=Self::MAX));
238 assert!(
239 b > 0 && b <= max_len,
240 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
241 );
242 }
243 self.wrapping_add((b - 1) as Self)
245 }
246
247 #[allow(clippy::cast_possible_truncation)]
248 #[allow(clippy::cast_possible_wrap)]
249 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self {
250 #[cfg(debug_assertions)]
251 {
252 let max_len = Self::safe_len(&(Self::MIN..=self));
253 assert!(
254 0 < b && b <= max_len,
255 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
256 );
257 }
258 self.wrapping_sub((b - 1) as Self)
260 }
261 };
262}
263
264impl Integer for i8 {
265 type SafeLen = u16;
266 impl_integer_ops!(i8, u8);
267}
268
269impl Integer for u8 {
270 type SafeLen = u16;
271 impl_integer_ops!(u8, Self);
272}
273
274impl Integer for i32 {
275 type SafeLen = u64;
276
277 impl_integer_ops!(i32, u32);
278}
279
280impl Integer for u32 {
281 type SafeLen = u64;
282
283 impl_integer_ops!(u32, Self);
284}
285
286impl Integer for i64 {
287 type SafeLen = u128;
288
289 impl_integer_ops!(i64, u64);
290}
291
292impl Integer for u64 {
293 type SafeLen = u128;
294
295 impl_integer_ops!(u64, Self);
296}
297
298impl Integer for i128 {
299 type SafeLen = UIntPlusOne<u128>;
300
301 #[inline]
302 fn checked_add_one(self) -> Option<Self> {
303 self.checked_add(1)
304 }
305
306 #[inline]
307 fn add_one(self) -> Self {
308 self + 1
309 }
310
311 #[inline]
312 fn sub_one(self) -> Self {
313 self - 1
314 }
315
316 #[inline]
317 fn assign_sub_one(&mut self) {
318 *self -= 1;
319 }
320
321 #[inline]
322 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self> {
323 range.next()
324 }
325
326 #[inline]
327 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self> {
328 range.next_back()
329 }
330
331 #[inline]
332 fn min_value() -> Self {
333 Self::MIN
334 }
335
336 #[inline]
337 fn max_value() -> Self {
338 Self::MAX
339 }
340
341 #[cfg(feature = "from_slice")]
342 #[inline]
343 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self> {
344 RangeSetBlaze::from_iter(slice.as_ref())
345 }
346
347 #[allow(clippy::cast_sign_loss)]
348 fn safe_len(r: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen {
349 debug_assert!(r.start() <= r.end());
350 let less1 = r.end().overflowing_sub(r.start()).0 as u128;
352 let less1 = UIntPlusOne::UInt(less1);
353 less1 + UIntPlusOne::UInt(1)
354 }
355
356 #[allow(clippy::cast_precision_loss)]
357 #[allow(clippy::cast_possible_truncation)]
358 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64 {
359 match len {
360 UIntPlusOne::UInt(v) => v as f64,
361 UIntPlusOne::MaxPlusOne => UIntPlusOne::<u128>::max_plus_one_as_f64(),
362 }
363 }
364
365 #[allow(clippy::cast_sign_loss)]
366 #[allow(clippy::cast_possible_truncation)]
367 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen {
368 if f >= UIntPlusOne::<u128>::max_plus_one_as_f64() {
369 UIntPlusOne::MaxPlusOne
370 } else {
371 UIntPlusOne::UInt(f as u128)
372 }
373 }
374
375 #[allow(clippy::cast_possible_wrap)]
383 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self {
384 #[cfg(debug_assertions)]
385 {
386 let max_len = Self::safe_len(&(self..=Self::MAX));
387 assert!(
388 UIntPlusOne::zero() < b && b <= max_len,
389 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
390 );
391 }
392
393 let UIntPlusOne::UInt(b) = b else {
394 if self == Self::MIN {
395 return Self::MAX;
396 }
397 let max_len = Self::safe_len(&(self..=Self::MAX));
398 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
399 };
400 self.wrapping_add((b - 1) as Self)
402 }
403
404 #[allow(clippy::cast_possible_wrap)]
412 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self {
413 #[cfg(debug_assertions)]
414 {
415 let max_len = Self::safe_len(&(Self::MIN..=self));
416 assert!(
417 UIntPlusOne::zero() < b && b <= max_len,
418 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
419 );
420 }
421
422 let UIntPlusOne::UInt(b) = b else {
423 if self == Self::MAX {
424 return Self::MIN;
425 }
426 let max_len = Self::safe_len(&(Self::MIN..=self));
427 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
428 };
429
430 self.wrapping_sub((b - 1) as Self)
432 }
433}
434
435impl Integer for u128 {
436 type SafeLen = UIntPlusOne<Self>;
437
438 #[inline]
439 fn checked_add_one(self) -> Option<Self> {
440 self.checked_add(1)
441 }
442
443 #[inline]
444 fn add_one(self) -> Self {
445 self + 1
446 }
447
448 #[inline]
449 fn sub_one(self) -> Self {
450 self - 1
451 }
452
453 #[inline]
454 fn assign_sub_one(&mut self) {
455 *self -= 1;
456 }
457
458 #[inline]
459 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self> {
460 range.next()
461 }
462
463 #[inline]
464 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self> {
465 range.next_back()
466 }
467
468 #[inline]
469 fn min_value() -> Self {
470 Self::MIN
471 }
472
473 #[inline]
474 fn max_value() -> Self {
475 Self::MAX
476 }
477
478 #[cfg(feature = "from_slice")]
479 #[inline]
480 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self> {
481 RangeSetBlaze::from_iter(slice.as_ref())
482 }
483
484 fn safe_len(r: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen {
485 debug_assert!(r.start() <= r.end());
486 UIntPlusOne::UInt(r.end() - r.start()) + UIntPlusOne::UInt(1)
487 }
488
489 #[allow(clippy::cast_precision_loss)]
490 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64 {
491 match len {
492 UIntPlusOne::UInt(len) => len as f64,
493 UIntPlusOne::MaxPlusOne => UIntPlusOne::<Self>::max_plus_one_as_f64(),
494 }
495 }
496
497 #[allow(clippy::cast_sign_loss)]
498 #[allow(clippy::cast_possible_truncation)]
499 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen {
500 if f >= UIntPlusOne::<Self>::max_plus_one_as_f64() {
501 UIntPlusOne::MaxPlusOne
502 } else {
503 UIntPlusOne::UInt(f as Self)
504 }
505 }
506
507 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self {
515 #[cfg(debug_assertions)]
516 {
517 let max_len = Self::safe_len(&(self..=Self::MAX));
518 assert!(
519 UIntPlusOne::zero() < b && b <= max_len,
520 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
521 );
522 }
523
524 let UIntPlusOne::UInt(b) = b else {
525 if self == Self::MIN {
526 return Self::MAX;
527 }
528 let max_len = Self::safe_len(&(self..=Self::MAX));
529 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
530 };
531 self.wrapping_add((b - 1) as Self)
533 }
534
535 #[allow(clippy::cast_possible_wrap)]
543 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self {
544 #[cfg(debug_assertions)]
545 {
546 let max_len = Self::safe_len(&(Self::MIN..=self));
547 assert!(
548 UIntPlusOne::zero() < b && b <= max_len,
549 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
550 );
551 }
552
553 let UIntPlusOne::UInt(b) = b else {
554 if self == Self::MAX {
555 return Self::MIN;
556 }
557 let max_len = Self::safe_len(&(Self::MIN..=self));
558 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
559 };
560
561 self.wrapping_sub((b - 1) as Self)
563 }
564}
565
566impl Integer for isize {
567 #[cfg(target_pointer_width = "32")]
568 type SafeLen = u64;
569 #[cfg(target_pointer_width = "64")]
570 type SafeLen = u128;
571
572 impl_integer_ops!(isize, usize);
573}
574
575impl Integer for usize {
576 #[cfg(target_pointer_width = "32")]
577 type SafeLen = u64;
578 #[cfg(target_pointer_width = "64")]
579 type SafeLen = u128;
580
581 impl_integer_ops!(usize, Self);
582}
583
584impl Integer for i16 {
585 type SafeLen = u32;
586
587 impl_integer_ops!(i16, u16);
588}
589
590impl Integer for u16 {
591 type SafeLen = u32;
592
593 impl_integer_ops!(u16, Self);
594}
595
596impl Integer for Ipv4Addr {
597 type SafeLen = u64;
598
599 #[inline]
600 fn checked_add_one(self) -> Option<Self> {
601 let num = u32::from(self);
602 num.checked_add(1).map(Self::from)
603 }
604
605 #[inline]
606 fn add_one(self) -> Self {
607 let num = u32::from(self);
608 Self::from(num + 1)
609 }
610
611 #[inline]
612 fn sub_one(self) -> Self {
613 let num = u32::from(self);
614 Self::from(num - 1)
615 }
616
617 #[inline]
618 fn assign_sub_one(&mut self) {
619 let num = u32::from(*self);
620 *self = Self::from(num - 1);
621 }
622
623 #[inline]
624 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self> {
625 range.next()
626 }
627
628 #[inline]
629 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self> {
630 range.next_back()
631 }
632
633 #[inline]
634 fn min_value() -> Self {
635 Self::new(0, 0, 0, 0)
636 }
637
638 #[inline]
639 fn max_value() -> Self {
640 Self::new(255, 255, 255, 255)
641 }
642
643 #[cfg(feature = "from_slice")]
644 #[inline]
645 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self> {
646 RangeSetBlaze::from_iter(slice.as_ref())
647 }
648
649 #[allow(clippy::cast_lossless)]
650 fn safe_len(r: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen {
651 let start_num = u32::from(*r.start());
652 let end_num = u32::from(*r.end());
653 debug_assert!(start_num <= end_num);
654 end_num.overflowing_sub(start_num).0 as <Self as Integer>::SafeLen + 1
656 }
657
658 #[allow(clippy::cast_precision_loss)]
659 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64 {
660 len as f64
661 }
662
663 #[allow(clippy::cast_possible_truncation)]
664 #[allow(clippy::cast_sign_loss)]
665 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen {
666 f as Self::SafeLen
667 }
668
669 #[allow(clippy::cast_possible_truncation)]
670 #[allow(clippy::cast_possible_wrap)]
671 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self {
672 #[cfg(debug_assertions)]
673 {
674 let max_len = Self::safe_len(&(self..=Self::max_value()));
675 assert!(
676 b > 0 && b <= max_len,
677 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
678 );
679 }
680 u32::from(self).wrapping_add((b - 1) as u32).into()
682 }
683
684 #[allow(clippy::cast_possible_truncation)]
685 #[allow(clippy::cast_possible_wrap)]
686 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self {
687 #[cfg(debug_assertions)]
688 {
689 let max_len = Self::safe_len(&(Self::min_value()..=self));
690 assert!(
691 0 < b && b <= max_len,
692 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
693 );
694 }
695 u32::from(self).wrapping_sub((b - 1) as u32).into()
697 }
698}
699
700impl Integer for Ipv6Addr {
701 type SafeLen = UIntPlusOne<u128>;
702
703 #[inline]
704 fn checked_add_one(self) -> Option<Self> {
705 let num = u128::from(self);
706 num.checked_add(1).map(Self::from)
707 }
708
709 #[inline]
710 fn add_one(self) -> Self {
711 let num = u128::from(self);
712 Self::from(num + 1)
713 }
714
715 #[inline]
716 fn sub_one(self) -> Self {
717 let num = u128::from(self);
718 Self::from(num - 1)
719 }
720
721 #[inline]
722 fn assign_sub_one(&mut self) {
723 let num = u128::from(*self);
724 *self = Self::from(num - 1);
725 }
726
727 #[inline]
728 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self> {
729 range.next()
730 }
731
732 #[inline]
733 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self> {
734 range.next_back()
735 }
736
737 #[inline]
738 fn min_value() -> Self {
739 Self::new(0, 0, 0, 0, 0, 0, 0, 0)
740 }
741
742 #[inline]
743 fn max_value() -> Self {
744 Self::from(u128::MAX)
745 }
746
747 #[cfg(feature = "from_slice")]
748 #[inline]
749 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self> {
750 RangeSetBlaze::from_iter(slice.as_ref())
751 }
752
753 fn safe_len(r: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen {
754 let start_num = u128::from(*r.start());
755 let end_num = u128::from(*r.end());
756
757 debug_assert!(start_num <= end_num);
758 UIntPlusOne::UInt(end_num - start_num) + UIntPlusOne::UInt(1)
759 }
760
761 #[allow(clippy::cast_precision_loss)]
762 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64 {
763 match len {
764 UIntPlusOne::UInt(len) => len as f64,
765 UIntPlusOne::MaxPlusOne => UIntPlusOne::<u128>::max_plus_one_as_f64(),
766 }
767 }
768
769 #[allow(clippy::cast_possible_truncation)]
770 #[allow(clippy::cast_sign_loss)]
771 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen {
772 if f >= UIntPlusOne::<u128>::max_plus_one_as_f64() {
773 UIntPlusOne::MaxPlusOne
774 } else {
775 UIntPlusOne::UInt(f as u128)
776 }
777 }
778
779 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self {
787 #[cfg(debug_assertions)]
788 {
789 let max_len = Self::safe_len(&(self..=Self::max_value()));
790 assert!(
791 UIntPlusOne::zero() < b && b <= max_len,
792 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
793 );
794 }
795
796 let UIntPlusOne::UInt(b) = b else {
797 if self == Self::min_value() {
798 return Self::max_value();
799 }
800 let max_len = Self::safe_len(&(self..=Self::max_value()));
801 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
802 };
803 u128::from(self).wrapping_add(b - 1).into()
805 }
806
807 #[allow(clippy::cast_possible_wrap)]
815 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self {
816 #[cfg(debug_assertions)]
817 {
818 let max_len = Self::safe_len(&(Self::min_value()..=self));
819 assert!(
820 UIntPlusOne::zero() < b && b <= max_len,
821 "b must be in range 1..=max_len (b = {b}, max_len = {max_len})"
822 );
823 }
824
825 let UIntPlusOne::UInt(b) = b else {
826 if self == Self::max_value() {
827 return Self::min_value();
828 }
829 let max_len = Self::safe_len(&(Self::min_value()..=self));
830 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
831 };
832
833 u128::from(self).wrapping_sub(b - 1).into()
835 }
836}
837
838const SURROGATE_START: u32 = 0xD800;
840const SURROGATE_END: u32 = 0xDFFF;
841
842impl Integer for char {
843 type SafeLen = u32;
846
847 #[inline]
848 fn checked_add_one(self) -> Option<Self> {
849 let mut num = u32::from(self) + 1;
851 if num == SURROGATE_START {
853 num = SURROGATE_END + 1;
854 }
855 Self::from_u32(num)
857 }
858
859 #[inline]
860 fn add_one(self) -> Self {
861 self.checked_add_one().map_or_else(
862 || {
863 panic!("char overflow"); },
865 |next| next,
866 )
867 }
868
869 #[inline]
870 fn sub_one(self) -> Self {
871 let mut num = u32::from(self).wrapping_sub(1);
872 if num == SURROGATE_END {
873 num = SURROGATE_START - 1;
874 }
875 Self::from_u32(num).expect("sub_one: underflow or invalid char (e.g., called on '\\u{0}')")
876 }
877
878 #[inline]
879 fn assign_sub_one(&mut self) {
880 *self = self.sub_one();
881 }
882
883 #[inline]
884 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self> {
885 range.next()
886 }
887
888 #[inline]
889 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self> {
890 range.next_back()
891 }
892
893 #[inline]
894 fn min_value() -> Self {
895 '\u{0}'
896 }
897
898 #[inline]
899 fn max_value() -> Self {
900 '\u{10FFFF}'
901 }
902
903 #[cfg(feature = "from_slice")]
904 #[inline]
905 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self> {
906 RangeSetBlaze::from_iter(slice.as_ref())
907 }
908
909 fn safe_len(r: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen {
910 let start_num = u32::from(*r.start());
912 let end_num = u32::from(*r.end());
913 let mut len = (end_num - start_num) as <Self as Integer>::SafeLen + 1;
914 if start_num < SURROGATE_START && SURROGATE_END < end_num {
915 len -= (SURROGATE_END - SURROGATE_START + 1) as <Self as Integer>::SafeLen;
916 }
917 len
918 }
919
920 #[allow(clippy::cast_precision_loss, clippy::cast_lossless)]
921 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64 {
922 len as f64
923 }
924
925 #[allow(clippy::cast_possible_truncation)]
926 #[allow(clippy::cast_sign_loss)]
927 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen {
928 f as Self::SafeLen
929 }
930
931 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self {
932 fn private_panic(a: char, b: u32) -> ! {
933 let max_len = char::safe_len(&(char::MIN..=a));
934 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
935 }
936
937 let Some(b_minus_one) = b.checked_sub(1) else {
938 private_panic(self, b);
939 };
940
941 let a = u32::from(self);
942 let Some(mut num) = a.checked_add(b_minus_one) else {
943 private_panic(self, b);
944 };
945 if a < SURROGATE_START && SURROGATE_START <= num {
946 let Some(num2) = num.checked_add(SURROGATE_END - SURROGATE_START + 1) else {
947 private_panic(self, b);
948 };
949 num = num2;
950 }
951
952 let Some(result) = Self::from_u32(num) else {
953 private_panic(self, b);
954 };
955 result
956 }
957
958 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self {
959 fn private_panic(a: char, b: u32) -> ! {
960 let max_len = char::safe_len(&(char::MIN..=a));
961 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
962 }
963
964 let Some(b_minus_one) = b.checked_sub(1) else {
965 private_panic(self, b);
966 };
967
968 let a = u32::from(self);
969 let Some(mut num) = a.checked_sub(b_minus_one) else {
970 private_panic(self, b);
971 };
972 if num <= SURROGATE_END && SURROGATE_END < a {
973 let Some(num2) = num.checked_sub(SURROGATE_END - SURROGATE_START + 1) else {
974 private_panic(self, b);
975 };
976 num = num2;
977 }
978
979 Self::from_u32(num).expect("Real Assert: Impossible for this to fail")
980 }
981}
982
983#[cfg(test)]
984mod tests {
985 use super::*;
986 use crate::prelude::*;
987 use num_traits::{One, Zero};
988 use syntactic_for::syntactic_for;
989
990 use wasm_bindgen_test::*;
991 wasm_bindgen_test_configure!(run_in_browser);
992
993 #[test]
994 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
995 fn coverage_integer() {
996 let mut a = 0u8..=0u8;
997 assert_eq!(u8::range_next_back(&mut a), Some(0));
998 assert_eq!(u8::range_next(&mut a), None);
999
1000 let mut b = 0i128..=0i128;
1001 assert_eq!(i128::range_next_back(&mut b), Some(0));
1002 assert_eq!(i128::range_next(&mut b), None);
1003
1004 let mut b = 0i128;
1005 i128::assign_sub_one(&mut b);
1006 assert_eq!(b, -1);
1007
1008 let f = i128::safe_len_to_f64_lossy(UIntPlusOne::MaxPlusOne);
1010 let i = i128::f64_to_safe_len_lossy(f);
1011 assert_eq!(i, UIntPlusOne::MaxPlusOne);
1012
1013 let mut b = 0u128..=0u128;
1014 assert_eq!(u128::range_next_back(&mut b), Some(0));
1015 assert_eq!(u128::range_next(&mut b), None);
1016
1017 let mut b = 1u128;
1018 u128::assign_sub_one(&mut b);
1019 assert_eq!(b, 0);
1020
1021 let f = u128::safe_len_to_f64_lossy(UIntPlusOne::MaxPlusOne);
1023 let i = u128::f64_to_safe_len_lossy(f);
1024 assert_eq!(i, UIntPlusOne::MaxPlusOne);
1025 }
1026
1027 #[test]
1028 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1029 #[should_panic(expected = "1")]
1030 #[cfg(debug_assertions)] fn test_add_len_less_one_with_max_plus_one() {
1032 let value: i128 = 100;
1033 let len = UIntPlusOne::MaxPlusOne;
1034 let _ = value.inclusive_end_from_start(len); }
1036
1037 #[test]
1038 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1039 #[should_panic(expected = "2")]
1040 #[cfg(debug_assertions)] fn test_sub_len_less_one_with_max_plus_one() {
1042 let value: i128 = 100;
1043 let len = UIntPlusOne::MaxPlusOne;
1044 let _ = value.start_from_inclusive_end(len); }
1046
1047 #[test]
1048 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1049 #[allow(clippy::cognitive_complexity, clippy::legacy_numeric_constants)]
1050 fn test_ipv4_and_ipv6_etc() {
1051 syntactic_for! { ty in [char, Ipv6Addr, u128, i128, Ipv4Addr] {
1052 $(
1053 let a = <$ty>::min_value();
1055 let b = a.checked_add_one();
1056 assert_eq!(b, Some(<$ty>::min_value().add_one()));
1057
1058 let a = <$ty>::max_value();
1060 let b = a.checked_add_one();
1061 assert_eq!(b, None);
1062
1063 let a = <$ty>::min_value();
1064 let mut b = a.add_one();
1065 assert_eq!(b, <$ty>::min_value().add_one());
1066
1067 let c = b.sub_one();
1068 assert_eq!(c, a);
1069
1070 b.assign_sub_one();
1071 assert_eq!(b, a);
1072
1073 let mut a = <$ty>::min_value()..=<$ty>::min_value();
1074 let b = <$ty>::range_next(&mut a);
1075 assert_eq!(b, Some(<$ty>::min_value()));
1076 let b = <$ty>::range_next(&mut a);
1077 assert_eq!(b, None);
1078
1079 let mut a = <$ty>::min_value()..=<$ty>::max_value();
1080 let b = <$ty>::range_next_back(&mut a);
1081 assert_eq!(b, Some(<$ty>::max_value()));
1082
1083 assert_eq!(<$ty>::min_value(), <$ty>::min_value());
1084
1085 let universe = <$ty>::min_value()..=<$ty>::max_value();
1086 let len = <$ty>::safe_len(&universe);
1087 assert_eq!(len, <$ty>::safe_len(&(<$ty>::min_value()..=<$ty>::max_value())));
1088
1089 let len_via_f64 = <$ty>::f64_to_safe_len_lossy(<$ty>::safe_len_to_f64_lossy(len));
1090 assert_eq!(len, len_via_f64);
1091
1092 let short = <$ty>::min_value()..=<$ty>::min_value();
1093 let len = <$ty>::safe_len(&short);
1094 let len_via_f64 = <$ty>::f64_to_safe_len_lossy(<$ty>::safe_len_to_f64_lossy(len));
1095 assert_eq!(len, len_via_f64);
1096
1097 let len = <$ty>::safe_len(&universe);
1098 let b = <$ty>::min_value().inclusive_end_from_start(len);
1099 assert_eq!(b, <$ty>::max_value());
1100
1101 let c = b.start_from_inclusive_end(len);
1102 assert_eq!(c, <$ty>::min_value());
1103
1104 let range = <$ty>::min_value()..=<$ty>::min_value().add_one();
1105 let len2 = <$ty>::safe_len(&range);
1106 let b = <$ty>::min_value().inclusive_end_from_start(len2);
1107 assert_eq!(b, <$ty>::min_value().add_one());
1108
1109 let b = <$ty>::max_value().start_from_inclusive_end(len2);
1110 assert_eq!(b, <$ty>::max_value().sub_one());
1111
1112 #[cfg(feature = "from_slice")]
1113 {
1114 let range_set_blaze = <$ty>::from_slice(&[<$ty>::min_value()]);
1115 assert_eq!(range_set_blaze, RangeSetBlaze::from_iter([<$ty>::min_value()]));
1116 }
1117 )*
1118 }}
1119 }
1120
1121 #[test]
1122 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1123 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1124 #[allow(clippy::legacy_numeric_constants)]
1125 fn test_i128_overflow() {
1126 let value: i128 = i128::max_value();
1127 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1128 }
1129
1130 #[test]
1131 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1132 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1133 #[allow(clippy::legacy_numeric_constants)]
1134 fn test_i128_underflow() {
1135 let value: i128 = i128::min_value();
1136 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1137 }
1138
1139 #[test]
1140 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1141 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1142 #[allow(clippy::legacy_numeric_constants)]
1143 fn test_u128_overflow() {
1144 let value: u128 = u128::max_value();
1145 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1146 }
1147
1148 #[test]
1149 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1150 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1151 #[allow(clippy::legacy_numeric_constants)]
1152 fn test_u128_underflow() {
1153 let value: u128 = u128::min_value();
1154 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1155 }
1156
1157 #[test]
1158 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1159 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1160 #[allow(clippy::legacy_numeric_constants)]
1161 fn test_ipv6_overflow() {
1162 let value: Ipv6Addr = Ipv6Addr::max_value();
1163 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1164 }
1165
1166 #[test]
1167 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1168 #[should_panic(expected = "char overflow")]
1169 #[allow(clippy::legacy_numeric_constants)]
1170 fn test_char0_overflow() {
1171 let value: char = char::max_value();
1172 let _ = value.add_one();
1173 }
1174
1175 #[test]
1176 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1177 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1112064)")]
1178 #[allow(clippy::legacy_numeric_constants)]
1179 fn test_char1_overflow() {
1180 let value: char = char::max_value();
1181 let len2 = char::safe_len(&(char::min_value()..=char::min_value().add_one()));
1182 let _ = value.inclusive_end_from_start(len2);
1183 }
1184
1185 #[test]
1186 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1187 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1188 #[allow(clippy::legacy_numeric_constants)]
1189 fn test_char1_underflow() {
1190 let value: char = char::min_value();
1191 let len2 = char::safe_len(&(char::min_value()..=char::min_value().add_one()));
1192 let _ = value.start_from_inclusive_end(len2);
1193 }
1194
1195 #[test]
1196 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1197 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1198 fn test_ipv6_underflow() {
1199 let value: Ipv6Addr = Ipv6Addr::min_value();
1200 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1201 }
1202
1203 #[test]
1204 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1205 #[allow(clippy::cognitive_complexity)]
1206 fn test_char() {
1207 let universe = !RangeSetBlaze::<char>::default();
1210
1211 let max_value = <char as Integer>::max_value();
1213 assert_eq!(max_value.checked_add_one(), None);
1214
1215 let mut prev = None;
1216 let mut len = <char as Integer>::SafeLen::zero();
1217 for item in <char as Integer>::min_value()..=max_value {
1218 let len2b = <char as Integer>::safe_len(&(item..=max_value));
1219 let mut expected = universe.len();
1220 expected -= len;
1221 assert_eq!(len2b, expected);
1222
1223 let item2 = max_value.start_from_inclusive_end(len2b);
1224 assert_eq!(item2, item);
1225
1226 let item3 = item2.inclusive_end_from_start(len2b);
1227 assert_eq!(item3, max_value);
1228
1229 len += <char as Integer>::SafeLen::one();
1230 let len2 = <char as Integer>::safe_len(&(<char as Integer>::min_value()..=item));
1231 assert_eq!(len, len2);
1232 assert_eq!(
1233 len2,
1234 <char as Integer>::f64_to_safe_len_lossy(<char as Integer>::safe_len_to_f64_lossy(
1235 len2
1236 ))
1237 );
1238
1239 let item2 = <char as Integer>::min_value().inclusive_end_from_start(len);
1240 assert_eq!(item2, item);
1241
1242 let item3 = item.start_from_inclusive_end(len);
1243 assert_eq!(item3, <char as Integer>::min_value());
1244
1245 if let Some(prev) = prev {
1246 assert!(universe.contains(prev));
1247 assert!(universe.contains(item));
1248 assert!(universe.is_superset(&RangeSetBlaze::from_iter([prev..=item])));
1249
1250 assert_eq!(prev.checked_add_one(), Some(item));
1251 assert_eq!(prev.add_one(), item);
1252
1253 assert_eq!(item.sub_one(), prev);
1254 let mut item2 = item;
1255 item2.assign_sub_one();
1256 assert_eq!(item2, prev);
1257 }
1258
1259 prev = Some(item);
1260 }
1261 assert_eq!(universe.len(), len);
1262
1263 }
1265
1266 #[test]
1267 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1268 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 66)")]
1269 fn test_add_len_less_one_panic_conditions1() {
1270 let character = 'A';
1272 let b = 0;
1273 _ = character.inclusive_end_from_start(b); }
1275
1276 #[test]
1277 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1278 #[should_panic(expected = "b must be in range 1..=max_len (b = 3, max_len = 1112064)")]
1279 fn test_add_len_less_one_panic_conditions2() {
1280 let character = char::MAX;
1282 let b = 3;
1283 _ = character.inclusive_end_from_start(b); }
1285
1286 #[test]
1287 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1288 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294967295, max_len = 66)")]
1289 fn test_add_len_less_one_panic_conditions3() {
1290 let character = 'A';
1292 let b = u32::MAX;
1293 _ = character.inclusive_end_from_start(b); }
1295
1296 #[test]
1297 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1298 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 66)")]
1299 fn test_sub_len_less_one_panic_conditions1() {
1300 let character = 'A';
1302 let b = 0;
1303 _ = character.start_from_inclusive_end(b); }
1305
1306 #[test]
1307 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1308 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294967295, max_len = 66)")]
1309 fn test_sub_len_less_one_panic_conditions2() {
1310 let character = 'A';
1312 let b = u32::MAX;
1313 _ = character.start_from_inclusive_end(b); }
1315
1316 #[allow(clippy::legacy_numeric_constants, clippy::cognitive_complexity)]
1317 #[test]
1318 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1319 fn test_use_of_as_00() {
1320 syntactic_for! { ty in [char, i8, i16, i32, i64, i128, isize, Ipv4Addr, Ipv6Addr, u8, u16, u32, u64, u128, usize] {
1321 $(
1322 let a = <$ty>::min_value();
1323 let b = <$ty>::max_value();
1324 let len = <$ty>::safe_len(&(a..=b));
1325 assert_eq!(<$ty>::inclusive_end_from_start(a, len), b);
1326 assert_eq!(<$ty>::start_from_inclusive_end(b, len), a);
1327 )*
1328 }}
1329 }
1330
1331 #[cfg(debug_assertions)]
1332 #[test]
1333 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1334 fn test_use_of_as_01() {
1335 let _ = 127i8.inclusive_end_from_start(0);
1336 }
1337
1338 #[cfg(not(debug_assertions))]
1339 #[test]
1340 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1341 fn test_use_of_as_02() {
1342 assert_eq!(127i8.inclusive_end_from_start(0), 126);
1343 assert_eq!(127i8.start_from_inclusive_end(0), -128);
1344 assert_eq!(127i8.inclusive_end_from_start(2), -128);
1345 assert_eq!((-126i8).start_from_inclusive_end(4), 127);
1346 }
1347
1348 #[cfg(debug_assertions)]
1349 #[test]
1350 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 256)")]
1351 fn test_use_of_as_03() {
1352 let _ = 127i8.start_from_inclusive_end(0);
1353 }
1354
1355 #[cfg(debug_assertions)]
1356 #[test]
1357 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1358 fn test_use_of_as_04() {
1359 let _ = 127i8.inclusive_end_from_start(2);
1360 }
1361
1362 #[cfg(debug_assertions)]
1363 #[test]
1364 #[should_panic(expected = "b must be in range 1..=max_len (b = 4, max_len = 3)")]
1365 fn test_use_of_as_05() {
1366 let _ = (-126i8).start_from_inclusive_end(4);
1367 }
1368
1369 #[test]
1370 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1371 fn test_use_of_as_06() {
1372 for a in (-128i8)..=127i8 {
1373 let b = i8::safe_len(&(a..=127i8));
1374 assert_eq!(a.inclusive_end_from_start(b), 127i8);
1375 let b = i8::safe_len(&(i8::MIN..=a));
1376 assert_eq!(a.start_from_inclusive_end(b), -128i8);
1377 }
1378 }
1379
1380 #[cfg(debug_assertions)]
1382 #[test]
1383 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1384 fn test_use_of_as_11() {
1385 let _ = i128::MAX.inclusive_end_from_start(UIntPlusOne::zero());
1386 }
1387
1388 #[cfg(not(debug_assertions))]
1389 #[test]
1390 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1391 fn test_use_of_as_12() {
1392 assert_eq!(
1393 i128::MAX.inclusive_end_from_start(UIntPlusOne::zero()),
1394 170141183460469231731687303715884105726
1395 );
1396 assert_eq!(
1397 i128::MAX.start_from_inclusive_end(UIntPlusOne::zero()),
1398 -170141183460469231731687303715884105728
1399 );
1400 assert_eq!(
1401 i128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2)),
1402 -170141183460469231731687303715884105728
1403 );
1404 assert_eq!(
1405 (i128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1406 170141183460469231731687303715884105727
1407 );
1408 }
1409
1410 #[cfg(debug_assertions)]
1411 #[test]
1412 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1413 fn test_use_of_as_13() {
1414 let _ = i128::MAX.start_from_inclusive_end(UIntPlusOne::zero());
1415 }
1416
1417 #[cfg(debug_assertions)]
1418 #[test]
1419 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1420 fn test_use_of_as_14() {
1421 let _ = i128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2));
1422 }
1423
1424 #[cfg(debug_assertions)]
1425 #[test]
1426 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1427 fn test_use_of_as_15() {
1428 let _ = (i128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2));
1429 }
1430
1431 #[test]
1432 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1433 fn test_use_of_as_16() {
1434 assert_eq!(
1435 (i128::MIN).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1436 i128::MAX
1437 );
1438 assert_eq!(
1439 (i128::MAX).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1440 i128::MIN
1441 );
1442 }
1443
1444 #[test]
1445 #[should_panic(
1446 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 170141183460469231731687303715884105728)"
1447 )]
1448 fn test_use_of_as_17() {
1449 let _ = (0i128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1450 }
1451
1452 #[test]
1453 #[should_panic(
1454 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 170141183460469231731687303715884105729)"
1455 )]
1456 fn test_use_of_as_18() {
1457 let _ = (0i128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1458 }
1459
1460 #[cfg(debug_assertions)]
1462 #[test]
1463 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1464 fn test_use_of_as_21() {
1465 let _ = u128::MAX.inclusive_end_from_start(UIntPlusOne::zero());
1466 }
1467
1468 #[cfg(not(debug_assertions))]
1469 #[test]
1470 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1471 fn test_use_of_as_22() {
1472 assert_eq!(
1473 u128::MAX.inclusive_end_from_start(UIntPlusOne::zero()),
1474 340282366920938463463374607431768211454
1475 );
1476 assert_eq!(u128::MAX.start_from_inclusive_end(UIntPlusOne::zero()), 0);
1477 assert_eq!(u128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2)), 0);
1478 assert_eq!(
1479 (u128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1480 340282366920938463463374607431768211455
1481 );
1482 }
1483
1484 #[cfg(debug_assertions)]
1485 #[test]
1486 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1487 fn test_use_of_as_23() {
1488 let _ = u128::MAX.start_from_inclusive_end(UIntPlusOne::zero());
1489 }
1490
1491 #[cfg(debug_assertions)]
1492 #[test]
1493 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1494 fn test_use_of_as_24() {
1495 let _ = u128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2));
1496 }
1497
1498 #[cfg(debug_assertions)]
1499 #[test]
1500 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1501 fn test_use_of_as_25() {
1502 let _ = (u128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2));
1503 }
1504
1505 #[test]
1506 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1507 fn test_use_of_as_26() {
1508 assert_eq!(
1509 (u128::MIN).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1510 u128::MAX
1511 );
1512 assert_eq!(
1513 (u128::MAX).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1514 u128::MIN
1515 );
1516 }
1517
1518 #[test]
1519 #[should_panic(
1520 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 340282366920938463463374607431768211454)"
1521 )]
1522 fn test_use_of_as_27() {
1523 let _ = (2u128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1524 }
1525
1526 #[test]
1527 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1528 fn test_use_of_as_28() {
1529 let _ = (0u128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1530 }
1531
1532 #[cfg(debug_assertions)]
1534 #[test]
1535 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1536 fn test_use_of_as_31() {
1537 let _ = Ipv4Addr::max_value().inclusive_end_from_start(0);
1538 }
1539
1540 #[cfg(not(debug_assertions))]
1541 #[test]
1542 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1543 fn test_use_of_as_32() {
1544 assert_eq!(
1545 Ipv4Addr::max_value().inclusive_end_from_start(0),
1546 Ipv4Addr::new(255, 255, 255, 254)
1547 );
1548 assert_eq!(
1549 Ipv4Addr::max_value().start_from_inclusive_end(0),
1550 Ipv4Addr::from(0)
1551 );
1552 assert_eq!(
1553 Ipv4Addr::max_value().inclusive_end_from_start(2),
1554 Ipv4Addr::from(0)
1555 );
1556 assert_eq!(
1557 Ipv4Addr::min_value().start_from_inclusive_end(2),
1558 Ipv4Addr::new(255, 255, 255, 255)
1559 );
1560 assert_eq!(
1561 Ipv4Addr::new(0, 0, 0, 2).inclusive_end_from_start(u64::MAX),
1562 Ipv4Addr::from(0)
1563 );
1564
1565 assert_eq!(
1566 Ipv4Addr::new(0, 0, 0, 0).start_from_inclusive_end(u64::MAX),
1567 Ipv4Addr::new(0, 0, 0, 2)
1568 );
1569 }
1570
1571 #[cfg(debug_assertions)]
1572 #[test]
1573 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 4294967296)")]
1574 fn test_use_of_as_33() {
1575 let _ = Ipv4Addr::max_value().start_from_inclusive_end(0);
1576 }
1577
1578 #[cfg(debug_assertions)]
1579 #[test]
1580 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1581 fn test_use_of_as_34() {
1582 let _ = Ipv4Addr::max_value().inclusive_end_from_start(2);
1583 }
1584
1585 #[cfg(debug_assertions)]
1586 #[test]
1587 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1588 fn test_use_of_as_35() {
1589 let _ = (Ipv4Addr::min_value()).start_from_inclusive_end(2);
1590 }
1591
1592 #[cfg(debug_assertions)]
1595 #[test]
1596 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1597 fn test_use_of_as_41() {
1598 let _ = Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::zero());
1599 }
1600
1601 #[cfg(not(debug_assertions))]
1602 #[test]
1603 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1604 fn test_use_of_as_42() {
1605 assert_eq!(
1606 Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::zero()),
1607 Ipv6Addr::from(340282366920938463463374607431768211454)
1608 );
1609 assert_eq!(
1610 Ipv6Addr::max_value().start_from_inclusive_end(UIntPlusOne::zero()),
1611 Ipv6Addr::from(0)
1612 );
1613 assert_eq!(
1614 Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::UInt(2)),
1615 Ipv6Addr::from(0)
1616 );
1617 assert_eq!(
1618 (Ipv6Addr::min_value()).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1619 Ipv6Addr::from(340282366920938463463374607431768211455)
1620 );
1621 }
1622
1623 #[cfg(debug_assertions)]
1624 #[test]
1625 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1626 fn test_use_of_as_43() {
1627 let _ = Ipv6Addr::max_value().start_from_inclusive_end(UIntPlusOne::zero());
1628 }
1629
1630 #[cfg(debug_assertions)]
1631 #[test]
1632 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1633 fn test_use_of_as_44() {
1634 let _ = Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::UInt(2));
1635 }
1636
1637 #[cfg(debug_assertions)]
1638 #[test]
1639 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1640 fn test_use_of_as_45() {
1641 let _ = (Ipv6Addr::min_value()).start_from_inclusive_end(UIntPlusOne::UInt(2));
1642 }
1643
1644 #[test]
1645 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1646 fn test_use_of_as_46() {
1647 assert_eq!(
1648 (Ipv6Addr::min_value()).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1649 Ipv6Addr::max_value()
1650 );
1651 assert_eq!(
1652 (Ipv6Addr::max_value()).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1653 Ipv6Addr::min_value()
1654 );
1655 }
1656
1657 #[test]
1658 #[should_panic(
1659 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 340282366920938463463374607431768211454)"
1660 )]
1661 fn test_use_of_as_47() {
1662 let _ = Ipv6Addr::from(2u128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1663 }
1664
1665 #[test]
1666 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1667 fn test_use_of_as_48() {
1668 let _ = Ipv6Addr::from(0u128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1669 }
1670
1671 #[test]
1674 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1112064)")]
1675 fn test_use_of_as_51() {
1676 let _ = char::max_value().inclusive_end_from_start(0);
1677 }
1678
1679 #[test]
1680 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1112064)")]
1681 fn test_use_of_as_53() {
1682 let _ = char::max_value().start_from_inclusive_end(0);
1683 }
1684
1685 #[test]
1686 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1112064)")]
1687 fn test_use_of_as_54() {
1688 let _ = char::max_value().inclusive_end_from_start(2);
1689 }
1690
1691 #[test]
1692 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1693 fn test_use_of_as_55() {
1694 let _ = (char::min_value()).start_from_inclusive_end(2);
1695 }
1696
1697 #[test]
1698 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1699 fn test_use_of_as_56() {
1700 assert_eq!(
1701 (char::min_value()).inclusive_end_from_start(1_112_064),
1702 char::max_value()
1703 );
1704 assert_eq!(
1705 (char::max_value()).start_from_inclusive_end(1_112_064),
1706 char::min_value()
1707 );
1708 }
1709
1710 #[test]
1711 #[should_panic(expected = "b must be in range 1..=max_len (b = 1112064, max_len = 3)")]
1712 fn test_use_of_as_57() {
1713 let _ = '\x02'.inclusive_end_from_start(1_112_064);
1714 }
1715
1716 #[test]
1717 #[should_panic(expected = "b must be in range 1..=max_len (b = 1112064, max_len = 1)")]
1718 fn test_use_of_as_58() {
1719 let _ = '\x00'.start_from_inclusive_end(1_112_064);
1720 }
1721
1722 #[test]
1723 #[cfg(debug_assertions)]
1724 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1725 #[should_panic(expected = "assertion failed: r.start() <= r.end()")]
1726 #[allow(clippy::reversed_empty_ranges)]
1727 fn test_safe_len() {
1728 let i = 0u128..=0u128;
1729 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(1));
1730
1731 let i = 0u128..=1u128;
1732 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(2));
1733
1734 let i = 1u128..=0u128;
1735 let _ = u128::safe_len(&i);
1737 }
1738
1739 #[test]
1740 #[cfg(debug_assertions)]
1741 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1742 #[should_panic(expected = "assertion failed: r.start() <= r.end()")]
1743 #[allow(clippy::reversed_empty_ranges)]
1744 fn safe_len2() {
1745 let i = 0u128..=0u128;
1746 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(1));
1747
1748 let i = 0u128..=1u128;
1749 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(2));
1750
1751 let i = 1u128..=0u128;
1752 let _ = u128::safe_len(&i);
1754 }
1755
1756 #[test]
1757 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1758 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294911999, max_len = 55295)")]
1759 fn safe_len_char1() {
1760 let a = '\u{D7FE}';
1761 let len = 4_294_911_999u32;
1762 let _ = a.inclusive_end_from_start(len);
1763 }
1764
1765 #[test]
1766 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1767 #[should_panic(expected = "b must be in range 1..=max_len (b = 57343, max_len = 55297)")]
1768 fn safe_len_char2() {
1769 let a = '\u{E000}';
1770 let len = 0xDFFFu32;
1771 let _ = a.start_from_inclusive_end(len);
1772 }
1773}