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