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, clippy::legacy_numeric_constants)]
1075 fn test_ipv4_and_ipv6_etc() {
1076 syntactic_for! { ty in [char, Ipv6Addr, u128, i128, Ipv4Addr] {
1077 $(
1078 let a = <$ty>::min_value();
1080 let b = a.checked_add_one();
1081 assert_eq!(b, Some(<$ty>::min_value().add_one()));
1082
1083 let a = <$ty>::max_value();
1085 let b = a.checked_add_one();
1086 assert_eq!(b, None);
1087
1088 let a = <$ty>::min_value();
1089 let mut b = a.add_one();
1090 assert_eq!(b, <$ty>::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>::min_value()..=<$ty>::min_value();
1099 let b = <$ty>::range_next(&mut a);
1100 assert_eq!(b, Some(<$ty>::min_value()));
1101 let b = <$ty>::range_next(&mut a);
1102 assert_eq!(b, None);
1103
1104 let mut a = <$ty>::min_value()..=<$ty>::max_value();
1105 let b = <$ty>::range_next_back(&mut a);
1106 assert_eq!(b, Some(<$ty>::max_value()));
1107
1108 assert_eq!(<$ty>::min_value(), <$ty>::min_value());
1109
1110 let universe = <$ty>::min_value()..=<$ty>::max_value();
1111 let len = <$ty>::safe_len(&universe);
1112 assert_eq!(len, <$ty>::safe_len(&(<$ty>::min_value()..=<$ty>::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>::min_value()..=<$ty>::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>::min_value().inclusive_end_from_start(len);
1124 assert_eq!(b, <$ty>::max_value());
1125
1126 let c = b.start_from_inclusive_end(len);
1127 assert_eq!(c, <$ty>::min_value());
1128
1129 let range = <$ty>::min_value()..=<$ty>::min_value().add_one();
1130 let len2 = <$ty>::safe_len(&range);
1131 let b = <$ty>::min_value().inclusive_end_from_start(len2);
1132 assert_eq!(b, <$ty>::min_value().add_one());
1133
1134 let b = <$ty>::max_value().start_from_inclusive_end(len2);
1135 assert_eq!(b, <$ty>::max_value().sub_one());
1136
1137 #[cfg(feature = "from_slice")]
1138 {
1139 let range_set_blaze = <$ty>::from_slice(&[<$ty>::min_value()]);
1140 assert_eq!(range_set_blaze, RangeSetBlaze::from_iter([<$ty>::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 #[allow(clippy::legacy_numeric_constants)]
1150 fn test_i128_overflow() {
1151 let value: i128 = i128::max_value();
1152 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1153 }
1154
1155 #[test]
1156 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1157 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 1)")]
1158 #[allow(clippy::legacy_numeric_constants)]
1159 fn test_i128_underflow() {
1160 let value: i128 = i128::min_value();
1161 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1162 }
1163
1164 #[test]
1165 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1166 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 1)")]
1167 #[allow(clippy::legacy_numeric_constants)]
1168 fn test_u128_overflow() {
1169 let value: u128 = u128::max_value();
1170 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1171 }
1172
1173 #[test]
1174 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1175 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 1)")]
1176 #[allow(clippy::legacy_numeric_constants)]
1177 fn test_u128_underflow() {
1178 let value: u128 = u128::min_value();
1179 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1180 }
1181
1182 #[test]
1183 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1184 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 1)")]
1185 #[allow(clippy::legacy_numeric_constants)]
1186 fn test_ipv6_overflow() {
1187 let value: Ipv6Addr = Ipv6Addr::max_value();
1188 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1189 }
1190
1191 #[test]
1192 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1193 #[should_panic(expected = "char overflow")]
1194 #[allow(clippy::legacy_numeric_constants)]
1195 fn test_char0_overflow() {
1196 let value: char = char::max_value();
1197 let _ = value.add_one();
1198 }
1199
1200 #[test]
1201 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1202 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1112064)")]
1203 #[allow(clippy::legacy_numeric_constants)]
1204 fn test_char1_overflow() {
1205 let value: char = char::max_value();
1206 let len2 = char::safe_len(&(char::min_value()..=char::min_value().add_one()));
1207 let _ = value.inclusive_end_from_start(len2);
1208 }
1209
1210 #[test]
1211 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1212 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1213 #[allow(clippy::legacy_numeric_constants)]
1214 fn test_char1_underflow() {
1215 let value: char = char::min_value();
1216 let len2 = char::safe_len(&(char::min_value()..=char::min_value().add_one()));
1217 let _ = value.start_from_inclusive_end(len2);
1218 }
1219
1220 #[test]
1221 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1222 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 1)")]
1223 fn test_ipv6_underflow() {
1224 let value: Ipv6Addr = Ipv6Addr::min_value();
1225 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1226 }
1227
1228 #[test]
1229 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1230 #[allow(clippy::cognitive_complexity)]
1231 fn test_char() {
1232 let universe = !RangeSetBlaze::<char>::default();
1235
1236 let max_value = char::max_value();
1238 assert_eq!(max_value.checked_add_one(), None);
1239
1240 let mut prev = None;
1241 let mut len = <char as Integer>::SafeLen::zero();
1242 for item in char::min_value()..=max_value {
1243 let len2b = char::safe_len(&(item..=max_value));
1244 let mut expected = universe.len();
1245 expected -= len;
1246 assert_eq!(len2b, expected);
1247
1248 let item2 = max_value.start_from_inclusive_end(len2b);
1249 assert_eq!(item2, item);
1250
1251 let item3 = item2.inclusive_end_from_start(len2b);
1252 assert_eq!(item3, max_value);
1253
1254 len += <char as Integer>::SafeLen::one();
1255 let len2 = char::safe_len(&(char::min_value()..=item));
1256 assert_eq!(len, len2);
1257 assert_eq!(
1258 len2,
1259 char::f64_to_safe_len_lossy(char::safe_len_to_f64_lossy(len2))
1260 );
1261
1262 let item2 = char::min_value().inclusive_end_from_start(len);
1263 assert_eq!(item2, item);
1264
1265 let item3 = item.start_from_inclusive_end(len);
1266 assert_eq!(item3, char::min_value());
1267
1268 if let Some(prev) = prev {
1269 assert!(universe.contains(prev));
1270 assert!(universe.contains(item));
1271 assert!(universe.is_superset(&RangeSetBlaze::from_iter([prev..=item])));
1272
1273 assert_eq!(prev.checked_add_one(), Some(item));
1274 assert_eq!(prev.add_one(), item);
1275
1276 assert_eq!(item.sub_one(), prev);
1277 let mut item2 = item;
1278 item2.assign_sub_one();
1279 assert_eq!(item2, prev);
1280 }
1281
1282 prev = Some(item);
1283 }
1284 assert_eq!(universe.len(), len);
1285
1286 }
1288
1289 #[test]
1290 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1291 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 66)")]
1292 fn test_add_len_less_one_panic_conditions1() {
1293 let character = 'A';
1295 let b = 0;
1296 _ = character.inclusive_end_from_start(b); }
1298
1299 #[test]
1300 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1301 #[should_panic(expected = "b must be in range 1..=max_len (b = 3, max_len = 1112064)")]
1302 fn test_add_len_less_one_panic_conditions2() {
1303 let character = char::MAX;
1305 let b = 3;
1306 _ = character.inclusive_end_from_start(b); }
1308
1309 #[test]
1310 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1311 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294967295, max_len = 66)")]
1312 fn test_add_len_less_one_panic_conditions3() {
1313 let character = 'A';
1315 let b = u32::MAX;
1316 _ = character.inclusive_end_from_start(b); }
1318
1319 #[test]
1320 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1321 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 66)")]
1322 fn test_sub_len_less_one_panic_conditions1() {
1323 let character = 'A';
1325 let b = 0;
1326 _ = character.start_from_inclusive_end(b); }
1328
1329 #[test]
1330 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1331 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294967295, max_len = 66)")]
1332 fn test_sub_len_less_one_panic_conditions2() {
1333 let character = 'A';
1335 let b = u32::MAX;
1336 _ = character.start_from_inclusive_end(b); }
1338
1339 #[allow(clippy::legacy_numeric_constants, clippy::cognitive_complexity)]
1340 #[test]
1341 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1342 fn test_use_of_as_00() {
1343 syntactic_for! { ty in [char, i8, i16, i32, i64, i128, isize, Ipv4Addr, Ipv6Addr, u8, u16, u32, u64, u128, usize] {
1344 $(
1345 let a = <$ty>::min_value();
1346 let b = <$ty>::max_value();
1347 let len = <$ty>::safe_len(&(a..=b));
1348 assert_eq!(<$ty>::inclusive_end_from_start(a, len), b);
1349 assert_eq!(<$ty>::start_from_inclusive_end(b, len), a);
1350 )*
1351 }}
1352 }
1353
1354 #[cfg(debug_assertions)]
1355 #[test]
1356 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1357 fn test_use_of_as_01() {
1358 let _ = 127i8.inclusive_end_from_start(0);
1359 }
1360
1361 #[cfg(not(debug_assertions))]
1362 #[test]
1363 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1364 fn test_use_of_as_02() {
1365 assert_eq!(127i8.inclusive_end_from_start(0), 126);
1366 assert_eq!(127i8.start_from_inclusive_end(0), -128);
1367 assert_eq!(127i8.inclusive_end_from_start(2), -128);
1368 assert_eq!((-126i8).start_from_inclusive_end(4), 127);
1369 }
1370
1371 #[cfg(debug_assertions)]
1372 #[test]
1373 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 256)")]
1374 fn test_use_of_as_03() {
1375 let _ = 127i8.start_from_inclusive_end(0);
1376 }
1377
1378 #[cfg(debug_assertions)]
1379 #[test]
1380 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1381 fn test_use_of_as_04() {
1382 let _ = 127i8.inclusive_end_from_start(2);
1383 }
1384
1385 #[cfg(debug_assertions)]
1386 #[test]
1387 #[should_panic(expected = "b must be in range 1..=max_len (b = 4, max_len = 3)")]
1388 fn test_use_of_as_05() {
1389 let _ = (-126i8).start_from_inclusive_end(4);
1390 }
1391
1392 #[test]
1393 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1394 fn test_use_of_as_06() {
1395 for a in (-128i8)..=127i8 {
1396 let b = i8::safe_len(&(a..=127i8));
1397 assert_eq!(a.inclusive_end_from_start(b), 127i8);
1398 let b = i8::safe_len(&(i8::MIN..=a));
1399 assert_eq!(a.start_from_inclusive_end(b), -128i8);
1400 }
1401 }
1402
1403 #[cfg(debug_assertions)]
1405 #[test]
1406 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1407 fn test_use_of_as_11() {
1408 let _ = i128::MAX.inclusive_end_from_start(UIntPlusOne::zero());
1409 }
1410
1411 #[cfg(not(debug_assertions))]
1412 #[test]
1413 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1414 fn test_use_of_as_12() {
1415 assert_eq!(
1416 i128::MAX.inclusive_end_from_start(UIntPlusOne::zero()),
1417 170141183460469231731687303715884105726
1418 );
1419 assert_eq!(
1420 i128::MAX.start_from_inclusive_end(UIntPlusOne::zero()),
1421 -170141183460469231731687303715884105728
1422 );
1423 assert_eq!(
1424 i128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2)),
1425 -170141183460469231731687303715884105728
1426 );
1427 assert_eq!(
1428 (i128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1429 170141183460469231731687303715884105727
1430 );
1431 }
1432
1433 #[cfg(debug_assertions)]
1434 #[test]
1435 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1436 fn test_use_of_as_13() {
1437 let _ = i128::MAX.start_from_inclusive_end(UIntPlusOne::zero());
1438 }
1439
1440 #[cfg(debug_assertions)]
1441 #[test]
1442 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1443 fn test_use_of_as_14() {
1444 let _ = i128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2));
1445 }
1446
1447 #[cfg(debug_assertions)]
1448 #[test]
1449 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1450 fn test_use_of_as_15() {
1451 let _ = (i128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2));
1452 }
1453
1454 #[test]
1455 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1456 fn test_use_of_as_16() {
1457 assert_eq!(
1458 (i128::MIN).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1459 i128::MAX
1460 );
1461 assert_eq!(
1462 (i128::MAX).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1463 i128::MIN
1464 );
1465 }
1466
1467 #[test]
1468 #[should_panic(
1469 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 170141183460469231731687303715884105728)"
1470 )]
1471 fn test_use_of_as_17() {
1472 let _ = (0i128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1473 }
1474
1475 #[test]
1476 #[should_panic(
1477 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 170141183460469231731687303715884105729)"
1478 )]
1479 fn test_use_of_as_18() {
1480 let _ = (0i128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1481 }
1482
1483 #[cfg(debug_assertions)]
1485 #[test]
1486 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1487 fn test_use_of_as_21() {
1488 let _ = u128::MAX.inclusive_end_from_start(UIntPlusOne::zero());
1489 }
1490
1491 #[cfg(not(debug_assertions))]
1492 #[test]
1493 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1494 fn test_use_of_as_22() {
1495 assert_eq!(
1496 u128::MAX.inclusive_end_from_start(UIntPlusOne::zero()),
1497 340282366920938463463374607431768211454
1498 );
1499 assert_eq!(u128::MAX.start_from_inclusive_end(UIntPlusOne::zero()), 0);
1500 assert_eq!(u128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2)), 0);
1501 assert_eq!(
1502 (u128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1503 340282366920938463463374607431768211455
1504 );
1505 }
1506
1507 #[cfg(debug_assertions)]
1508 #[test]
1509 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1510 fn test_use_of_as_23() {
1511 let _ = u128::MAX.start_from_inclusive_end(UIntPlusOne::zero());
1512 }
1513
1514 #[cfg(debug_assertions)]
1515 #[test]
1516 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1517 fn test_use_of_as_24() {
1518 let _ = u128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2));
1519 }
1520
1521 #[cfg(debug_assertions)]
1522 #[test]
1523 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1524 fn test_use_of_as_25() {
1525 let _ = (u128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2));
1526 }
1527
1528 #[test]
1529 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1530 fn test_use_of_as_26() {
1531 assert_eq!(
1532 (u128::MIN).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1533 u128::MAX
1534 );
1535 assert_eq!(
1536 (u128::MAX).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1537 u128::MIN
1538 );
1539 }
1540
1541 #[test]
1542 #[should_panic(
1543 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 340282366920938463463374607431768211454)"
1544 )]
1545 fn test_use_of_as_27() {
1546 let _ = (2u128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1547 }
1548
1549 #[test]
1550 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 1)")]
1551 fn test_use_of_as_28() {
1552 let _ = (0u128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1553 }
1554
1555 #[cfg(debug_assertions)]
1557 #[test]
1558 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1559 fn test_use_of_as_31() {
1560 let _ = Ipv4Addr::max_value().inclusive_end_from_start(0);
1561 }
1562
1563 #[cfg(not(debug_assertions))]
1564 #[test]
1565 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1566 fn test_use_of_as_32() {
1567 assert_eq!(
1568 Ipv4Addr::max_value().inclusive_end_from_start(0),
1569 Ipv4Addr::new(255, 255, 255, 254)
1570 );
1571 assert_eq!(
1572 Ipv4Addr::max_value().start_from_inclusive_end(0),
1573 Ipv4Addr::from(0)
1574 );
1575 assert_eq!(
1576 Ipv4Addr::max_value().inclusive_end_from_start(2),
1577 Ipv4Addr::from(0)
1578 );
1579 assert_eq!(
1580 Ipv4Addr::min_value().start_from_inclusive_end(2),
1581 Ipv4Addr::new(255, 255, 255, 255)
1582 );
1583 assert_eq!(
1584 Ipv4Addr::new(0, 0, 0, 2).inclusive_end_from_start(u64::MAX),
1585 Ipv4Addr::from(0)
1586 );
1587
1588 assert_eq!(
1589 Ipv4Addr::new(0, 0, 0, 0).start_from_inclusive_end(u64::MAX),
1590 Ipv4Addr::new(0, 0, 0, 2)
1591 );
1592 }
1593
1594 #[cfg(debug_assertions)]
1595 #[test]
1596 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 4294967296)")]
1597 fn test_use_of_as_33() {
1598 let _ = Ipv4Addr::max_value().start_from_inclusive_end(0);
1599 }
1600
1601 #[cfg(debug_assertions)]
1602 #[test]
1603 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1604 fn test_use_of_as_34() {
1605 let _ = Ipv4Addr::max_value().inclusive_end_from_start(2);
1606 }
1607
1608 #[cfg(debug_assertions)]
1609 #[test]
1610 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1611 fn test_use_of_as_35() {
1612 let _ = (Ipv4Addr::min_value()).start_from_inclusive_end(2);
1613 }
1614
1615 #[cfg(debug_assertions)]
1618 #[test]
1619 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1620 fn test_use_of_as_41() {
1621 let _ = Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::zero());
1622 }
1623
1624 #[cfg(not(debug_assertions))]
1625 #[test]
1626 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1627 fn test_use_of_as_42() {
1628 assert_eq!(
1629 Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::zero()),
1630 Ipv6Addr::from(340282366920938463463374607431768211454)
1631 );
1632 assert_eq!(
1633 Ipv6Addr::max_value().start_from_inclusive_end(UIntPlusOne::zero()),
1634 Ipv6Addr::from(0)
1635 );
1636 assert_eq!(
1637 Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::UInt(2)),
1638 Ipv6Addr::from(0)
1639 );
1640 assert_eq!(
1641 (Ipv6Addr::min_value()).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1642 Ipv6Addr::from(340282366920938463463374607431768211455)
1643 );
1644 }
1645
1646 #[cfg(debug_assertions)]
1647 #[test]
1648 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1649 fn test_use_of_as_43() {
1650 let _ = Ipv6Addr::max_value().start_from_inclusive_end(UIntPlusOne::zero());
1651 }
1652
1653 #[cfg(debug_assertions)]
1654 #[test]
1655 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1656 fn test_use_of_as_44() {
1657 let _ = Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::UInt(2));
1658 }
1659
1660 #[cfg(debug_assertions)]
1661 #[test]
1662 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1663 fn test_use_of_as_45() {
1664 let _ = (Ipv6Addr::min_value()).start_from_inclusive_end(UIntPlusOne::UInt(2));
1665 }
1666
1667 #[test]
1668 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1669 fn test_use_of_as_46() {
1670 assert_eq!(
1671 (Ipv6Addr::min_value()).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1672 Ipv6Addr::max_value()
1673 );
1674 assert_eq!(
1675 (Ipv6Addr::max_value()).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1676 Ipv6Addr::min_value()
1677 );
1678 }
1679
1680 #[test]
1681 #[should_panic(
1682 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 340282366920938463463374607431768211454)"
1683 )]
1684 fn test_use_of_as_47() {
1685 let _ = Ipv6Addr::from(2u128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1686 }
1687
1688 #[test]
1689 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1), max_len = 1)")]
1690 fn test_use_of_as_48() {
1691 let _ = Ipv6Addr::from(0u128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1692 }
1693
1694 #[test]
1697 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1112064)")]
1698 fn test_use_of_as_51() {
1699 let _ = char::max_value().inclusive_end_from_start(0);
1700 }
1701
1702 #[test]
1703 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1112064)")]
1704 fn test_use_of_as_53() {
1705 let _ = char::max_value().start_from_inclusive_end(0);
1706 }
1707
1708 #[test]
1709 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1112064)")]
1710 fn test_use_of_as_54() {
1711 let _ = char::max_value().inclusive_end_from_start(2);
1712 }
1713
1714 #[test]
1715 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1716 fn test_use_of_as_55() {
1717 let _ = (char::min_value()).start_from_inclusive_end(2);
1718 }
1719
1720 #[test]
1721 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1722 fn test_use_of_as_56() {
1723 assert_eq!(
1724 (char::min_value()).inclusive_end_from_start(1_112_064),
1725 char::max_value()
1726 );
1727 assert_eq!(
1728 (char::max_value()).start_from_inclusive_end(1_112_064),
1729 char::min_value()
1730 );
1731 }
1732
1733 #[test]
1734 #[should_panic(expected = "b must be in range 1..=max_len (b = 1112064, max_len = 3)")]
1735 fn test_use_of_as_57() {
1736 let _ = '\x02'.inclusive_end_from_start(1_112_064);
1737 }
1738
1739 #[test]
1740 #[should_panic(expected = "b must be in range 1..=max_len (b = 1112064, max_len = 1)")]
1741 fn test_use_of_as_58() {
1742 let _ = '\x00'.start_from_inclusive_end(1_112_064);
1743 }
1744
1745 #[test]
1746 #[cfg(debug_assertions)]
1747 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1748 #[should_panic(expected = "assertion failed: r.start() <= r.end()")]
1749 #[allow(clippy::reversed_empty_ranges)]
1750 fn test_safe_len() {
1751 let i = 0u128..=0u128;
1752 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(1));
1753
1754 let i = 0u128..=1u128;
1755 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(2));
1756
1757 let i = 1u128..=0u128;
1758 let _ = u128::safe_len(&i);
1760 }
1761
1762 #[test]
1763 #[cfg(debug_assertions)]
1764 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1765 #[should_panic(expected = "assertion failed: r.start() <= r.end()")]
1766 #[allow(clippy::reversed_empty_ranges)]
1767 fn safe_len2() {
1768 let i = 0u128..=0u128;
1769 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(1));
1770
1771 let i = 0u128..=1u128;
1772 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(2));
1773
1774 let i = 1u128..=0u128;
1775 let _ = u128::safe_len(&i);
1777 }
1778
1779 #[test]
1780 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1781 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294911999, max_len = 55295)")]
1782 fn safe_len_char1() {
1783 let a = '\u{D7FE}';
1784 let len = 4_294_911_999u32;
1785 let _ = a.inclusive_end_from_start(len);
1786 }
1787
1788 #[test]
1789 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1790 #[should_panic(expected = "b must be in range 1..=max_len (b = 57343, max_len = 55297)")]
1791 fn safe_len_char2() {
1792 let a = '\u{E000}';
1793 let len = 0xDFFFu32;
1794 let _ = a.start_from_inclusive_end(len);
1795 }
1796}