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().map_or_else(
868 || {
869 panic!("char overflow"); },
871 |next| next,
872 )
873 }
874
875 #[inline]
876 fn sub_one(self) -> Self {
877 let mut num = u32::from(self).wrapping_sub(1);
878 if num == SURROGATE_END {
879 num = SURROGATE_START - 1;
880 }
881 Self::from_u32(num).expect("sub_one: underflow or invalid char (e.g., called on '\\u{0}')")
882 }
883
884 #[inline]
885 fn assign_sub_one(&mut self) {
886 *self = self.sub_one();
887 }
888
889 #[inline]
890 fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self> {
891 range.next()
892 }
893
894 #[inline]
895 fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self> {
896 range.next_back()
897 }
898
899 #[inline]
900 fn min_value() -> Self {
901 '\u{0}'
902 }
903
904 #[inline]
905 fn max_value() -> Self {
906 '\u{10FFFF}'
907 }
908
909 #[cfg(feature = "from_slice")]
910 #[inline]
911 fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self> {
912 RangeSetBlaze::from_iter(slice.as_ref())
913 }
914
915 fn safe_len(r: &RangeInclusive<Self>) -> <Self as Integer>::SafeLen {
916 let start_num = u32::from(*r.start());
918 let end_num = u32::from(*r.end());
919 let mut len = (end_num - start_num) as <Self as Integer>::SafeLen + 1;
920 if start_num < SURROGATE_START && SURROGATE_END < end_num {
921 len -= (SURROGATE_END - SURROGATE_START + 1) as <Self as Integer>::SafeLen;
922 }
923 len
924 }
925
926 #[allow(clippy::cast_precision_loss, clippy::cast_lossless)]
927 fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64 {
928 len as f64
929 }
930
931 #[allow(clippy::cast_possible_truncation)]
932 #[allow(clippy::cast_sign_loss)]
933 fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen {
934 f as Self::SafeLen
935 }
936
937 fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self {
938 fn private_panic(a: char, b: u32) -> ! {
939 let max_len = char::safe_len(&(char::MIN..=a));
940 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
941 }
942
943 let Some(b_minus_one) = b.checked_sub(1) else {
944 private_panic(self, b);
945 };
946
947 let a = u32::from(self);
948 let Some(mut num) = a.checked_add(b_minus_one) else {
949 private_panic(self, b);
950 };
951 if a < SURROGATE_START && SURROGATE_START <= num {
952 let Some(num2) = num.checked_add(SURROGATE_END - SURROGATE_START + 1) else {
953 private_panic(self, b);
954 };
955 num = num2;
956 }
957
958 let Some(result) = Self::from_u32(num) else {
959 private_panic(self, b);
960 };
961 result
962 }
963
964 fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self {
965 fn private_panic(a: char, b: u32) -> ! {
966 let max_len = char::safe_len(&(char::MIN..=a));
967 panic!("b must be in range 1..=max_len (b = {b}, max_len = {max_len})");
968 }
969
970 let Some(b_minus_one) = b.checked_sub(1) else {
971 private_panic(self, b);
972 };
973
974 let a = u32::from(self);
975 let Some(mut num) = a.checked_sub(b_minus_one) else {
976 private_panic(self, b);
977 };
978 if num <= SURROGATE_END && SURROGATE_END < a {
979 let Some(num2) = num.checked_sub(SURROGATE_END - SURROGATE_START + 1) else {
980 private_panic(self, b);
981 };
982 num = num2;
983 }
984
985 Self::from_u32(num).expect("Real Assert: Impossible for this to fail")
986 }
987}
988
989#[cfg(test)]
990mod tests {
991 use super::*;
992 use crate::prelude::*;
993 use num_traits::{One, Zero};
994 use syntactic_for::syntactic_for;
995
996 use wasm_bindgen_test::*;
997 wasm_bindgen_test_configure!(run_in_browser);
998
999 #[test]
1000 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1001 fn coverage_integer() {
1002 let mut a = 0u8..=0u8;
1003 assert_eq!(u8::range_next_back(&mut a), Some(0));
1004 assert_eq!(u8::range_next(&mut a), None);
1005
1006 let mut b = 0i128..=0i128;
1007 assert_eq!(i128::range_next_back(&mut b), Some(0));
1008 assert_eq!(i128::range_next(&mut b), None);
1009
1010 let mut b = 0i128;
1011 i128::assign_sub_one(&mut b);
1012 assert_eq!(b, -1);
1013
1014 let f = i128::safe_len_to_f64_lossy(UIntPlusOne::MaxPlusOne);
1016 let i = i128::f64_to_safe_len_lossy(f);
1017 assert_eq!(i, UIntPlusOne::MaxPlusOne);
1018
1019 let mut b = 0u128..=0u128;
1020 assert_eq!(u128::range_next_back(&mut b), Some(0));
1021 assert_eq!(u128::range_next(&mut b), None);
1022
1023 let mut b = 1u128;
1024 u128::assign_sub_one(&mut b);
1025 assert_eq!(b, 0);
1026
1027 let f = u128::safe_len_to_f64_lossy(UIntPlusOne::MaxPlusOne);
1029 let i = u128::f64_to_safe_len_lossy(f);
1030 assert_eq!(i, UIntPlusOne::MaxPlusOne);
1031 }
1032
1033 #[test]
1034 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1035 #[should_panic(expected = "1")]
1036 #[cfg(debug_assertions)] fn test_add_len_less_one_with_max_plus_one() {
1038 let value: i128 = 100;
1039 let len = UIntPlusOne::MaxPlusOne;
1040 let _ = value.inclusive_end_from_start(len); }
1042
1043 #[test]
1044 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1045 #[should_panic(expected = "2")]
1046 #[cfg(debug_assertions)] fn test_sub_len_less_one_with_max_plus_one() {
1048 let value: i128 = 100;
1049 let len = UIntPlusOne::MaxPlusOne;
1050 let _ = value.start_from_inclusive_end(len); }
1052
1053 #[test]
1054 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1055 #[allow(clippy::cognitive_complexity, clippy::legacy_numeric_constants)]
1056 fn test_ipv4_and_ipv6_etc() {
1057 syntactic_for! { ty in [char, Ipv6Addr, u128, i128, Ipv4Addr] {
1058 $(
1059 let a = <$ty>::min_value();
1061 let b = a.checked_add_one();
1062 assert_eq!(b, Some(<$ty>::min_value().add_one()));
1063
1064 let a = <$ty>::max_value();
1066 let b = a.checked_add_one();
1067 assert_eq!(b, None);
1068
1069 let a = <$ty>::min_value();
1070 let mut b = a.add_one();
1071 assert_eq!(b, <$ty>::min_value().add_one());
1072
1073 let c = b.sub_one();
1074 assert_eq!(c, a);
1075
1076 b.assign_sub_one();
1077 assert_eq!(b, a);
1078
1079 let mut a = <$ty>::min_value()..=<$ty>::min_value();
1080 let b = <$ty>::range_next(&mut a);
1081 assert_eq!(b, Some(<$ty>::min_value()));
1082 let b = <$ty>::range_next(&mut a);
1083 assert_eq!(b, None);
1084
1085 let mut a = <$ty>::min_value()..=<$ty>::max_value();
1086 let b = <$ty>::range_next_back(&mut a);
1087 assert_eq!(b, Some(<$ty>::max_value()));
1088
1089 assert_eq!(<$ty>::min_value(), <$ty>::min_value());
1090
1091 let universe = <$ty>::min_value()..=<$ty>::max_value();
1092 let len = <$ty>::safe_len(&universe);
1093 assert_eq!(len, <$ty>::safe_len(&(<$ty>::min_value()..=<$ty>::max_value())));
1094
1095 let len_via_f64 = <$ty>::f64_to_safe_len_lossy(<$ty>::safe_len_to_f64_lossy(len));
1096 assert_eq!(len, len_via_f64);
1097
1098 let short = <$ty>::min_value()..=<$ty>::min_value();
1099 let len = <$ty>::safe_len(&short);
1100 let len_via_f64 = <$ty>::f64_to_safe_len_lossy(<$ty>::safe_len_to_f64_lossy(len));
1101 assert_eq!(len, len_via_f64);
1102
1103 let len = <$ty>::safe_len(&universe);
1104 let b = <$ty>::min_value().inclusive_end_from_start(len);
1105 assert_eq!(b, <$ty>::max_value());
1106
1107 let c = b.start_from_inclusive_end(len);
1108 assert_eq!(c, <$ty>::min_value());
1109
1110 let range = <$ty>::min_value()..=<$ty>::min_value().add_one();
1111 let len2 = <$ty>::safe_len(&range);
1112 let b = <$ty>::min_value().inclusive_end_from_start(len2);
1113 assert_eq!(b, <$ty>::min_value().add_one());
1114
1115 let b = <$ty>::max_value().start_from_inclusive_end(len2);
1116 assert_eq!(b, <$ty>::max_value().sub_one());
1117
1118 #[cfg(feature = "from_slice")]
1119 {
1120 let range_set_blaze = <$ty>::from_slice(&[<$ty>::min_value()]);
1121 assert_eq!(range_set_blaze, RangeSetBlaze::from_iter([<$ty>::min_value()]));
1122 }
1123 )*
1124 }}
1125 }
1126
1127 #[test]
1128 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1129 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1130 #[allow(clippy::legacy_numeric_constants)]
1131 fn test_i128_overflow() {
1132 let value: i128 = i128::max_value();
1133 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1134 }
1135
1136 #[test]
1137 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1138 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1139 #[allow(clippy::legacy_numeric_constants)]
1140 fn test_i128_underflow() {
1141 let value: i128 = i128::min_value();
1142 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1143 }
1144
1145 #[test]
1146 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1147 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1148 #[allow(clippy::legacy_numeric_constants)]
1149 fn test_u128_overflow() {
1150 let value: u128 = u128::max_value();
1151 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1152 }
1153
1154 #[test]
1155 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1156 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1157 #[allow(clippy::legacy_numeric_constants)]
1158 fn test_u128_underflow() {
1159 let value: u128 = u128::min_value();
1160 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1161 }
1162
1163 #[test]
1164 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1165 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1166 #[allow(clippy::legacy_numeric_constants)]
1167 fn test_ipv6_overflow() {
1168 let value: Ipv6Addr = Ipv6Addr::max_value();
1169 let _ = value.inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1170 }
1171
1172 #[test]
1173 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1174 #[should_panic(expected = "char overflow")]
1175 #[allow(clippy::legacy_numeric_constants)]
1176 fn test_char0_overflow() {
1177 let value: char = char::max_value();
1178 let _ = value.add_one();
1179 }
1180
1181 #[test]
1182 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1183 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1112064)")]
1184 #[allow(clippy::legacy_numeric_constants)]
1185 fn test_char1_overflow() {
1186 let value: char = char::max_value();
1187 let len2 = char::safe_len(&(char::min_value()..=char::min_value().add_one()));
1188 let _ = value.inclusive_end_from_start(len2);
1189 }
1190
1191 #[test]
1192 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1193 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1194 #[allow(clippy::legacy_numeric_constants)]
1195 fn test_char1_underflow() {
1196 let value: char = char::min_value();
1197 let len2 = char::safe_len(&(char::min_value()..=char::min_value().add_one()));
1198 let _ = value.start_from_inclusive_end(len2);
1199 }
1200
1201 #[test]
1202 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1203 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1204 fn test_ipv6_underflow() {
1205 let value: Ipv6Addr = Ipv6Addr::min_value();
1206 let _ = value.start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1207 }
1208
1209 #[test]
1210 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1211 #[allow(clippy::cognitive_complexity)]
1212 fn test_char() {
1213 let universe = !RangeSetBlaze::<char>::default();
1216
1217 let max_value = <char as Integer>::max_value();
1219 assert_eq!(max_value.checked_add_one(), None);
1220
1221 let mut prev = None;
1222 let mut len = <char as Integer>::SafeLen::zero();
1223 for item in <char as Integer>::min_value()..=max_value {
1224 let len2b = <char as Integer>::safe_len(&(item..=max_value));
1225 let mut expected = universe.len();
1226 expected -= len;
1227 assert_eq!(len2b, expected);
1228
1229 let item2 = max_value.start_from_inclusive_end(len2b);
1230 assert_eq!(item2, item);
1231
1232 let item3 = item2.inclusive_end_from_start(len2b);
1233 assert_eq!(item3, max_value);
1234
1235 len += <char as Integer>::SafeLen::one();
1236 let len2 = <char as Integer>::safe_len(&(<char as Integer>::min_value()..=item));
1237 assert_eq!(len, len2);
1238 assert_eq!(
1239 len2,
1240 <char as Integer>::f64_to_safe_len_lossy(<char as Integer>::safe_len_to_f64_lossy(
1241 len2
1242 ))
1243 );
1244
1245 let item2 = <char as Integer>::min_value().inclusive_end_from_start(len);
1246 assert_eq!(item2, item);
1247
1248 let item3 = item.start_from_inclusive_end(len);
1249 assert_eq!(item3, <char as Integer>::min_value());
1250
1251 if let Some(prev) = prev {
1252 assert!(universe.contains(prev));
1253 assert!(universe.contains(item));
1254 assert!(universe.is_superset(&RangeSetBlaze::from_iter([prev..=item])));
1255
1256 assert_eq!(prev.checked_add_one(), Some(item));
1257 assert_eq!(prev.add_one(), item);
1258
1259 assert_eq!(item.sub_one(), prev);
1260 let mut item2 = item;
1261 item2.assign_sub_one();
1262 assert_eq!(item2, prev);
1263 }
1264
1265 prev = Some(item);
1266 }
1267 assert_eq!(universe.len(), len);
1268
1269 }
1271
1272 #[test]
1273 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1274 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 66)")]
1275 fn test_add_len_less_one_panic_conditions1() {
1276 let character = 'A';
1278 let b = 0;
1279 _ = character.inclusive_end_from_start(b); }
1281
1282 #[test]
1283 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1284 #[should_panic(expected = "b must be in range 1..=max_len (b = 3, max_len = 1112064)")]
1285 fn test_add_len_less_one_panic_conditions2() {
1286 let character = char::MAX;
1288 let b = 3;
1289 _ = character.inclusive_end_from_start(b); }
1291
1292 #[test]
1293 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1294 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294967295, max_len = 66)")]
1295 fn test_add_len_less_one_panic_conditions3() {
1296 let character = 'A';
1298 let b = u32::MAX;
1299 _ = character.inclusive_end_from_start(b); }
1301
1302 #[test]
1303 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1304 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 66)")]
1305 fn test_sub_len_less_one_panic_conditions1() {
1306 let character = 'A';
1308 let b = 0;
1309 _ = character.start_from_inclusive_end(b); }
1311
1312 #[test]
1313 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1314 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294967295, max_len = 66)")]
1315 fn test_sub_len_less_one_panic_conditions2() {
1316 let character = 'A';
1318 let b = u32::MAX;
1319 _ = character.start_from_inclusive_end(b); }
1321
1322 #[allow(clippy::legacy_numeric_constants, clippy::cognitive_complexity)]
1323 #[test]
1324 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1325 fn test_use_of_as_00() {
1326 syntactic_for! { ty in [char, i8, i16, i32, i64, i128, isize, Ipv4Addr, Ipv6Addr, u8, u16, u32, u64, u128, usize] {
1327 $(
1328 let a = <$ty>::min_value();
1329 let b = <$ty>::max_value();
1330 let len = <$ty>::safe_len(&(a..=b));
1331 assert_eq!(<$ty>::inclusive_end_from_start(a, len), b);
1332 assert_eq!(<$ty>::start_from_inclusive_end(b, len), a);
1333 )*
1334 }}
1335 }
1336
1337 #[cfg(debug_assertions)]
1338 #[test]
1339 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1340 fn test_use_of_as_01() {
1341 let _ = 127i8.inclusive_end_from_start(0);
1342 }
1343
1344 #[cfg(not(debug_assertions))]
1345 #[test]
1346 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1347 fn test_use_of_as_02() {
1348 assert_eq!(127i8.inclusive_end_from_start(0), 126);
1349 assert_eq!(127i8.start_from_inclusive_end(0), -128);
1350 assert_eq!(127i8.inclusive_end_from_start(2), -128);
1351 assert_eq!((-126i8).start_from_inclusive_end(4), 127);
1352 }
1353
1354 #[cfg(debug_assertions)]
1355 #[test]
1356 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 256)")]
1357 fn test_use_of_as_03() {
1358 let _ = 127i8.start_from_inclusive_end(0);
1359 }
1360
1361 #[cfg(debug_assertions)]
1362 #[test]
1363 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1364 fn test_use_of_as_04() {
1365 let _ = 127i8.inclusive_end_from_start(2);
1366 }
1367
1368 #[cfg(debug_assertions)]
1369 #[test]
1370 #[should_panic(expected = "b must be in range 1..=max_len (b = 4, max_len = 3)")]
1371 fn test_use_of_as_05() {
1372 let _ = (-126i8).start_from_inclusive_end(4);
1373 }
1374
1375 #[test]
1376 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1377 fn test_use_of_as_06() {
1378 for a in (-128i8)..=127i8 {
1379 let b = i8::safe_len(&(a..=127i8));
1380 assert_eq!(a.inclusive_end_from_start(b), 127i8);
1381 let b = i8::safe_len(&(i8::MIN..=a));
1382 assert_eq!(a.start_from_inclusive_end(b), -128i8);
1383 }
1384 }
1385
1386 #[cfg(debug_assertions)]
1388 #[test]
1389 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1390 fn test_use_of_as_11() {
1391 let _ = i128::MAX.inclusive_end_from_start(UIntPlusOne::zero());
1392 }
1393
1394 #[cfg(not(debug_assertions))]
1395 #[test]
1396 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1397 fn test_use_of_as_12() {
1398 assert_eq!(
1399 i128::MAX.inclusive_end_from_start(UIntPlusOne::zero()),
1400 170141183460469231731687303715884105726
1401 );
1402 assert_eq!(
1403 i128::MAX.start_from_inclusive_end(UIntPlusOne::zero()),
1404 -170141183460469231731687303715884105728
1405 );
1406 assert_eq!(
1407 i128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2)),
1408 -170141183460469231731687303715884105728
1409 );
1410 assert_eq!(
1411 (i128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1412 170141183460469231731687303715884105727
1413 );
1414 }
1415
1416 #[cfg(debug_assertions)]
1417 #[test]
1418 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1419 fn test_use_of_as_13() {
1420 let _ = i128::MAX.start_from_inclusive_end(UIntPlusOne::zero());
1421 }
1422
1423 #[cfg(debug_assertions)]
1424 #[test]
1425 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1426 fn test_use_of_as_14() {
1427 let _ = i128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2));
1428 }
1429
1430 #[cfg(debug_assertions)]
1431 #[test]
1432 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1433 fn test_use_of_as_15() {
1434 let _ = (i128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2));
1435 }
1436
1437 #[test]
1438 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1439 fn test_use_of_as_16() {
1440 assert_eq!(
1441 (i128::MIN).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1442 i128::MAX
1443 );
1444 assert_eq!(
1445 (i128::MAX).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1446 i128::MIN
1447 );
1448 }
1449
1450 #[test]
1451 #[should_panic(
1452 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 170141183460469231731687303715884105728)"
1453 )]
1454 fn test_use_of_as_17() {
1455 let _ = (0i128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1456 }
1457
1458 #[test]
1459 #[should_panic(
1460 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 170141183460469231731687303715884105729)"
1461 )]
1462 fn test_use_of_as_18() {
1463 let _ = (0i128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1464 }
1465
1466 #[cfg(debug_assertions)]
1468 #[test]
1469 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1470 fn test_use_of_as_21() {
1471 let _ = u128::MAX.inclusive_end_from_start(UIntPlusOne::zero());
1472 }
1473
1474 #[cfg(not(debug_assertions))]
1475 #[test]
1476 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1477 fn test_use_of_as_22() {
1478 assert_eq!(
1479 u128::MAX.inclusive_end_from_start(UIntPlusOne::zero()),
1480 340282366920938463463374607431768211454
1481 );
1482 assert_eq!(u128::MAX.start_from_inclusive_end(UIntPlusOne::zero()), 0);
1483 assert_eq!(u128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2)), 0);
1484 assert_eq!(
1485 (u128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1486 340282366920938463463374607431768211455
1487 );
1488 }
1489
1490 #[cfg(debug_assertions)]
1491 #[test]
1492 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1493 fn test_use_of_as_23() {
1494 let _ = u128::MAX.start_from_inclusive_end(UIntPlusOne::zero());
1495 }
1496
1497 #[cfg(debug_assertions)]
1498 #[test]
1499 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1500 fn test_use_of_as_24() {
1501 let _ = u128::MAX.inclusive_end_from_start(UIntPlusOne::UInt(2));
1502 }
1503
1504 #[cfg(debug_assertions)]
1505 #[test]
1506 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1507 fn test_use_of_as_25() {
1508 let _ = (u128::MIN).start_from_inclusive_end(UIntPlusOne::UInt(2));
1509 }
1510
1511 #[test]
1512 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1513 fn test_use_of_as_26() {
1514 assert_eq!(
1515 (u128::MIN).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1516 u128::MAX
1517 );
1518 assert_eq!(
1519 (u128::MAX).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1520 u128::MIN
1521 );
1522 }
1523
1524 #[test]
1525 #[should_panic(
1526 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 340282366920938463463374607431768211454)"
1527 )]
1528 fn test_use_of_as_27() {
1529 let _ = (2u128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1530 }
1531
1532 #[test]
1533 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1534 fn test_use_of_as_28() {
1535 let _ = (0u128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1536 }
1537
1538 #[cfg(debug_assertions)]
1540 #[test]
1541 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1542 fn test_use_of_as_31() {
1543 let _ = Ipv4Addr::max_value().inclusive_end_from_start(0);
1544 }
1545
1546 #[cfg(not(debug_assertions))]
1547 #[test]
1548 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1549 fn test_use_of_as_32() {
1550 assert_eq!(
1551 Ipv4Addr::max_value().inclusive_end_from_start(0),
1552 Ipv4Addr::new(255, 255, 255, 254)
1553 );
1554 assert_eq!(
1555 Ipv4Addr::max_value().start_from_inclusive_end(0),
1556 Ipv4Addr::from(0)
1557 );
1558 assert_eq!(
1559 Ipv4Addr::max_value().inclusive_end_from_start(2),
1560 Ipv4Addr::from(0)
1561 );
1562 assert_eq!(
1563 Ipv4Addr::min_value().start_from_inclusive_end(2),
1564 Ipv4Addr::new(255, 255, 255, 255)
1565 );
1566 assert_eq!(
1567 Ipv4Addr::new(0, 0, 0, 2).inclusive_end_from_start(u64::MAX),
1568 Ipv4Addr::from(0)
1569 );
1570
1571 assert_eq!(
1572 Ipv4Addr::new(0, 0, 0, 0).start_from_inclusive_end(u64::MAX),
1573 Ipv4Addr::new(0, 0, 0, 2)
1574 );
1575 }
1576
1577 #[cfg(debug_assertions)]
1578 #[test]
1579 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 4294967296)")]
1580 fn test_use_of_as_33() {
1581 let _ = Ipv4Addr::max_value().start_from_inclusive_end(0);
1582 }
1583
1584 #[cfg(debug_assertions)]
1585 #[test]
1586 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1587 fn test_use_of_as_34() {
1588 let _ = Ipv4Addr::max_value().inclusive_end_from_start(2);
1589 }
1590
1591 #[cfg(debug_assertions)]
1592 #[test]
1593 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1594 fn test_use_of_as_35() {
1595 let _ = (Ipv4Addr::min_value()).start_from_inclusive_end(2);
1596 }
1597
1598 #[cfg(debug_assertions)]
1601 #[test]
1602 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1)")]
1603 fn test_use_of_as_41() {
1604 let _ = Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::zero());
1605 }
1606
1607 #[cfg(not(debug_assertions))]
1608 #[test]
1609 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1610 fn test_use_of_as_42() {
1611 assert_eq!(
1612 Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::zero()),
1613 Ipv6Addr::from(340282366920938463463374607431768211454)
1614 );
1615 assert_eq!(
1616 Ipv6Addr::max_value().start_from_inclusive_end(UIntPlusOne::zero()),
1617 Ipv6Addr::from(0)
1618 );
1619 assert_eq!(
1620 Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::UInt(2)),
1621 Ipv6Addr::from(0)
1622 );
1623 assert_eq!(
1624 (Ipv6Addr::min_value()).start_from_inclusive_end(UIntPlusOne::UInt(2)),
1625 Ipv6Addr::from(340282366920938463463374607431768211455)
1626 );
1627 }
1628
1629 #[cfg(debug_assertions)]
1630 #[test]
1631 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = (u128::MAX + 1)")]
1632 fn test_use_of_as_43() {
1633 let _ = Ipv6Addr::max_value().start_from_inclusive_end(UIntPlusOne::zero());
1634 }
1635
1636 #[cfg(debug_assertions)]
1637 #[test]
1638 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1639 fn test_use_of_as_44() {
1640 let _ = Ipv6Addr::max_value().inclusive_end_from_start(UIntPlusOne::UInt(2));
1641 }
1642
1643 #[cfg(debug_assertions)]
1644 #[test]
1645 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1646 fn test_use_of_as_45() {
1647 let _ = (Ipv6Addr::min_value()).start_from_inclusive_end(UIntPlusOne::UInt(2));
1648 }
1649
1650 #[test]
1651 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1652 fn test_use_of_as_46() {
1653 assert_eq!(
1654 (Ipv6Addr::min_value()).inclusive_end_from_start(UIntPlusOne::MaxPlusOne),
1655 Ipv6Addr::max_value()
1656 );
1657 assert_eq!(
1658 (Ipv6Addr::max_value()).start_from_inclusive_end(UIntPlusOne::MaxPlusOne),
1659 Ipv6Addr::min_value()
1660 );
1661 }
1662
1663 #[test]
1664 #[should_panic(
1665 expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 340282366920938463463374607431768211454)"
1666 )]
1667 fn test_use_of_as_47() {
1668 let _ = Ipv6Addr::from(2u128).inclusive_end_from_start(UIntPlusOne::MaxPlusOne);
1669 }
1670
1671 #[test]
1672 #[should_panic(expected = "b must be in range 1..=max_len (b = (u128::MAX + 1, max_len = 1)")]
1673 fn test_use_of_as_48() {
1674 let _ = Ipv6Addr::from(0u128).start_from_inclusive_end(UIntPlusOne::MaxPlusOne);
1675 }
1676
1677 #[test]
1680 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1112064)")]
1681 fn test_use_of_as_51() {
1682 let _ = char::max_value().inclusive_end_from_start(0);
1683 }
1684
1685 #[test]
1686 #[should_panic(expected = "b must be in range 1..=max_len (b = 0, max_len = 1112064)")]
1687 fn test_use_of_as_53() {
1688 let _ = char::max_value().start_from_inclusive_end(0);
1689 }
1690
1691 #[test]
1692 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1112064)")]
1693 fn test_use_of_as_54() {
1694 let _ = char::max_value().inclusive_end_from_start(2);
1695 }
1696
1697 #[test]
1698 #[should_panic(expected = "b must be in range 1..=max_len (b = 2, max_len = 1)")]
1699 fn test_use_of_as_55() {
1700 let _ = (char::min_value()).start_from_inclusive_end(2);
1701 }
1702
1703 #[test]
1704 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1705 fn test_use_of_as_56() {
1706 assert_eq!(
1707 (char::min_value()).inclusive_end_from_start(1_112_064),
1708 char::max_value()
1709 );
1710 assert_eq!(
1711 (char::max_value()).start_from_inclusive_end(1_112_064),
1712 char::min_value()
1713 );
1714 }
1715
1716 #[test]
1717 #[should_panic(expected = "b must be in range 1..=max_len (b = 1112064, max_len = 3)")]
1718 fn test_use_of_as_57() {
1719 let _ = '\x02'.inclusive_end_from_start(1_112_064);
1720 }
1721
1722 #[test]
1723 #[should_panic(expected = "b must be in range 1..=max_len (b = 1112064, max_len = 1)")]
1724 fn test_use_of_as_58() {
1725 let _ = '\x00'.start_from_inclusive_end(1_112_064);
1726 }
1727
1728 #[test]
1729 #[cfg(debug_assertions)]
1730 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1731 #[should_panic(expected = "assertion failed: r.start() <= r.end()")]
1732 #[allow(clippy::reversed_empty_ranges)]
1733 fn test_safe_len() {
1734 let i = 0u128..=0u128;
1735 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(1));
1736
1737 let i = 0u128..=1u128;
1738 assert_eq!(u128::safe_len(&i), UIntPlusOne::UInt(2));
1739
1740 let i = 1u128..=0u128;
1741 let _ = u128::safe_len(&i);
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 safe_len2() {
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_attr(target_arch = "wasm32", wasm_bindgen_test)]
1764 #[should_panic(expected = "b must be in range 1..=max_len (b = 4294911999, max_len = 55295)")]
1765 fn safe_len_char1() {
1766 let a = '\u{D7FE}';
1767 let len = 4_294_911_999u32;
1768 let _ = a.inclusive_end_from_start(len);
1769 }
1770
1771 #[test]
1772 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1773 #[should_panic(expected = "b must be in range 1..=max_len (b = 57343, max_len = 55297)")]
1774 fn safe_len_char2() {
1775 let a = '\u{E000}';
1776 let len = 0xDFFFu32;
1777 let _ = a.start_from_inclusive_end(len);
1778 }
1779}