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