1c0nst::c0nst! {
27 pub c0nst trait ConstZero {
32 fn zero() -> Self;
34 fn is_zero(&self) -> bool;
36 fn set_zero(&mut self);
38 }
39
40 pub c0nst trait ConstOne {
42 fn one() -> Self;
44 fn is_one(&self) -> bool;
46 fn set_one(&mut self);
48 }
49
50 pub c0nst trait ConstBounded {
52 fn min_value() -> Self;
54 fn max_value() -> Self;
56 }
57
58 pub c0nst trait ConstOverflowingAdd: Sized + [c0nst] core::ops::Add<Output = Self> {
60 fn overflowing_add(&self, v: &Self) -> (Self, bool);
63 }
64
65 pub c0nst trait ConstOverflowingSub: Sized + [c0nst] core::ops::Sub<Output = Self> {
67 fn overflowing_sub(&self, v: &Self) -> (Self, bool);
70 }
71
72 pub c0nst trait ConstWrappingAdd: Sized + [c0nst] ConstOverflowingAdd {
74 fn wrapping_add(&self, v: &Self) -> Self;
76 }
77
78 pub c0nst trait ConstWrappingSub: Sized + [c0nst] ConstOverflowingSub {
80 fn wrapping_sub(&self, v: &Self) -> Self;
82 }
83
84 pub c0nst trait ConstCheckedAdd: Sized + [c0nst] ConstOverflowingAdd {
86 fn checked_add(&self, v: &Self) -> Option<Self>;
88 }
89
90 pub c0nst trait ConstCheckedSub: Sized + [c0nst] ConstOverflowingSub {
92 fn checked_sub(&self, v: &Self) -> Option<Self>;
94 }
95
96 pub c0nst trait ConstSaturatingAdd: Sized + [c0nst] ConstOverflowingAdd + [c0nst] ConstBounded {
98 fn saturating_add(&self, v: &Self) -> Self;
100 }
101
102 pub c0nst trait ConstSaturatingSub: Sized + [c0nst] ConstOverflowingSub + [c0nst] ConstZero {
104 fn saturating_sub(&self, v: &Self) -> Self;
106 }
107
108 pub c0nst trait ConstOverflowingMul: Sized + [c0nst] core::ops::Mul<Output = Self> {
110 fn overflowing_mul(&self, v: &Self) -> (Self, bool);
113 }
114
115 pub c0nst trait ConstWrappingMul: Sized + [c0nst] ConstOverflowingMul {
117 fn wrapping_mul(&self, v: &Self) -> Self;
119 }
120
121 pub c0nst trait ConstCheckedMul: Sized + [c0nst] ConstOverflowingMul {
123 fn checked_mul(&self, v: &Self) -> Option<Self>;
125 }
126
127 pub c0nst trait ConstSaturatingMul: Sized + [c0nst] ConstOverflowingMul + [c0nst] ConstBounded {
129 fn saturating_mul(&self, v: &Self) -> Self;
131 }
132
133 pub c0nst trait ConstCheckedDiv: Sized + [c0nst] core::ops::Div<Output = Self> + [c0nst] ConstZero {
135 fn checked_div(&self, v: &Self) -> Option<Self>;
137 }
138
139 pub c0nst trait ConstCheckedRem: Sized + [c0nst] core::ops::Rem<Output = Self> + [c0nst] ConstZero {
141 fn checked_rem(&self, v: &Self) -> Option<Self>;
143 }
144
145 pub c0nst trait ConstEuclid: Sized + [c0nst] core::ops::Div<Output = Self> + [c0nst] core::ops::Rem<Output = Self> {
147 fn div_euclid(&self, v: &Self) -> Self;
149 fn rem_euclid(&self, v: &Self) -> Self;
151 }
152
153 pub c0nst trait ConstCheckedEuclid: Sized + [c0nst] ConstEuclid + [c0nst] ConstZero {
155 fn checked_div_euclid(&self, v: &Self) -> Option<Self>;
157 fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
159 }
160
161 pub c0nst trait ConstOverflowingShl: Sized + [c0nst] core::ops::Shl<u32, Output = Self> {
163 fn overflowing_shl(&self, rhs: u32) -> (Self, bool);
166 }
167
168 pub c0nst trait ConstOverflowingShr: Sized + [c0nst] core::ops::Shr<u32, Output = Self> {
170 fn overflowing_shr(&self, rhs: u32) -> (Self, bool);
173 }
174
175 pub c0nst trait ConstWrappingShl: Sized + [c0nst] ConstOverflowingShl {
177 fn wrapping_shl(&self, rhs: u32) -> Self;
179 }
180
181 pub c0nst trait ConstWrappingShr: Sized + [c0nst] ConstOverflowingShr {
183 fn wrapping_shr(&self, rhs: u32) -> Self;
185 }
186
187 pub c0nst trait ConstCheckedShl: Sized + [c0nst] ConstOverflowingShl {
189 fn checked_shl(&self, rhs: u32) -> Option<Self>;
191 }
192
193 pub c0nst trait ConstCheckedShr: Sized + [c0nst] ConstOverflowingShr {
195 fn checked_shr(&self, rhs: u32) -> Option<Self>;
197 }
198
199 pub c0nst trait ConstToBytes {
201 type Bytes: Copy + [c0nst] AsRef<[u8]> + [c0nst] AsMut<[u8]>;
203 fn to_le_bytes(&self) -> Self::Bytes;
205 fn to_be_bytes(&self) -> Self::Bytes;
207 }
208
209 pub c0nst trait ConstFromBytes: Sized {
211 type Bytes: Copy + [c0nst] AsRef<[u8]> + [c0nst] AsMut<[u8]>;
213 fn from_le_bytes(bytes: &Self::Bytes) -> Self;
215 fn from_be_bytes(bytes: &Self::Bytes) -> Self;
217 }
218
219 pub c0nst trait ConstPowerOfTwo: Sized + [c0nst] ConstZero + [c0nst] ConstOne {
231 fn is_power_of_two(&self) -> bool;
235
236 fn next_power_of_two(self) -> Self;
242
243 fn checked_next_power_of_two(self) -> Option<Self>;
247 }
248
249 pub c0nst trait ConstAbsDiff: Sized + [c0nst] core::cmp::Ord + [c0nst] core::ops::Sub<Output = Self> {
261 fn abs_diff(self, other: Self) -> Self;
263 }
264
265 pub c0nst trait ConstCheckedPow: Sized + [c0nst] ConstOne + [c0nst] ConstCheckedMul {
269 fn checked_pow(self, exp: u32) -> Option<Self>;
272 }
273
274 pub c0nst trait ConstIlog: Sized + [c0nst] ConstZero + [c0nst] ConstOne + [c0nst] core::cmp::Ord + [c0nst] core::ops::Div<Output = Self> {
281 fn ilog2(self) -> u32;
287
288 fn ilog10(self) -> u32;
294
295 fn ilog(self, base: Self) -> u32;
302
303 fn checked_ilog2(self) -> Option<u32>;
307
308 fn checked_ilog10(self) -> Option<u32>;
312
313 fn checked_ilog(self, base: Self) -> Option<u32>;
318 }
319
320 pub c0nst trait ConstMultiple: Sized + [c0nst] ConstZero + [c0nst] core::ops::Rem<Output = Self> + [c0nst] core::ops::Add<Output = Self> + [c0nst] core::ops::Sub<Output = Self> + [c0nst] core::cmp::Eq {
326 fn is_multiple_of(&self, rhs: &Self) -> bool;
330
331 fn next_multiple_of(self, rhs: Self) -> Self;
338
339 fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
344 }
345
346 pub c0nst trait ConstDivCeil: Sized + [c0nst] ConstZero + [c0nst] ConstOne + [c0nst] ConstCheckedAdd {
350 fn div_ceil(self, rhs: Self) -> Self;
356
357 fn checked_div_ceil(self, rhs: Self) -> Option<Self>;
361 }
362
363 pub c0nst trait ConstIsqrt: Sized + [c0nst] ConstZero {
367 fn isqrt(self) -> Self;
369
370 fn checked_isqrt(self) -> Option<Self>;
376 }
377
378 pub c0nst trait ConstCarryingAdd: Sized {
383 fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
388 }
389
390 pub c0nst trait ConstBorrowingSub: Sized {
395 fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);
400 }
401
402 pub c0nst trait ConstWideningMul: Sized {
406 fn widening_mul(self, rhs: Self) -> (Self, Self);
410 }
411
412 pub c0nst trait ConstCarryingMul: Sized {
416 fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);
421
422 fn carrying_mul_add(self, rhs: Self, addend: Self, carry: Self) -> (Self, Self);
427 }
428
429 pub c0nst trait ConstMidpoint: Sized {
434 fn midpoint(self, rhs: Self) -> Self;
438 }
439
440 pub c0nst trait ConstUnboundedShift: Sized {
447 fn unbounded_shl(self, rhs: u32) -> Self;
449
450 fn unbounded_shr(self, rhs: u32) -> Self;
452 }
453
454 pub c0nst trait ConstBitPrimInt:
465 [c0nst] core::ops::BitAnd<Output = Self> +
466 [c0nst] core::ops::BitOr<Output = Self> +
467 [c0nst] core::ops::BitXor<Output = Self> +
468 [c0nst] core::ops::Not<Output = Self> +
469 [c0nst] core::ops::Shl<usize, Output = Self> +
470 [c0nst] core::ops::Shr<usize, Output = Self> +
471 [c0nst] core::ops::BitAndAssign +
472 [c0nst] core::ops::BitOrAssign +
473 [c0nst] core::ops::BitXorAssign +
474 [c0nst] core::ops::ShlAssign<usize> +
475 [c0nst] core::ops::ShrAssign<usize> +
476 [c0nst] ConstOne +
477 [c0nst] ConstZero +
478 Sized + Copy {
479
480 fn swap_bytes(self) -> Self;
481 fn leading_zeros(self) -> u32;
482 fn trailing_zeros(self) -> u32;
483 fn count_zeros(self) -> u32;
484 fn count_ones(self) -> u32;
485 fn leading_ones(self) -> u32 {
486 (!self).leading_zeros()
487 }
488 fn trailing_ones(self) -> u32 {
489 (!self).trailing_zeros()
490 }
491 fn rotate_left(self, n: u32) -> Self;
492 fn rotate_right(self, n: u32) -> Self;
493 fn unsigned_shl(self, n: u32) -> Self;
494 fn unsigned_shr(self, n: u32) -> Self;
495 fn signed_shl(self, n: u32) -> Self {
496 self.unsigned_shl(n)
497 }
498 fn signed_shr(self, n: u32) -> Self {
499 self.unsigned_shr(n)
500 }
501 fn reverse_bits(self) -> Self;
502 fn from_be(x: Self) -> Self;
503 fn from_le(x: Self) -> Self;
504 fn to_be(self) -> Self;
505 fn to_le(self) -> Self;
506 }
507
508 pub c0nst trait ConstPrimInt:
516 [c0nst] ConstBitPrimInt +
517 [c0nst] core::ops::Add<Output = Self> +
518 [c0nst] core::ops::Sub<Output = Self> +
519 [c0nst] core::ops::Mul<Output = Self> +
520 [c0nst] core::ops::Div<Output = Self> +
521 [c0nst] core::ops::AddAssign +
522 [c0nst] core::ops::SubAssign +
523 [c0nst] core::cmp::PartialEq +
524 [c0nst] core::cmp::Eq +
525 [c0nst] core::cmp::PartialOrd +
526 [c0nst] core::cmp::Ord +
527 [c0nst] core::convert::From<u8> +
528 [c0nst] core::default::Default +
529 [c0nst] ConstBounded {
530
531 fn pow(self, exp: u32) -> Self;
532 }
533}
534
535macro_rules! const_zero_impl {
536 ($t:ty, $v:expr) => {
537 c0nst::c0nst! {
538 impl c0nst ConstZero for $t {
539 fn zero() -> Self { $v }
540 fn is_zero(&self) -> bool { *self == $v }
541 fn set_zero(&mut self) { *self = $v }
542 }
543 }
544 };
545}
546
547macro_rules! const_one_impl {
548 ($t:ty, $v:expr) => {
549 c0nst::c0nst! {
550 impl c0nst ConstOne for $t {
551 fn one() -> Self { $v }
552 fn is_one(&self) -> bool { *self == $v }
553 fn set_one(&mut self) { *self = $v }
554 }
555 }
556 };
557}
558
559macro_rules! const_bounded_impl {
560 ($t:ty, $min:expr, $max:expr) => {
561 c0nst::c0nst! {
562 impl c0nst ConstBounded for $t {
563 fn min_value() -> Self { $min }
564 fn max_value() -> Self { $max }
565 }
566 }
567 };
568}
569
570macro_rules! const_bit_prim_int_impl {
571 ($t:ty) => {
572 c0nst::c0nst! {
573 impl c0nst ConstBitPrimInt for $t {
574 fn leading_zeros(self) -> u32 { self.leading_zeros() }
575 fn trailing_zeros(self) -> u32 { self.trailing_zeros() }
576 fn count_zeros(self) -> u32 { self.count_zeros() }
577 fn count_ones(self) -> u32 { self.count_ones() }
578 fn swap_bytes(self) -> Self { self.swap_bytes() }
579 fn rotate_left(self, n: u32) -> Self { self.rotate_left(n) }
580 fn rotate_right(self, n: u32) -> Self { self.rotate_right(n) }
581 fn unsigned_shl(self, n: u32) -> Self { self << n }
582 fn unsigned_shr(self, n: u32) -> Self { self >> n }
583 fn reverse_bits(self) -> Self { self.reverse_bits() }
584 fn from_be(x: Self) -> Self { <$t>::from_be(x) }
585 fn from_le(x: Self) -> Self { <$t>::from_le(x) }
586 fn to_be(self) -> Self { self.to_be() }
587 fn to_le(self) -> Self { self.to_le() }
588 }
589 }
590 };
591}
592
593macro_rules! const_prim_int_impl {
594 ($t:ty) => {
595 c0nst::c0nst! {
596 impl c0nst ConstPrimInt for $t {
597 fn pow(self, exp: u32) -> Self { self.pow(exp) }
598 }
599 }
600 };
601}
602
603macro_rules! const_overflowing_add_impl {
604 ($t:ty) => {
605 c0nst::c0nst! {
606 impl c0nst ConstOverflowingAdd for $t {
607 fn overflowing_add(&self, v: &Self) -> (Self, bool) {
608 (*self).overflowing_add(*v)
609 }
610 }
611 }
612 };
613}
614
615macro_rules! const_overflowing_sub_impl {
616 ($t:ty) => {
617 c0nst::c0nst! {
618 impl c0nst ConstOverflowingSub for $t {
619 fn overflowing_sub(&self, v: &Self) -> (Self, bool) {
620 (*self).overflowing_sub(*v)
621 }
622 }
623 }
624 };
625}
626
627const_zero_impl!(u8, 0);
628const_zero_impl!(u16, 0);
629const_zero_impl!(u32, 0);
630const_zero_impl!(u64, 0);
631const_zero_impl!(u128, 0);
632
633const_one_impl!(u8, 1);
634const_one_impl!(u16, 1);
635const_one_impl!(u32, 1);
636const_one_impl!(u64, 1);
637const_one_impl!(u128, 1);
638
639const_bounded_impl!(u8, u8::MIN, u8::MAX);
640const_bounded_impl!(u16, u16::MIN, u16::MAX);
641const_bounded_impl!(u32, u32::MIN, u32::MAX);
642const_bounded_impl!(u64, u64::MIN, u64::MAX);
643const_bounded_impl!(u128, u128::MIN, u128::MAX);
644
645const_overflowing_add_impl!(u8);
646const_overflowing_add_impl!(u16);
647const_overflowing_add_impl!(u32);
648const_overflowing_add_impl!(u64);
649const_overflowing_add_impl!(u128);
650
651const_overflowing_sub_impl!(u8);
652const_overflowing_sub_impl!(u16);
653const_overflowing_sub_impl!(u32);
654const_overflowing_sub_impl!(u64);
655const_overflowing_sub_impl!(u128);
656
657macro_rules! const_wrapping_add_impl {
658 ($t:ty) => {
659 c0nst::c0nst! {
660 impl c0nst ConstWrappingAdd for $t {
661 fn wrapping_add(&self, v: &Self) -> Self {
662 self.overflowing_add(v).0
663 }
664 }
665 }
666 };
667}
668
669macro_rules! const_wrapping_sub_impl {
670 ($t:ty) => {
671 c0nst::c0nst! {
672 impl c0nst ConstWrappingSub for $t {
673 fn wrapping_sub(&self, v: &Self) -> Self {
674 self.overflowing_sub(v).0
675 }
676 }
677 }
678 };
679}
680
681macro_rules! const_checked_add_impl {
682 ($t:ty) => {
683 c0nst::c0nst! {
684 impl c0nst ConstCheckedAdd for $t {
685 fn checked_add(&self, v: &Self) -> Option<Self> {
686 let (res, overflow) = self.overflowing_add(v);
687 if overflow { None } else { Some(res) }
688 }
689 }
690 }
691 };
692}
693
694macro_rules! const_checked_sub_impl {
695 ($t:ty) => {
696 c0nst::c0nst! {
697 impl c0nst ConstCheckedSub for $t {
698 fn checked_sub(&self, v: &Self) -> Option<Self> {
699 let (res, overflow) = self.overflowing_sub(v);
700 if overflow { None } else { Some(res) }
701 }
702 }
703 }
704 };
705}
706
707const_wrapping_add_impl!(u8);
708const_wrapping_add_impl!(u16);
709const_wrapping_add_impl!(u32);
710const_wrapping_add_impl!(u64);
711const_wrapping_add_impl!(u128);
712
713const_wrapping_sub_impl!(u8);
714const_wrapping_sub_impl!(u16);
715const_wrapping_sub_impl!(u32);
716const_wrapping_sub_impl!(u64);
717const_wrapping_sub_impl!(u128);
718
719const_checked_add_impl!(u8);
720const_checked_add_impl!(u16);
721const_checked_add_impl!(u32);
722const_checked_add_impl!(u64);
723const_checked_add_impl!(u128);
724
725const_checked_sub_impl!(u8);
726const_checked_sub_impl!(u16);
727const_checked_sub_impl!(u32);
728const_checked_sub_impl!(u64);
729const_checked_sub_impl!(u128);
730
731macro_rules! const_saturating_add_impl {
732 ($t:ty) => {
733 c0nst::c0nst! {
734 impl c0nst ConstSaturatingAdd for $t {
735 fn saturating_add(&self, v: &Self) -> Self {
736 let (res, overflow) = self.overflowing_add(v);
737 if overflow { Self::max_value() } else { res }
738 }
739 }
740 }
741 };
742}
743
744macro_rules! const_saturating_sub_impl {
745 ($t:ty) => {
746 c0nst::c0nst! {
747 impl c0nst ConstSaturatingSub for $t {
748 fn saturating_sub(&self, v: &Self) -> Self {
749 let (res, overflow) = self.overflowing_sub(v);
750 if overflow { Self::zero() } else { res }
751 }
752 }
753 }
754 };
755}
756
757const_saturating_add_impl!(u8);
758const_saturating_add_impl!(u16);
759const_saturating_add_impl!(u32);
760const_saturating_add_impl!(u64);
761const_saturating_add_impl!(u128);
762
763const_saturating_sub_impl!(u8);
764const_saturating_sub_impl!(u16);
765const_saturating_sub_impl!(u32);
766const_saturating_sub_impl!(u64);
767const_saturating_sub_impl!(u128);
768
769macro_rules! const_overflowing_mul_impl {
770 ($t:ty) => {
771 c0nst::c0nst! {
772 impl c0nst ConstOverflowingMul for $t {
773 fn overflowing_mul(&self, v: &Self) -> (Self, bool) {
774 (*self).overflowing_mul(*v)
775 }
776 }
777 }
778 };
779}
780
781macro_rules! const_wrapping_mul_impl {
782 ($t:ty) => {
783 c0nst::c0nst! {
784 impl c0nst ConstWrappingMul for $t {
785 fn wrapping_mul(&self, v: &Self) -> Self {
786 self.overflowing_mul(v).0
787 }
788 }
789 }
790 };
791}
792
793macro_rules! const_checked_mul_impl {
794 ($t:ty) => {
795 c0nst::c0nst! {
796 impl c0nst ConstCheckedMul for $t {
797 fn checked_mul(&self, v: &Self) -> Option<Self> {
798 let (res, overflow) = self.overflowing_mul(v);
799 if overflow { None } else { Some(res) }
800 }
801 }
802 }
803 };
804}
805
806macro_rules! const_saturating_mul_impl {
807 ($t:ty) => {
808 c0nst::c0nst! {
809 impl c0nst ConstSaturatingMul for $t {
810 fn saturating_mul(&self, v: &Self) -> Self {
811 let (res, overflow) = self.overflowing_mul(v);
812 if overflow { Self::max_value() } else { res }
813 }
814 }
815 }
816 };
817}
818
819const_overflowing_mul_impl!(u8);
820const_overflowing_mul_impl!(u16);
821const_overflowing_mul_impl!(u32);
822const_overflowing_mul_impl!(u64);
823const_overflowing_mul_impl!(u128);
824
825const_wrapping_mul_impl!(u8);
826const_wrapping_mul_impl!(u16);
827const_wrapping_mul_impl!(u32);
828const_wrapping_mul_impl!(u64);
829const_wrapping_mul_impl!(u128);
830
831const_checked_mul_impl!(u8);
832const_checked_mul_impl!(u16);
833const_checked_mul_impl!(u32);
834const_checked_mul_impl!(u64);
835const_checked_mul_impl!(u128);
836
837const_saturating_mul_impl!(u8);
838const_saturating_mul_impl!(u16);
839const_saturating_mul_impl!(u32);
840const_saturating_mul_impl!(u64);
841const_saturating_mul_impl!(u128);
842
843macro_rules! const_checked_div_impl {
844 ($t:ty) => {
845 c0nst::c0nst! {
846 impl c0nst ConstCheckedDiv for $t {
847 fn checked_div(&self, v: &Self) -> Option<Self> {
848 if v.is_zero() { None } else { Some(*self / *v) }
849 }
850 }
851 }
852 };
853}
854
855macro_rules! const_checked_rem_impl {
856 ($t:ty) => {
857 c0nst::c0nst! {
858 impl c0nst ConstCheckedRem for $t {
859 fn checked_rem(&self, v: &Self) -> Option<Self> {
860 if v.is_zero() { None } else { Some(*self % *v) }
861 }
862 }
863 }
864 };
865}
866
867const_checked_div_impl!(u8);
868const_checked_div_impl!(u16);
869const_checked_div_impl!(u32);
870const_checked_div_impl!(u64);
871const_checked_div_impl!(u128);
872
873const_checked_rem_impl!(u8);
874const_checked_rem_impl!(u16);
875const_checked_rem_impl!(u32);
876const_checked_rem_impl!(u64);
877const_checked_rem_impl!(u128);
878
879macro_rules! const_euclid_impl {
880 ($t:ty) => {
881 c0nst::c0nst! {
882 impl c0nst ConstEuclid for $t {
883 fn div_euclid(&self, v: &Self) -> Self {
884 *self / *v
886 }
887 fn rem_euclid(&self, v: &Self) -> Self {
888 *self % *v
890 }
891 }
892 }
893 };
894}
895
896macro_rules! const_checked_euclid_impl {
897 ($t:ty) => {
898 c0nst::c0nst! {
899 impl c0nst ConstCheckedEuclid for $t {
900 fn checked_div_euclid(&self, v: &Self) -> Option<Self> {
901 if v.is_zero() { None } else { Some(*self / *v) }
902 }
903 fn checked_rem_euclid(&self, v: &Self) -> Option<Self> {
904 if v.is_zero() { None } else { Some(*self % *v) }
905 }
906 }
907 }
908 };
909}
910
911const_euclid_impl!(u8);
912const_euclid_impl!(u16);
913const_euclid_impl!(u32);
914const_euclid_impl!(u64);
915const_euclid_impl!(u128);
916
917const_checked_euclid_impl!(u8);
918const_checked_euclid_impl!(u16);
919const_checked_euclid_impl!(u32);
920const_checked_euclid_impl!(u64);
921const_checked_euclid_impl!(u128);
922
923macro_rules! const_overflowing_shl_impl {
924 ($t:ty) => {
925 c0nst::c0nst! {
926 impl c0nst ConstOverflowingShl for $t {
927 fn overflowing_shl(&self, rhs: u32) -> (Self, bool) {
928 (*self).overflowing_shl(rhs)
929 }
930 }
931 }
932 };
933}
934
935macro_rules! const_overflowing_shr_impl {
936 ($t:ty) => {
937 c0nst::c0nst! {
938 impl c0nst ConstOverflowingShr for $t {
939 fn overflowing_shr(&self, rhs: u32) -> (Self, bool) {
940 (*self).overflowing_shr(rhs)
941 }
942 }
943 }
944 };
945}
946
947macro_rules! const_wrapping_shl_impl {
948 ($t:ty) => {
949 c0nst::c0nst! {
950 impl c0nst ConstWrappingShl for $t {
951 fn wrapping_shl(&self, rhs: u32) -> Self {
952 ConstOverflowingShl::overflowing_shl(self, rhs).0
953 }
954 }
955 }
956 };
957}
958
959macro_rules! const_wrapping_shr_impl {
960 ($t:ty) => {
961 c0nst::c0nst! {
962 impl c0nst ConstWrappingShr for $t {
963 fn wrapping_shr(&self, rhs: u32) -> Self {
964 ConstOverflowingShr::overflowing_shr(self, rhs).0
965 }
966 }
967 }
968 };
969}
970
971macro_rules! const_checked_shl_impl {
972 ($t:ty) => {
973 c0nst::c0nst! {
974 impl c0nst ConstCheckedShl for $t {
975 fn checked_shl(&self, rhs: u32) -> Option<Self> {
976 let (res, overflow) = ConstOverflowingShl::overflowing_shl(self, rhs);
977 if overflow { None } else { Some(res) }
978 }
979 }
980 }
981 };
982}
983
984macro_rules! const_checked_shr_impl {
985 ($t:ty) => {
986 c0nst::c0nst! {
987 impl c0nst ConstCheckedShr for $t {
988 fn checked_shr(&self, rhs: u32) -> Option<Self> {
989 let (res, overflow) = ConstOverflowingShr::overflowing_shr(self, rhs);
990 if overflow { None } else { Some(res) }
991 }
992 }
993 }
994 };
995}
996
997const_overflowing_shl_impl!(u8);
998const_overflowing_shl_impl!(u16);
999const_overflowing_shl_impl!(u32);
1000const_overflowing_shl_impl!(u64);
1001const_overflowing_shl_impl!(u128);
1002
1003const_overflowing_shr_impl!(u8);
1004const_overflowing_shr_impl!(u16);
1005const_overflowing_shr_impl!(u32);
1006const_overflowing_shr_impl!(u64);
1007const_overflowing_shr_impl!(u128);
1008
1009const_wrapping_shl_impl!(u8);
1010const_wrapping_shl_impl!(u16);
1011const_wrapping_shl_impl!(u32);
1012const_wrapping_shl_impl!(u64);
1013const_wrapping_shl_impl!(u128);
1014
1015const_wrapping_shr_impl!(u8);
1016const_wrapping_shr_impl!(u16);
1017const_wrapping_shr_impl!(u32);
1018const_wrapping_shr_impl!(u64);
1019const_wrapping_shr_impl!(u128);
1020
1021const_checked_shl_impl!(u8);
1022const_checked_shl_impl!(u16);
1023const_checked_shl_impl!(u32);
1024const_checked_shl_impl!(u64);
1025const_checked_shl_impl!(u128);
1026
1027const_checked_shr_impl!(u8);
1028const_checked_shr_impl!(u16);
1029const_checked_shr_impl!(u32);
1030const_checked_shr_impl!(u64);
1031const_checked_shr_impl!(u128);
1032
1033macro_rules! const_to_bytes_impl {
1034 ($t:ty, $n:expr) => {
1035 c0nst::c0nst! {
1036 impl c0nst ConstToBytes for $t {
1037 type Bytes = [u8; $n];
1038 fn to_le_bytes(&self) -> [u8; $n] { (*self).to_le_bytes() }
1039 fn to_be_bytes(&self) -> [u8; $n] { (*self).to_be_bytes() }
1040 }
1041 }
1042 };
1043}
1044
1045const_to_bytes_impl!(u8, 1);
1046const_to_bytes_impl!(u16, 2);
1047const_to_bytes_impl!(u32, 4);
1048const_to_bytes_impl!(u64, 8);
1049const_to_bytes_impl!(u128, 16);
1050
1051macro_rules! const_from_bytes_impl {
1052 ($t:ty, $n:expr) => {
1053 c0nst::c0nst! {
1054 impl c0nst ConstFromBytes for $t {
1055 type Bytes = [u8; $n];
1056 fn from_le_bytes(bytes: &[u8; $n]) -> Self { <$t>::from_le_bytes(*bytes) }
1057 fn from_be_bytes(bytes: &[u8; $n]) -> Self { <$t>::from_be_bytes(*bytes) }
1058 }
1059 }
1060 };
1061}
1062
1063const_from_bytes_impl!(u8, 1);
1064const_from_bytes_impl!(u16, 2);
1065const_from_bytes_impl!(u32, 4);
1066const_from_bytes_impl!(u64, 8);
1067const_from_bytes_impl!(u128, 16);
1068
1069macro_rules! const_power_of_two_impl {
1070 ($t:ty) => {
1071 c0nst::c0nst! {
1072 impl c0nst ConstPowerOfTwo for $t {
1073 fn is_power_of_two(&self) -> bool {
1074 (*self).is_power_of_two()
1075 }
1076 fn next_power_of_two(self) -> Self {
1077 self.next_power_of_two()
1078 }
1079 fn checked_next_power_of_two(self) -> Option<Self> {
1080 self.checked_next_power_of_two()
1081 }
1082 }
1083 }
1084 };
1085}
1086
1087const_power_of_two_impl!(u8);
1088const_power_of_two_impl!(u16);
1089const_power_of_two_impl!(u32);
1090const_power_of_two_impl!(u64);
1091const_power_of_two_impl!(u128);
1092
1093macro_rules! const_abs_diff_impl {
1094 ($t:ty) => {
1095 c0nst::c0nst! {
1096 impl c0nst ConstAbsDiff for $t {
1097 fn abs_diff(self, other: Self) -> Self {
1098 <$t>::abs_diff(self, other)
1099 }
1100 }
1101 }
1102 };
1103}
1104
1105const_abs_diff_impl!(u8);
1106const_abs_diff_impl!(u16);
1107const_abs_diff_impl!(u32);
1108const_abs_diff_impl!(u64);
1109const_abs_diff_impl!(u128);
1110
1111macro_rules! const_checked_pow_impl {
1112 ($t:ty) => {
1113 c0nst::c0nst! {
1114 impl c0nst ConstCheckedPow for $t {
1115 fn checked_pow(self, exp: u32) -> Option<Self> {
1116 self.checked_pow(exp)
1117 }
1118 }
1119 }
1120 };
1121}
1122
1123const_checked_pow_impl!(u8);
1124const_checked_pow_impl!(u16);
1125const_checked_pow_impl!(u32);
1126const_checked_pow_impl!(u64);
1127const_checked_pow_impl!(u128);
1128
1129macro_rules! const_ilog_impl {
1130 ($t:ty) => {
1131 c0nst::c0nst! {
1132 impl c0nst ConstIlog for $t {
1133 fn ilog2(self) -> u32 {
1134 self.ilog2()
1135 }
1136 fn ilog10(self) -> u32 {
1137 self.ilog10()
1138 }
1139 fn ilog(self, base: Self) -> u32 {
1140 self.ilog(base)
1141 }
1142 fn checked_ilog2(self) -> Option<u32> {
1143 self.checked_ilog2()
1144 }
1145 fn checked_ilog10(self) -> Option<u32> {
1146 self.checked_ilog10()
1147 }
1148 fn checked_ilog(self, base: Self) -> Option<u32> {
1149 self.checked_ilog(base)
1150 }
1151 }
1152 }
1153 };
1154}
1155
1156const_ilog_impl!(u8);
1157const_ilog_impl!(u16);
1158const_ilog_impl!(u32);
1159const_ilog_impl!(u64);
1160const_ilog_impl!(u128);
1161
1162#[cfg(not(feature = "1_87"))]
1164macro_rules! const_multiple_impl {
1165 ($t:ty) => {
1166 c0nst::c0nst! {
1167 impl c0nst ConstMultiple for $t {
1168 fn is_multiple_of(&self, rhs: &Self) -> bool {
1169 if rhs.is_zero() {
1170 false
1171 } else {
1172 *self % *rhs == 0
1173 }
1174 }
1175 fn next_multiple_of(self, rhs: Self) -> Self {
1176 self.next_multiple_of(rhs)
1177 }
1178 fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
1179 self.checked_next_multiple_of(rhs)
1180 }
1181 }
1182 }
1183 };
1184}
1185
1186#[cfg(feature = "1_87")]
1187macro_rules! const_multiple_impl {
1188 ($t:ty) => {
1189 c0nst::c0nst! {
1190 impl c0nst ConstMultiple for $t {
1191 fn is_multiple_of(&self, rhs: &Self) -> bool {
1192 <$t>::is_multiple_of(*self, *rhs)
1193 }
1194 fn next_multiple_of(self, rhs: Self) -> Self {
1195 self.next_multiple_of(rhs)
1196 }
1197 fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
1198 self.checked_next_multiple_of(rhs)
1199 }
1200 }
1201 }
1202 };
1203}
1204
1205const_multiple_impl!(u8);
1206const_multiple_impl!(u16);
1207const_multiple_impl!(u32);
1208const_multiple_impl!(u64);
1209const_multiple_impl!(u128);
1210
1211macro_rules! const_div_ceil_impl {
1212 ($t:ty) => {
1213 c0nst::c0nst! {
1214 impl c0nst ConstDivCeil for $t {
1215 fn div_ceil(self, rhs: Self) -> Self {
1216 <$t>::div_ceil(self, rhs)
1217 }
1218 fn checked_div_ceil(self, rhs: Self) -> Option<Self> {
1219 if rhs.is_zero() {
1220 None
1221 } else {
1222 Some(<$t>::div_ceil(self, rhs))
1223 }
1224 }
1225 }
1226 }
1227 };
1228}
1229
1230const_div_ceil_impl!(u8);
1231const_div_ceil_impl!(u16);
1232const_div_ceil_impl!(u32);
1233const_div_ceil_impl!(u64);
1234const_div_ceil_impl!(u128);
1235
1236#[cfg(feature = "nightly")]
1238macro_rules! const_isqrt_impl {
1239 ($t:ty) => {
1240 c0nst::c0nst! {
1241 impl c0nst ConstIsqrt for $t {
1242 fn isqrt(self) -> Self {
1243 <$t>::isqrt(self)
1244 }
1245 fn checked_isqrt(self) -> Option<Self> {
1246 Some(<$t>::isqrt(self))
1248 }
1249 }
1250 }
1251 };
1252}
1253
1254#[cfg(feature = "nightly")]
1255const_isqrt_impl!(u8);
1256#[cfg(feature = "nightly")]
1257const_isqrt_impl!(u16);
1258#[cfg(feature = "nightly")]
1259const_isqrt_impl!(u32);
1260#[cfg(feature = "nightly")]
1261const_isqrt_impl!(u64);
1262#[cfg(feature = "nightly")]
1263const_isqrt_impl!(u128);
1264
1265#[cfg(not(feature = "nightly"))]
1268macro_rules! const_carrying_add_impl {
1269 ($t:ty) => {
1270 c0nst::c0nst! {
1271 impl c0nst ConstCarryingAdd for $t {
1272 fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
1273 let (sum1, c1) = self.overflowing_add(rhs);
1274 let (sum2, c2) = sum1.overflowing_add(carry as $t);
1275 (sum2, c1 | c2)
1278 }
1279 }
1280 }
1281 };
1282}
1283
1284#[cfg(feature = "nightly")]
1285macro_rules! const_carrying_add_impl {
1286 ($t:ty) => {
1287 c0nst::c0nst! {
1288 impl c0nst ConstCarryingAdd for $t {
1289 fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) {
1290 <$t>::carrying_add(self, rhs, carry)
1291 }
1292 }
1293 }
1294 };
1295}
1296
1297#[cfg(not(feature = "nightly"))]
1298macro_rules! const_borrowing_sub_impl {
1299 ($t:ty) => {
1300 c0nst::c0nst! {
1301 impl c0nst ConstBorrowingSub for $t {
1302 fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
1303 let (diff1, b1) = self.overflowing_sub(rhs);
1304 let (diff2, b2) = diff1.overflowing_sub(borrow as $t);
1305 (diff2, b1 | b2)
1306 }
1307 }
1308 }
1309 };
1310}
1311
1312#[cfg(feature = "nightly")]
1313macro_rules! const_borrowing_sub_impl {
1314 ($t:ty) => {
1315 c0nst::c0nst! {
1316 impl c0nst ConstBorrowingSub for $t {
1317 fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool) {
1318 <$t>::borrowing_sub(self, rhs, borrow)
1319 }
1320 }
1321 }
1322 };
1323}
1324
1325#[cfg(not(feature = "nightly"))]
1326macro_rules! const_widening_mul_impl {
1327 ($t:ty, $double:ty, $bits:expr) => {
1328 c0nst::c0nst! {
1329 impl c0nst ConstWideningMul for $t {
1330 fn widening_mul(self, rhs: Self) -> (Self, Self) {
1331 let product = (self as $double) * (rhs as $double);
1332 (product as $t, (product >> $bits) as $t)
1333 }
1334 }
1335 }
1336 };
1337}
1338
1339#[cfg(feature = "nightly")]
1340macro_rules! const_widening_mul_impl {
1341 ($t:ty, $double:ty, $bits:expr) => {
1342 c0nst::c0nst! {
1343 impl c0nst ConstWideningMul for $t {
1344 fn widening_mul(self, rhs: Self) -> (Self, Self) {
1345 let product: $double = <$t>::widening_mul(self, rhs);
1346 (product as $t, (product >> $bits) as $t)
1347 }
1348 }
1349 }
1350 };
1351}
1352
1353#[cfg(not(feature = "nightly"))]
1354macro_rules! const_carrying_mul_impl {
1355 ($t:ty, $double:ty, $bits:expr) => {
1356 c0nst::c0nst! {
1357 impl c0nst ConstCarryingMul for $t {
1358 fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
1359 let product = (self as $double) * (rhs as $double) + (carry as $double);
1360 (product as $t, (product >> $bits) as $t)
1361 }
1362 fn carrying_mul_add(self, rhs: Self, addend: Self, carry: Self) -> (Self, Self) {
1363 let product = (self as $double) * (rhs as $double)
1364 + (addend as $double)
1365 + (carry as $double);
1366 (product as $t, (product >> $bits) as $t)
1367 }
1368 }
1369 }
1370 };
1371}
1372
1373#[cfg(feature = "nightly")]
1374macro_rules! const_carrying_mul_impl {
1375 ($t:ty, $double:ty, $bits:expr) => {
1376 c0nst::c0nst! {
1377 impl c0nst ConstCarryingMul for $t {
1378 fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
1379 <$t>::carrying_mul(self, rhs, carry)
1380 }
1381 fn carrying_mul_add(self, rhs: Self, addend: Self, carry: Self) -> (Self, Self) {
1382 let (lo, hi) = <$t>::carrying_mul(self, rhs, carry);
1384 let (lo2, c) = lo.overflowing_add(addend);
1385 (lo2, hi.wrapping_add(c as $t))
1386 }
1387 }
1388 }
1389 };
1390}
1391
1392const_carrying_add_impl!(u8);
1393const_carrying_add_impl!(u16);
1394const_carrying_add_impl!(u32);
1395const_carrying_add_impl!(u64);
1396const_carrying_add_impl!(u128);
1397
1398const_borrowing_sub_impl!(u8);
1399const_borrowing_sub_impl!(u16);
1400const_borrowing_sub_impl!(u32);
1401const_borrowing_sub_impl!(u64);
1402const_borrowing_sub_impl!(u128);
1403
1404const_widening_mul_impl!(u8, u16, 8);
1405const_widening_mul_impl!(u16, u32, 16);
1406const_widening_mul_impl!(u32, u64, 32);
1407const_widening_mul_impl!(u64, u128, 64);
1408const_carrying_mul_impl!(u8, u16, 8);
1411const_carrying_mul_impl!(u16, u32, 16);
1412const_carrying_mul_impl!(u32, u64, 32);
1413const_carrying_mul_impl!(u64, u128, 64);
1414#[cfg(not(feature = "1_87"))]
1418macro_rules! const_midpoint_impl {
1419 ($t:ty) => {
1420 c0nst::c0nst! {
1421 impl c0nst ConstMidpoint for $t {
1422 fn midpoint(self, rhs: Self) -> Self {
1423 (self & rhs) + ((self ^ rhs) >> 1)
1425 }
1426 }
1427 }
1428 };
1429}
1430
1431#[cfg(feature = "1_87")]
1432macro_rules! const_midpoint_impl {
1433 ($t:ty) => {
1434 c0nst::c0nst! {
1435 impl c0nst ConstMidpoint for $t {
1436 fn midpoint(self, rhs: Self) -> Self {
1437 <$t>::midpoint(self, rhs)
1438 }
1439 }
1440 }
1441 };
1442}
1443
1444const_midpoint_impl!(u8);
1445const_midpoint_impl!(u16);
1446const_midpoint_impl!(u32);
1447const_midpoint_impl!(u64);
1448const_midpoint_impl!(u128);
1449
1450#[cfg(not(feature = "1_87"))]
1452macro_rules! const_unbounded_shift_impl {
1453 ($t:ty, $bits:expr) => {
1454 c0nst::c0nst! {
1455 impl c0nst ConstUnboundedShift for $t {
1456 fn unbounded_shl(self, rhs: u32) -> Self {
1457 if rhs >= $bits { 0 } else { self << rhs }
1458 }
1459 fn unbounded_shr(self, rhs: u32) -> Self {
1460 if rhs >= $bits { 0 } else { self >> rhs }
1461 }
1462 }
1463 }
1464 };
1465}
1466
1467#[cfg(feature = "1_87")]
1468macro_rules! const_unbounded_shift_impl {
1469 ($t:ty, $bits:expr) => {
1470 c0nst::c0nst! {
1471 impl c0nst ConstUnboundedShift for $t {
1472 fn unbounded_shl(self, rhs: u32) -> Self {
1473 <$t>::unbounded_shl(self, rhs)
1474 }
1475 fn unbounded_shr(self, rhs: u32) -> Self {
1476 <$t>::unbounded_shr(self, rhs)
1477 }
1478 }
1479 }
1480 };
1481}
1482
1483const_unbounded_shift_impl!(u8, 8);
1484const_unbounded_shift_impl!(u16, 16);
1485const_unbounded_shift_impl!(u32, 32);
1486const_unbounded_shift_impl!(u64, 64);
1487const_unbounded_shift_impl!(u128, 128);
1488
1489const_bit_prim_int_impl!(u8);
1490const_bit_prim_int_impl!(u16);
1491const_bit_prim_int_impl!(u32);
1492const_bit_prim_int_impl!(u64);
1493const_bit_prim_int_impl!(u128);
1494
1495const_prim_int_impl!(u8);
1496const_prim_int_impl!(u16);
1497const_prim_int_impl!(u32);
1498const_prim_int_impl!(u64);
1499const_prim_int_impl!(u128);
1500
1501#[cfg(test)]
1502mod tests {
1503 use super::*;
1504
1505 c0nst::c0nst! {
1506 pub c0nst fn add_words<T: [c0nst] ConstPrimInt>(a: T, b: T) -> T {
1507 a + b
1508 }
1509
1510 pub c0nst fn assign_add<T: [c0nst] ConstPrimInt>(a: &mut T, b: T) {
1511 *a += b;
1512 }
1513
1514 pub c0nst fn default_word<T: [c0nst] ConstPrimInt>() -> T {
1515 T::default()
1516 }
1517
1518 pub c0nst fn zero_word<T: [c0nst] ConstZero>() -> T {
1519 T::zero()
1520 }
1521
1522 pub c0nst fn one_word<T: [c0nst] ConstOne>() -> T {
1523 T::one()
1524 }
1525
1526 pub c0nst fn min_word<T: [c0nst] ConstBounded>() -> T {
1527 T::min_value()
1528 }
1529
1530 pub c0nst fn max_word<T: [c0nst] ConstBounded>() -> T {
1531 T::max_value()
1532 }
1533
1534 pub c0nst fn is_zero_word<T: [c0nst] ConstZero>(v: &T) -> bool {
1535 v.is_zero()
1536 }
1537
1538 pub c0nst fn set_zero_word<T: [c0nst] ConstZero>(v: &mut T) {
1539 v.set_zero();
1540 }
1541
1542 pub c0nst fn is_one_word<T: [c0nst] ConstOne>(v: &T) -> bool {
1543 v.is_one()
1544 }
1545
1546 pub c0nst fn set_one_word<T: [c0nst] ConstOne>(v: &mut T) {
1547 v.set_one();
1548 }
1549
1550 pub c0nst fn overflowing_add_word<T: [c0nst] ConstOverflowingAdd>(a: &T, b: &T) -> (T, bool) {
1551 a.overflowing_add(b)
1552 }
1553
1554 pub c0nst fn overflowing_sub_word<T: [c0nst] ConstOverflowingSub>(a: &T, b: &T) -> (T, bool) {
1555 a.overflowing_sub(b)
1556 }
1557
1558 pub c0nst fn to_le_bytes_word<T: [c0nst] ConstToBytes>(v: &T) -> T::Bytes {
1559 v.to_le_bytes()
1560 }
1561
1562 pub c0nst fn to_be_bytes_word<T: [c0nst] ConstToBytes>(v: &T) -> T::Bytes {
1563 v.to_be_bytes()
1564 }
1565
1566 pub c0nst fn from_le_bytes_word<T: [c0nst] ConstFromBytes>(bytes: &T::Bytes) -> T {
1567 T::from_le_bytes(bytes)
1568 }
1569
1570 pub c0nst fn from_be_bytes_word<T: [c0nst] ConstFromBytes>(bytes: &T::Bytes) -> T {
1571 T::from_be_bytes(bytes)
1572 }
1573
1574 pub c0nst fn wrapping_add_word<T: [c0nst] ConstWrappingAdd>(a: &T, b: &T) -> T {
1575 a.wrapping_add(b)
1576 }
1577
1578 pub c0nst fn wrapping_sub_word<T: [c0nst] ConstWrappingSub>(a: &T, b: &T) -> T {
1579 a.wrapping_sub(b)
1580 }
1581
1582 pub c0nst fn checked_add_word<T: [c0nst] ConstCheckedAdd>(a: &T, b: &T) -> Option<T> {
1583 a.checked_add(b)
1584 }
1585
1586 pub c0nst fn checked_sub_word<T: [c0nst] ConstCheckedSub>(a: &T, b: &T) -> Option<T> {
1587 a.checked_sub(b)
1588 }
1589
1590 pub c0nst fn saturating_add_word<T: [c0nst] ConstSaturatingAdd>(a: &T, b: &T) -> T {
1591 a.saturating_add(b)
1592 }
1593
1594 pub c0nst fn saturating_sub_word<T: [c0nst] ConstSaturatingSub>(a: &T, b: &T) -> T {
1595 a.saturating_sub(b)
1596 }
1597
1598 pub c0nst fn carrying_add_word<T: [c0nst] ConstCarryingAdd>(a: T, b: T, carry: bool) -> (T, bool) {
1599 a.carrying_add(b, carry)
1600 }
1601
1602 pub c0nst fn borrowing_sub_word<T: [c0nst] ConstBorrowingSub>(a: T, b: T, borrow: bool) -> (T, bool) {
1603 a.borrowing_sub(b, borrow)
1604 }
1605
1606 pub c0nst fn widening_mul_word<T: [c0nst] ConstWideningMul>(a: T, b: T) -> (T, T) {
1607 a.widening_mul(b)
1608 }
1609
1610 pub c0nst fn carrying_mul_word<T: [c0nst] ConstCarryingMul>(a: T, b: T, carry: T) -> (T, T) {
1611 a.carrying_mul(b, carry)
1612 }
1613
1614 pub c0nst fn carrying_mul_add_word<T: [c0nst] ConstCarryingMul>(a: T, b: T, addend: T, carry: T) -> (T, T) {
1615 a.carrying_mul_add(b, addend, carry)
1616 }
1617
1618 pub c0nst fn midpoint_word<T: [c0nst] ConstMidpoint>(a: T, b: T) -> T {
1619 a.midpoint(b)
1620 }
1621
1622 pub c0nst fn unbounded_shl_word<T: [c0nst] ConstUnboundedShift>(a: T, n: u32) -> T {
1623 a.unbounded_shl(n)
1624 }
1625
1626 pub c0nst fn unbounded_shr_word<T: [c0nst] ConstUnboundedShift>(a: T, n: u32) -> T {
1627 a.unbounded_shr(n)
1628 }
1629 }
1630
1631 #[test]
1632 fn test_constprimint_ops() {
1633 assert_eq!(add_words(2u8, 3u8), 5u8);
1634 assert_eq!(default_word::<u32>(), 0u32);
1635 assert_eq!(zero_word::<u64>(), 0u64);
1636 assert_eq!(one_word::<u128>(), 1u128);
1637 assert_eq!(min_word::<u8>(), 0u8);
1638 assert_eq!(max_word::<u8>(), 255u8);
1639
1640 let mut val = 10u8;
1641 assign_add(&mut val, 5u8);
1642 assert_eq!(val, 15u8);
1643
1644 #[cfg(feature = "nightly")]
1645 {
1646 const ADD_RES: u8 = add_words(2u8, 3u8);
1647 const DEFAULT_RES: u32 = default_word::<u32>();
1648 const ZERO_RES: u64 = zero_word::<u64>();
1649 const ONE_RES: u128 = one_word::<u128>();
1650 const MIN_RES: u8 = min_word::<u8>();
1651 const MAX_RES: u8 = max_word::<u8>();
1652 const ASSIGN_RES: u8 = {
1653 let mut v = 10u8;
1654 assign_add(&mut v, 5u8);
1655 v
1656 };
1657 assert_eq!(ADD_RES, 5u8);
1658 assert_eq!(DEFAULT_RES, 0u32);
1659 assert_eq!(ZERO_RES, 0u64);
1660 assert_eq!(ONE_RES, 1u128);
1661 assert_eq!(MIN_RES, 0u8);
1662 assert_eq!(MAX_RES, 255u8);
1663 assert_eq!(ASSIGN_RES, 15u8);
1664 }
1665 }
1666
1667 #[test]
1668 fn test_const_zero_one_methods() {
1669 assert!(is_zero_word(&0u8));
1671 assert!(!is_zero_word(&1u8));
1672 assert!(is_zero_word(&0u64));
1673 assert!(!is_zero_word(&42u64));
1674
1675 let mut val = 42u32;
1677 set_zero_word(&mut val);
1678 assert_eq!(val, 0u32);
1679
1680 assert!(is_one_word(&1u8));
1682 assert!(!is_one_word(&0u8));
1683 assert!(!is_one_word(&2u8));
1684 assert!(is_one_word(&1u128));
1685
1686 let mut val = 0u16;
1688 set_one_word(&mut val);
1689 assert_eq!(val, 1u16);
1690
1691 #[cfg(feature = "nightly")]
1692 {
1693 const IS_ZERO_TRUE: bool = is_zero_word(&0u8);
1694 const IS_ZERO_FALSE: bool = is_zero_word(&1u8);
1695 const SET_ZERO_RES: u32 = {
1696 let mut v = 42u32;
1697 set_zero_word(&mut v);
1698 v
1699 };
1700 const IS_ONE_TRUE: bool = is_one_word(&1u64);
1701 const IS_ONE_FALSE: bool = is_one_word(&0u64);
1702 const SET_ONE_RES: u16 = {
1703 let mut v = 0u16;
1704 set_one_word(&mut v);
1705 v
1706 };
1707 assert!(IS_ZERO_TRUE);
1708 assert!(!IS_ZERO_FALSE);
1709 assert_eq!(SET_ZERO_RES, 0u32);
1710 assert!(IS_ONE_TRUE);
1711 assert!(!IS_ONE_FALSE);
1712 assert_eq!(SET_ONE_RES, 1u16);
1713 }
1714 }
1715
1716 #[test]
1717 fn test_const_overflowing_ops() {
1718 let (sum, overflow) = overflowing_add_word(&100u8, &50u8);
1720 assert_eq!(sum, 150u8);
1721 assert!(!overflow);
1722
1723 let (sum, overflow) = overflowing_add_word(&200u8, &100u8);
1725 assert_eq!(sum, 44u8); assert!(overflow);
1727
1728 let (diff, overflow) = overflowing_sub_word(&100u8, &50u8);
1730 assert_eq!(diff, 50u8);
1731 assert!(!overflow);
1732
1733 let (diff, overflow) = overflowing_sub_word(&50u8, &100u8);
1735 assert_eq!(diff, 206u8); assert!(overflow);
1737
1738 let (sum, overflow) = overflowing_add_word(&u64::MAX, &1u64);
1740 assert_eq!(sum, 0u64);
1741 assert!(overflow);
1742
1743 #[cfg(feature = "nightly")]
1744 {
1745 const ADD_NO_OVERFLOW: (u8, bool) = overflowing_add_word(&100u8, &50u8);
1746 const ADD_OVERFLOW: (u8, bool) = overflowing_add_word(&200u8, &100u8);
1747 const SUB_NO_OVERFLOW: (u8, bool) = overflowing_sub_word(&100u8, &50u8);
1748 const SUB_OVERFLOW: (u8, bool) = overflowing_sub_word(&50u8, &100u8);
1749
1750 assert_eq!(ADD_NO_OVERFLOW, (150u8, false));
1751 assert_eq!(ADD_OVERFLOW, (44u8, true));
1752 assert_eq!(SUB_NO_OVERFLOW, (50u8, false));
1753 assert_eq!(SUB_OVERFLOW, (206u8, true));
1754 }
1755 }
1756
1757 #[test]
1758 fn test_const_to_bytes() {
1759 let bytes = to_le_bytes_word(&0x12345678u32);
1761 assert_eq!(bytes.as_ref(), &[0x78, 0x56, 0x34, 0x12]);
1762
1763 let bytes = to_be_bytes_word(&0x12345678u32);
1765 assert_eq!(bytes.as_ref(), &[0x12, 0x34, 0x56, 0x78]);
1766
1767 let bytes = to_le_bytes_word(&0xABu8);
1769 assert_eq!(bytes.as_ref(), &[0xAB]);
1770
1771 let bytes = to_le_bytes_word(&0x0102030405060708u64);
1773 assert_eq!(
1774 bytes.as_ref(),
1775 &[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]
1776 );
1777
1778 #[cfg(feature = "nightly")]
1779 {
1780 const LE_BYTES: [u8; 4] = to_le_bytes_word(&0x12345678u32);
1781 const BE_BYTES: [u8; 4] = to_be_bytes_word(&0x12345678u32);
1782 assert_eq!(LE_BYTES, [0x78, 0x56, 0x34, 0x12]);
1783 assert_eq!(BE_BYTES, [0x12, 0x34, 0x56, 0x78]);
1784 }
1785 }
1786
1787 #[test]
1788 fn test_const_from_bytes() {
1789 let val: u32 = from_le_bytes_word(&[0x78, 0x56, 0x34, 0x12]);
1791 assert_eq!(val, 0x12345678u32);
1792
1793 let val: u32 = from_be_bytes_word(&[0x12, 0x34, 0x56, 0x78]);
1795 assert_eq!(val, 0x12345678u32);
1796
1797 let val: u8 = from_le_bytes_word(&[0xAB]);
1799 assert_eq!(val, 0xABu8);
1800
1801 let val: u64 = from_le_bytes_word(&[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]);
1803 assert_eq!(val, 0x0102030405060708u64);
1804
1805 let original = 0xDEADBEEFu32;
1807 let bytes = to_le_bytes_word(&original);
1808 let roundtrip: u32 = from_le_bytes_word(&bytes);
1809 assert_eq!(roundtrip, original);
1810
1811 #[cfg(feature = "nightly")]
1812 {
1813 const FROM_LE: u32 = from_le_bytes_word(&[0x78, 0x56, 0x34, 0x12]);
1814 const FROM_BE: u32 = from_be_bytes_word(&[0x12, 0x34, 0x56, 0x78]);
1815 assert_eq!(FROM_LE, 0x12345678u32);
1816 assert_eq!(FROM_BE, 0x12345678u32);
1817 }
1818 }
1819
1820 #[test]
1821 fn test_const_wrapping_checked_ops() {
1822 assert_eq!(wrapping_add_word(&100u8, &50u8), 150u8);
1824 assert_eq!(wrapping_add_word(&200u8, &100u8), 44u8);
1826
1827 assert_eq!(wrapping_sub_word(&100u8, &50u8), 50u8);
1829 assert_eq!(wrapping_sub_word(&50u8, &100u8), 206u8);
1831
1832 assert_eq!(checked_add_word(&100u8, &50u8), Some(150u8));
1834 assert_eq!(checked_add_word(&200u8, &100u8), None);
1836
1837 assert_eq!(checked_sub_word(&100u8, &50u8), Some(50u8));
1839 assert_eq!(checked_sub_word(&50u8, &100u8), None);
1841
1842 assert_eq!(wrapping_add_word(&u64::MAX, &1u64), 0u64);
1844 assert_eq!(checked_add_word(&u64::MAX, &1u64), None);
1845
1846 #[cfg(feature = "nightly")]
1847 {
1848 const WRAP_ADD_NO_OVERFLOW: u8 = wrapping_add_word(&100u8, &50u8);
1849 const WRAP_ADD_OVERFLOW: u8 = wrapping_add_word(&200u8, &100u8);
1850 const WRAP_SUB_NO_OVERFLOW: u8 = wrapping_sub_word(&100u8, &50u8);
1851 const WRAP_SUB_OVERFLOW: u8 = wrapping_sub_word(&50u8, &100u8);
1852
1853 const CHECK_ADD_OK: Option<u8> = checked_add_word(&100u8, &50u8);
1854 const CHECK_ADD_OVERFLOW: Option<u8> = checked_add_word(&200u8, &100u8);
1855 const CHECK_SUB_OK: Option<u8> = checked_sub_word(&100u8, &50u8);
1856 const CHECK_SUB_OVERFLOW: Option<u8> = checked_sub_word(&50u8, &100u8);
1857
1858 assert_eq!(WRAP_ADD_NO_OVERFLOW, 150u8);
1859 assert_eq!(WRAP_ADD_OVERFLOW, 44u8);
1860 assert_eq!(WRAP_SUB_NO_OVERFLOW, 50u8);
1861 assert_eq!(WRAP_SUB_OVERFLOW, 206u8);
1862
1863 assert_eq!(CHECK_ADD_OK, Some(150u8));
1864 assert_eq!(CHECK_ADD_OVERFLOW, None);
1865 assert_eq!(CHECK_SUB_OK, Some(50u8));
1866 assert_eq!(CHECK_SUB_OVERFLOW, None);
1867 }
1868 }
1869
1870 #[test]
1871 fn test_const_saturating_ops() {
1872 assert_eq!(saturating_add_word(&100u8, &50u8), 150u8);
1874 assert_eq!(saturating_add_word(&200u8, &100u8), 255u8);
1876
1877 assert_eq!(saturating_sub_word(&100u8, &50u8), 50u8);
1879 assert_eq!(saturating_sub_word(&50u8, &100u8), 0u8);
1881
1882 assert_eq!(saturating_add_word(&u64::MAX, &1u64), u64::MAX);
1884 assert_eq!(saturating_sub_word(&0u64, &1u64), 0u64);
1885
1886 #[cfg(feature = "nightly")]
1887 {
1888 const SAT_ADD_NO_OVERFLOW: u8 = saturating_add_word(&100u8, &50u8);
1889 const SAT_ADD_OVERFLOW: u8 = saturating_add_word(&200u8, &100u8);
1890 const SAT_SUB_NO_OVERFLOW: u8 = saturating_sub_word(&100u8, &50u8);
1891 const SAT_SUB_OVERFLOW: u8 = saturating_sub_word(&50u8, &100u8);
1892
1893 assert_eq!(SAT_ADD_NO_OVERFLOW, 150u8);
1894 assert_eq!(SAT_ADD_OVERFLOW, 255u8);
1895 assert_eq!(SAT_SUB_NO_OVERFLOW, 50u8);
1896 assert_eq!(SAT_SUB_OVERFLOW, 0u8);
1897 }
1898 }
1899
1900 #[test]
1901 fn test_const_carrying_add() {
1902 let (sum, carry) = carrying_add_word(100u8, 50u8, false);
1904 assert_eq!(sum, 150u8);
1905 assert!(!carry);
1906
1907 let (sum, carry) = carrying_add_word(200u8, 100u8, false);
1909 assert_eq!(sum, 44u8); assert!(carry);
1911
1912 let (sum, carry) = carrying_add_word(100u8, 50u8, true);
1914 assert_eq!(sum, 151u8);
1915 assert!(!carry);
1916
1917 let (sum, carry) = carrying_add_word(200u8, 55u8, true);
1919 assert_eq!(sum, 0u8); assert!(carry);
1921
1922 let (sum, carry) = carrying_add_word(u8::MAX, 0u8, true);
1924 assert_eq!(sum, 0u8);
1925 assert!(carry);
1926
1927 let (sum, carry) = carrying_add_word(u64::MAX, 0u64, true);
1929 assert_eq!(sum, 0u64);
1930 assert!(carry);
1931
1932 #[cfg(feature = "nightly")]
1933 {
1934 const CA_NO_CARRY: (u8, bool) = carrying_add_word(100u8, 50u8, false);
1935 const CA_CARRY_OUT: (u8, bool) = carrying_add_word(200u8, 100u8, false);
1936 const CA_CARRY_IN: (u8, bool) = carrying_add_word(100u8, 50u8, true);
1937 const CA_BOTH_CARRY: (u8, bool) = carrying_add_word(200u8, 55u8, true);
1938
1939 assert_eq!(CA_NO_CARRY, (150u8, false));
1940 assert_eq!(CA_CARRY_OUT, (44u8, true));
1941 assert_eq!(CA_CARRY_IN, (151u8, false));
1942 assert_eq!(CA_BOTH_CARRY, (0u8, true));
1943 }
1944 }
1945
1946 #[test]
1947 fn test_const_borrowing_sub() {
1948 let (diff, borrow) = borrowing_sub_word(100u8, 50u8, false);
1950 assert_eq!(diff, 50u8);
1951 assert!(!borrow);
1952
1953 let (diff, borrow) = borrowing_sub_word(50u8, 100u8, false);
1955 assert_eq!(diff, 206u8); assert!(borrow);
1957
1958 let (diff, borrow) = borrowing_sub_word(100u8, 50u8, true);
1960 assert_eq!(diff, 49u8);
1961 assert!(!borrow);
1962
1963 let (diff, borrow) = borrowing_sub_word(50u8, 50u8, true);
1965 assert_eq!(diff, 255u8); assert!(borrow);
1967
1968 let (diff, borrow) = borrowing_sub_word(0u8, 0u8, true);
1970 assert_eq!(diff, 255u8);
1971 assert!(borrow);
1972
1973 let (diff, borrow) = borrowing_sub_word(0u64, 0u64, true);
1975 assert_eq!(diff, u64::MAX);
1976 assert!(borrow);
1977
1978 #[cfg(feature = "nightly")]
1979 {
1980 const BS_NO_BORROW: (u8, bool) = borrowing_sub_word(100u8, 50u8, false);
1981 const BS_BORROW_OUT: (u8, bool) = borrowing_sub_word(50u8, 100u8, false);
1982 const BS_BORROW_IN: (u8, bool) = borrowing_sub_word(100u8, 50u8, true);
1983 const BS_BOTH_BORROW: (u8, bool) = borrowing_sub_word(50u8, 50u8, true);
1984
1985 assert_eq!(BS_NO_BORROW, (50u8, false));
1986 assert_eq!(BS_BORROW_OUT, (206u8, true));
1987 assert_eq!(BS_BORROW_IN, (49u8, false));
1988 assert_eq!(BS_BOTH_BORROW, (255u8, true));
1989 }
1990 }
1991
1992 #[test]
1993 fn test_const_widening_mul() {
1994 let (lo, hi) = widening_mul_word(10u8, 5u8);
1996 assert_eq!(lo, 50u8);
1997 assert_eq!(hi, 0u8);
1998
1999 let (lo, hi) = widening_mul_word(200u8, 3u8);
2001 assert_eq!(lo, 88u8); assert_eq!(hi, 2u8); let (lo, hi) = widening_mul_word(u8::MAX, u8::MAX);
2006 assert_eq!(lo, 0x01u8);
2008 assert_eq!(hi, 0xFEu8);
2009
2010 let (lo, hi) = widening_mul_word(1000u16, 1000u16);
2012 assert_eq!(lo, 0x4240u16);
2014 assert_eq!(hi, 0x000Fu16);
2015
2016 let (lo, hi) = widening_mul_word(u64::MAX, 2u64);
2018 assert_eq!(lo, u64::MAX - 1);
2020 assert_eq!(hi, 1u64);
2021
2022 #[cfg(feature = "nightly")]
2023 {
2024 const WM_SIMPLE: (u8, u8) = widening_mul_word(10u8, 5u8);
2025 const WM_HIGH: (u8, u8) = widening_mul_word(200u8, 3u8);
2026 const WM_MAX: (u8, u8) = widening_mul_word(u8::MAX, u8::MAX);
2027
2028 assert_eq!(WM_SIMPLE, (50u8, 0u8));
2029 assert_eq!(WM_HIGH, (88u8, 2u8));
2030 assert_eq!(WM_MAX, (0x01u8, 0xFEu8));
2031 }
2032 }
2033
2034 #[test]
2035 fn test_const_carrying_mul() {
2036 let (lo, hi) = carrying_mul_word(10u8, 5u8, 0u8);
2038 assert_eq!(lo, 50u8);
2039 assert_eq!(hi, 0u8);
2040
2041 let (lo, hi) = carrying_mul_word(10u8, 5u8, 10u8);
2043 assert_eq!(lo, 60u8);
2045 assert_eq!(hi, 0u8);
2046
2047 let (lo, hi) = carrying_mul_word(200u8, 3u8, 0u8);
2049 assert_eq!(lo, 88u8); assert_eq!(hi, 2u8); let (lo, hi) = carrying_mul_word(200u8, 3u8, 200u8);
2054 assert_eq!(lo, 0x20u8);
2056 assert_eq!(hi, 3u8);
2057
2058 let (lo, hi) = carrying_mul_word(u8::MAX, u8::MAX, u8::MAX);
2060 assert_eq!(lo, 0x00u8);
2062 assert_eq!(hi, 0xFFu8);
2063
2064 let (lo, hi) = carrying_mul_word(1000u16, 1000u16, 1000u16);
2066 assert_eq!(lo, 0x4628u16);
2068 assert_eq!(hi, 0x000Fu16);
2069
2070 #[cfg(feature = "nightly")]
2071 {
2072 const CM_SIMPLE: (u8, u8) = carrying_mul_word(10u8, 5u8, 0u8);
2073 const CM_WITH_CARRY: (u8, u8) = carrying_mul_word(10u8, 5u8, 10u8);
2074 const CM_MAX: (u8, u8) = carrying_mul_word(u8::MAX, u8::MAX, u8::MAX);
2075
2076 assert_eq!(CM_SIMPLE, (50u8, 0u8));
2077 assert_eq!(CM_WITH_CARRY, (60u8, 0u8));
2078 assert_eq!(CM_MAX, (0x00u8, 0xFFu8));
2079 }
2080 }
2081
2082 #[test]
2083 fn test_const_carrying_mul_add() {
2084 let (lo, hi) = carrying_mul_add_word(10u8, 5u8, 7u8, 0u8);
2086 assert_eq!(lo, 57u8);
2087 assert_eq!(hi, 0u8);
2088
2089 let (lo, hi) = carrying_mul_add_word(10u8, 5u8, 10u8, 10u8);
2091 assert_eq!(lo, 70u8);
2092 assert_eq!(hi, 0u8);
2093
2094 let (lo, hi) = carrying_mul_add_word(16u8, 16u8, 0u8, 0u8);
2098 assert_eq!(lo, 0x00u8);
2099 assert_eq!(hi, 1u8);
2100
2101 let (lo, hi) = carrying_mul_add_word(u8::MAX, u8::MAX, u8::MAX, u8::MAX);
2105 assert_eq!(lo, 0xFFu8);
2107 assert_eq!(hi, 0xFFu8);
2108
2109 #[cfg(feature = "nightly")]
2116 {
2117 const CMA_SIMPLE: (u8, u8) = carrying_mul_add_word(10u8, 5u8, 7u8, 0u8);
2118 const CMA_MAX: (u8, u8) = carrying_mul_add_word(u8::MAX, u8::MAX, u8::MAX, u8::MAX);
2119
2120 assert_eq!(CMA_SIMPLE, (57u8, 0u8));
2121 assert_eq!(CMA_MAX, (0xFFu8, 0xFFu8));
2122 }
2123 }
2124
2125 #[test]
2126 fn test_const_midpoint() {
2127 assert_eq!(midpoint_word(0u8, 10u8), 5u8);
2129 assert_eq!(midpoint_word(10u8, 0u8), 5u8); assert_eq!(midpoint_word(0u8, 9u8), 4u8); assert_eq!(midpoint_word(1u8, 10u8), 5u8); assert_eq!(midpoint_word(42u8, 42u8), 42u8);
2137
2138 assert_eq!(midpoint_word(u8::MAX, u8::MAX), u8::MAX);
2140 assert_eq!(midpoint_word(u8::MAX, u8::MAX - 1), u8::MAX - 1); assert_eq!(midpoint_word(0u8, u8::MAX), 127u8); assert_eq!(midpoint_word(0u64, 100u64), 50u64);
2145 assert_eq!(midpoint_word(u64::MAX, u64::MAX), u64::MAX);
2146 assert_eq!(midpoint_word(u64::MAX - 1, u64::MAX), u64::MAX - 1); assert_eq!(midpoint_word(0u128, u128::MAX), u128::MAX / 2);
2150
2151 #[cfg(feature = "nightly")]
2152 {
2153 const MID_SIMPLE: u8 = midpoint_word(0u8, 10u8);
2154 const MID_ROUND: u8 = midpoint_word(0u8, 9u8);
2155 const MID_MAX: u8 = midpoint_word(u8::MAX, u8::MAX);
2156 const MID_EDGE: u8 = midpoint_word(0u8, u8::MAX);
2157
2158 assert_eq!(MID_SIMPLE, 5u8);
2159 assert_eq!(MID_ROUND, 4u8);
2160 assert_eq!(MID_MAX, u8::MAX);
2161 assert_eq!(MID_EDGE, 127u8);
2162 }
2163 }
2164
2165 #[test]
2166 fn test_const_unbounded_shift() {
2167 assert_eq!(unbounded_shl_word(1u8, 0), 1u8);
2169 assert_eq!(unbounded_shl_word(1u8, 1), 2u8);
2170 assert_eq!(unbounded_shl_word(1u8, 7), 128u8);
2171 assert_eq!(unbounded_shr_word(128u8, 7), 1u8);
2172 assert_eq!(unbounded_shr_word(255u8, 4), 15u8);
2173
2174 assert_eq!(unbounded_shl_word(1u8, 8), 0u8);
2176 assert_eq!(unbounded_shr_word(255u8, 8), 0u8);
2177
2178 assert_eq!(unbounded_shl_word(255u8, 9), 0u8);
2180 assert_eq!(unbounded_shl_word(255u8, 100), 0u8);
2181 assert_eq!(unbounded_shr_word(255u8, 9), 0u8);
2182 assert_eq!(unbounded_shr_word(255u8, 100), 0u8);
2183
2184 assert_eq!(unbounded_shl_word(1u64, 63), 1u64 << 63);
2186 assert_eq!(unbounded_shl_word(1u64, 64), 0u64);
2187 assert_eq!(unbounded_shr_word(u64::MAX, 64), 0u64);
2188
2189 assert_eq!(unbounded_shl_word(1u128, 127), 1u128 << 127);
2191 assert_eq!(unbounded_shl_word(1u128, 128), 0u128);
2192 assert_eq!(unbounded_shr_word(u128::MAX, 128), 0u128);
2193
2194 #[cfg(feature = "nightly")]
2195 {
2196 const SHL_NORMAL: u8 = unbounded_shl_word(1u8, 4);
2197 const SHL_BOUNDARY: u8 = unbounded_shl_word(1u8, 8);
2198 const SHL_BEYOND: u8 = unbounded_shl_word(1u8, 100);
2199 const SHR_NORMAL: u8 = unbounded_shr_word(128u8, 4);
2200 const SHR_BOUNDARY: u8 = unbounded_shr_word(255u8, 8);
2201 const SHR_BEYOND: u8 = unbounded_shr_word(255u8, 100);
2202
2203 assert_eq!(SHL_NORMAL, 16u8);
2204 assert_eq!(SHL_BOUNDARY, 0u8);
2205 assert_eq!(SHL_BEYOND, 0u8);
2206 assert_eq!(SHR_NORMAL, 8u8);
2207 assert_eq!(SHR_BOUNDARY, 0u8);
2208 assert_eq!(SHR_BEYOND, 0u8);
2209 }
2210 }
2211}