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