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