@@ -455,6 +455,12 @@ macro_rules! nonzero_integer {
455
455
UnsignedPrimitive = $Uint: ty,
456
456
457
457
// Used in doc comments.
458
+ rot = $rot: literal,
459
+ rot_op = $rot_op: literal,
460
+ rot_result = $rot_result: literal,
461
+ swap_op = $swap_op: literal,
462
+ swapped = $swapped: literal,
463
+ reversed = $reversed: literal,
458
464
leading_zeros_test = $leading_zeros_test: expr,
459
465
) => {
460
466
/// An integer that is known not to equal zero.
@@ -604,6 +610,270 @@ macro_rules! nonzero_integer {
604
610
unsafe { NonZero :: new_unchecked( self . get( ) . count_ones( ) ) }
605
611
}
606
612
613
+ /// Shifts the bits to the left by a specified amount, `n`,
614
+ /// wrapping the truncated bits to the end of the resulting integer.
615
+ ///
616
+ /// Please note this isn't the same operation as the `<<` shifting operator!
617
+ ///
618
+ /// # Examples
619
+ ///
620
+ /// Basic usage:
621
+ ///
622
+ /// ```
623
+ /// #![feature(nonzero_bitwise)]
624
+ /// # use std::num::NonZero;
625
+ /// #
626
+ /// # fn main() { test().unwrap(); }
627
+ /// # fn test() -> Option<()> {
628
+ #[ doc = concat!( "let n = NonZero::new(" , $rot_op, stringify!( $Int) , ")?;" ) ]
629
+ #[ doc = concat!( "let m = NonZero::new(" , $rot_result, ")?;" ) ]
630
+ ///
631
+ #[ doc = concat!( "assert_eq!(n.rotate_left(" , $rot, "), m);" ) ]
632
+ /// # Some(())
633
+ /// # }
634
+ /// ```
635
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
636
+ #[ must_use = "this returns the result of the operation, \
637
+ without modifying the original"]
638
+ #[ inline( always) ]
639
+ pub const fn rotate_left( self , n: u32 ) -> Self {
640
+ let result = self . get( ) . rotate_left( n) ;
641
+ // SAFETY: Rotating bits preserves the property int > 0.
642
+ unsafe { Self :: new_unchecked( result) }
643
+ }
644
+
645
+ /// Shifts the bits to the right by a specified amount, `n`,
646
+ /// wrapping the truncated bits to the beginning of the resulting
647
+ /// integer.
648
+ ///
649
+ /// Please note this isn't the same operation as the `>>` shifting operator!
650
+ ///
651
+ /// # Examples
652
+ ///
653
+ /// Basic usage:
654
+ ///
655
+ /// ```
656
+ /// #![feature(nonzero_bitwise)]
657
+ /// # use std::num::NonZero;
658
+ /// #
659
+ /// # fn main() { test().unwrap(); }
660
+ /// # fn test() -> Option<()> {
661
+ #[ doc = concat!( "let n = NonZero::new(" , $rot_result, stringify!( $Int) , ")?;" ) ]
662
+ #[ doc = concat!( "let m = NonZero::new(" , $rot_op, ")?;" ) ]
663
+ ///
664
+ #[ doc = concat!( "assert_eq!(n.rotate_right(" , $rot, "), m);" ) ]
665
+ /// # Some(())
666
+ /// # }
667
+ /// ```
668
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
669
+ #[ must_use = "this returns the result of the operation, \
670
+ without modifying the original"]
671
+ #[ inline( always) ]
672
+ pub const fn rotate_right( self , n: u32 ) -> Self {
673
+ let result = self . get( ) . rotate_right( n) ;
674
+ // SAFETY: Rotating bits preserves the property int > 0.
675
+ unsafe { Self :: new_unchecked( result) }
676
+ }
677
+
678
+ /// Reverses the byte order of the integer.
679
+ ///
680
+ /// # Examples
681
+ ///
682
+ /// Basic usage:
683
+ ///
684
+ /// ```
685
+ /// #![feature(nonzero_bitwise)]
686
+ /// # use std::num::NonZero;
687
+ /// #
688
+ /// # fn main() { test().unwrap(); }
689
+ /// # fn test() -> Option<()> {
690
+ #[ doc = concat!( "let n = NonZero::new(" , $swap_op, stringify!( $Int) , ")?;" ) ]
691
+ /// let m = n.swap_bytes();
692
+ ///
693
+ #[ doc = concat!( "assert_eq!(m, NonZero::new(" , $swapped, ")?);" ) ]
694
+ /// # Some(())
695
+ /// # }
696
+ /// ```
697
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
698
+ #[ must_use = "this returns the result of the operation, \
699
+ without modifying the original"]
700
+ #[ inline( always) ]
701
+ pub const fn swap_bytes( self ) -> Self {
702
+ let result = self . get( ) . swap_bytes( ) ;
703
+ // SAFETY: Shuffling bytes preserves the property int > 0.
704
+ unsafe { Self :: new_unchecked( result) }
705
+ }
706
+
707
+ /// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit,
708
+ /// second least-significant bit becomes second most-significant bit, etc.
709
+ ///
710
+ /// # Examples
711
+ ///
712
+ /// Basic usage:
713
+ ///
714
+ /// ```
715
+ /// #![feature(nonzero_bitwise)]
716
+ /// # use std::num::NonZero;
717
+ /// #
718
+ /// # fn main() { test().unwrap(); }
719
+ /// # fn test() -> Option<()> {
720
+ #[ doc = concat!( "let n = NonZero::new(" , $swap_op, stringify!( $Int) , ")?;" ) ]
721
+ /// let m = n.reverse_bits();
722
+ ///
723
+ #[ doc = concat!( "assert_eq!(m, NonZero::new(" , $reversed, ")?);" ) ]
724
+ /// # Some(())
725
+ /// # }
726
+ /// ```
727
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
728
+ #[ must_use = "this returns the result of the operation, \
729
+ without modifying the original"]
730
+ #[ inline( always) ]
731
+ pub const fn reverse_bits( self ) -> Self {
732
+ let result = self . get( ) . reverse_bits( ) ;
733
+ // SAFETY: Reversing bits preserves the property int > 0.
734
+ unsafe { Self :: new_unchecked( result) }
735
+ }
736
+
737
+ /// Converts an integer from big endian to the target's endianness.
738
+ ///
739
+ /// On big endian this is a no-op. On little endian the bytes are
740
+ /// swapped.
741
+ ///
742
+ /// # Examples
743
+ ///
744
+ /// Basic usage:
745
+ ///
746
+ /// ```
747
+ /// #![feature(nonzero_bitwise)]
748
+ /// # use std::num::NonZero;
749
+ #[ doc = concat!( "use std::num::" , stringify!( $Ty) , ";" ) ]
750
+ /// #
751
+ /// # fn main() { test().unwrap(); }
752
+ /// # fn test() -> Option<()> {
753
+ #[ doc = concat!( "let n = NonZero::new(0x1A" , stringify!( $Int) , ")?;" ) ]
754
+ ///
755
+ /// if cfg!(target_endian = "big") {
756
+ #[ doc = concat!( " assert_eq!(" , stringify!( $Ty) , "::from_be(n), n)" ) ]
757
+ /// } else {
758
+ #[ doc = concat!( " assert_eq!(" , stringify!( $Ty) , "::from_be(n), n.swap_bytes())" ) ]
759
+ /// }
760
+ /// # Some(())
761
+ /// # }
762
+ /// ```
763
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
764
+ #[ must_use]
765
+ #[ inline( always) ]
766
+ pub const fn from_be( x: Self ) -> Self {
767
+ let result = $Int:: from_be( x. get( ) ) ;
768
+ // SAFETY: Shuffling bytes preserves the property int > 0.
769
+ unsafe { Self :: new_unchecked( result) }
770
+ }
771
+
772
+ /// Converts an integer from little endian to the target's endianness.
773
+ ///
774
+ /// On little endian this is a no-op. On big endian the bytes are
775
+ /// swapped.
776
+ ///
777
+ /// # Examples
778
+ ///
779
+ /// Basic usage:
780
+ ///
781
+ /// ```
782
+ /// #![feature(nonzero_bitwise)]
783
+ /// # use std::num::NonZero;
784
+ #[ doc = concat!( "use std::num::" , stringify!( $Ty) , ";" ) ]
785
+ /// #
786
+ /// # fn main() { test().unwrap(); }
787
+ /// # fn test() -> Option<()> {
788
+ #[ doc = concat!( "let n = NonZero::new(0x1A" , stringify!( $Int) , ")?;" ) ]
789
+ ///
790
+ /// if cfg!(target_endian = "little") {
791
+ #[ doc = concat!( " assert_eq!(" , stringify!( $Ty) , "::from_le(n), n)" ) ]
792
+ /// } else {
793
+ #[ doc = concat!( " assert_eq!(" , stringify!( $Ty) , "::from_le(n), n.swap_bytes())" ) ]
794
+ /// }
795
+ /// # Some(())
796
+ /// # }
797
+ /// ```
798
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
799
+ #[ must_use]
800
+ #[ inline( always) ]
801
+ pub const fn from_le( x: Self ) -> Self {
802
+ let result = $Int:: from_le( x. get( ) ) ;
803
+ // SAFETY: Shuffling bytes preserves the property int > 0.
804
+ unsafe { Self :: new_unchecked( result) }
805
+ }
806
+
807
+ /// Converts `self` to big endian from the target's endianness.
808
+ ///
809
+ /// On big endian this is a no-op. On little endian the bytes are
810
+ /// swapped.
811
+ ///
812
+ /// # Examples
813
+ ///
814
+ /// Basic usage:
815
+ ///
816
+ /// ```
817
+ /// #![feature(nonzero_bitwise)]
818
+ /// # use std::num::NonZero;
819
+ /// #
820
+ /// # fn main() { test().unwrap(); }
821
+ /// # fn test() -> Option<()> {
822
+ #[ doc = concat!( "let n = NonZero::new(0x1A" , stringify!( $Int) , ")?;" ) ]
823
+ ///
824
+ /// if cfg!(target_endian = "big") {
825
+ /// assert_eq!(n.to_be(), n)
826
+ /// } else {
827
+ /// assert_eq!(n.to_be(), n.swap_bytes())
828
+ /// }
829
+ /// # Some(())
830
+ /// # }
831
+ /// ```
832
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
833
+ #[ must_use = "this returns the result of the operation, \
834
+ without modifying the original"]
835
+ #[ inline( always) ]
836
+ pub const fn to_be( self ) -> Self {
837
+ let result = self . get( ) . to_be( ) ;
838
+ // SAFETY: Shuffling bytes preserves the property int > 0.
839
+ unsafe { Self :: new_unchecked( result) }
840
+ }
841
+
842
+ /// Converts `self` to little endian from the target's endianness.
843
+ ///
844
+ /// On little endian this is a no-op. On big endian the bytes are
845
+ /// swapped.
846
+ ///
847
+ /// # Examples
848
+ ///
849
+ /// Basic usage:
850
+ ///
851
+ /// ```
852
+ /// #![feature(nonzero_bitwise)]
853
+ /// # use std::num::NonZero;
854
+ /// #
855
+ /// # fn main() { test().unwrap(); }
856
+ /// # fn test() -> Option<()> {
857
+ #[ doc = concat!( "let n = NonZero::new(0x1A" , stringify!( $Int) , ")?;" ) ]
858
+ ///
859
+ /// if cfg!(target_endian = "little") {
860
+ /// assert_eq!(n.to_le(), n)
861
+ /// } else {
862
+ /// assert_eq!(n.to_le(), n.swap_bytes())
863
+ /// }
864
+ /// # Some(())
865
+ /// # }
866
+ /// ```
867
+ #[ unstable( feature = "nonzero_bitwise" , issue = "128281" ) ]
868
+ #[ must_use = "this returns the result of the operation, \
869
+ without modifying the original"]
870
+ #[ inline( always) ]
871
+ pub const fn to_le( self ) -> Self {
872
+ let result = self . get( ) . to_le( ) ;
873
+ // SAFETY: Shuffling bytes preserves the property int > 0.
874
+ unsafe { Self :: new_unchecked( result) }
875
+ }
876
+
607
877
nonzero_integer_signedness_dependent_methods! {
608
878
Primitive = $signedness $Int,
609
879
UnsignedPrimitive = $Uint,
@@ -826,22 +1096,54 @@ macro_rules! nonzero_integer {
826
1096
nonzero_integer_signedness_dependent_impls!( $signedness $Int) ;
827
1097
} ;
828
1098
829
- ( Self = $Ty: ident, Primitive = unsigned $Int: ident $( , ) ?) => {
1099
+ (
1100
+ Self = $Ty: ident,
1101
+ Primitive = unsigned $Int: ident,
1102
+ rot = $rot: literal,
1103
+ rot_op = $rot_op: literal,
1104
+ rot_result = $rot_result: literal,
1105
+ swap_op = $swap_op: literal,
1106
+ swapped = $swapped: literal,
1107
+ reversed = $reversed: literal,
1108
+ $( , ) ?
1109
+ ) => {
830
1110
nonzero_integer! {
831
1111
#[ stable( feature = "nonzero" , since = "1.28.0" ) ]
832
1112
Self = $Ty,
833
1113
Primitive = unsigned $Int,
834
1114
UnsignedPrimitive = $Int,
1115
+ rot = $rot,
1116
+ rot_op = $rot_op,
1117
+ rot_result = $rot_result,
1118
+ swap_op = $swap_op,
1119
+ swapped = $swapped,
1120
+ reversed = $reversed,
835
1121
leading_zeros_test = concat!( stringify!( $Int) , "::MAX" ) ,
836
1122
}
837
1123
} ;
838
1124
839
- ( Self = $Ty: ident, Primitive = signed $Int: ident, $( $rest: tt) * ) => {
1125
+ (
1126
+ Self = $Ty: ident,
1127
+ Primitive = signed $Int: ident,
1128
+ UnsignedPrimitive = $UInt: ident,
1129
+ rot = $rot: literal,
1130
+ rot_op = $rot_op: literal,
1131
+ rot_result = $rot_result: literal,
1132
+ swap_op = $swap_op: literal,
1133
+ swapped = $swapped: literal,
1134
+ reversed = $reversed: literal,
1135
+ ) => {
840
1136
nonzero_integer! {
841
1137
#[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
842
1138
Self = $Ty,
843
1139
Primitive = signed $Int,
844
- $( $rest) *
1140
+ UnsignedPrimitive = $UInt,
1141
+ rot = $rot,
1142
+ rot_op = $rot_op,
1143
+ rot_result = $rot_result,
1144
+ swap_op = $swap_op,
1145
+ swapped = $swapped,
1146
+ reversed = $reversed,
845
1147
leading_zeros_test = concat!( "-1" , stringify!( $Int) ) ,
846
1148
}
847
1149
} ;
@@ -1241,6 +1543,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
1241
1543
/// assert_eq!(ten.isqrt(), three);
1242
1544
/// # Some(())
1243
1545
/// # }
1546
+ /// ```
1244
1547
#[ unstable( feature = "isqrt" , issue = "116226" ) ]
1245
1548
#[ rustc_const_unstable( feature = "isqrt" , issue = "116226" ) ]
1246
1549
#[ must_use = "this returns the result of the operation, \
@@ -1704,65 +2007,189 @@ macro_rules! sign_dependent_expr {
1704
2007
nonzero_integer ! {
1705
2008
Self = NonZeroU8 ,
1706
2009
Primitive = unsigned u8 ,
2010
+ rot = 2 ,
2011
+ rot_op = "0x82" ,
2012
+ rot_result = "0xa" ,
2013
+ swap_op = "0x12" ,
2014
+ swapped = "0x12" ,
2015
+ reversed = "0x48" ,
1707
2016
}
1708
2017
1709
2018
nonzero_integer ! {
1710
2019
Self = NonZeroU16 ,
1711
2020
Primitive = unsigned u16 ,
2021
+ rot = 4 ,
2022
+ rot_op = "0xa003" ,
2023
+ rot_result = "0x3a" ,
2024
+ swap_op = "0x1234" ,
2025
+ swapped = "0x3412" ,
2026
+ reversed = "0x2c48" ,
1712
2027
}
1713
2028
1714
2029
nonzero_integer ! {
1715
2030
Self = NonZeroU32 ,
1716
2031
Primitive = unsigned u32 ,
2032
+ rot = 8 ,
2033
+ rot_op = "0x10000b3" ,
2034
+ rot_result = "0xb301" ,
2035
+ swap_op = "0x12345678" ,
2036
+ swapped = "0x78563412" ,
2037
+ reversed = "0x1e6a2c48" ,
1717
2038
}
1718
2039
1719
2040
nonzero_integer ! {
1720
2041
Self = NonZeroU64 ,
1721
2042
Primitive = unsigned u64 ,
2043
+ rot = 12 ,
2044
+ rot_op = "0xaa00000000006e1" ,
2045
+ rot_result = "0x6e10aa" ,
2046
+ swap_op = "0x1234567890123456" ,
2047
+ swapped = "0x5634129078563412" ,
2048
+ reversed = "0x6a2c48091e6a2c48" ,
1722
2049
}
1723
2050
1724
2051
nonzero_integer ! {
1725
2052
Self = NonZeroU128 ,
1726
2053
Primitive = unsigned u128 ,
2054
+ rot = 16 ,
2055
+ rot_op = "0x13f40000000000000000000000004f76" ,
2056
+ rot_result = "0x4f7613f4" ,
2057
+ swap_op = "0x12345678901234567890123456789012" ,
2058
+ swapped = "0x12907856341290785634129078563412" ,
2059
+ reversed = "0x48091e6a2c48091e6a2c48091e6a2c48" ,
2060
+ }
2061
+
2062
+ #[ cfg( target_pointer_width = "16" ) ]
2063
+ nonzero_integer ! {
2064
+ Self = NonZeroUsize ,
2065
+ Primitive = unsigned usize ,
2066
+ rot = 4 ,
2067
+ rot_op = "0xa003" ,
2068
+ rot_result = "0x3a" ,
2069
+ swap_op = "0x1234" ,
2070
+ swapped = "0x3412" ,
2071
+ reversed = "0x2c48" ,
1727
2072
}
1728
2073
2074
+ #[ cfg( target_pointer_width = "32" ) ]
1729
2075
nonzero_integer ! {
1730
2076
Self = NonZeroUsize ,
1731
2077
Primitive = unsigned usize ,
2078
+ rot = 8 ,
2079
+ rot_op = "0x10000b3" ,
2080
+ rot_result = "0xb301" ,
2081
+ swap_op = "0x12345678" ,
2082
+ swapped = "0x78563412" ,
2083
+ reversed = "0x1e6a2c48" ,
2084
+ }
2085
+
2086
+ #[ cfg( target_pointer_width = "64" ) ]
2087
+ nonzero_integer ! {
2088
+ Self = NonZeroUsize ,
2089
+ Primitive = unsigned usize ,
2090
+ rot = 12 ,
2091
+ rot_op = "0xaa00000000006e1" ,
2092
+ rot_result = "0x6e10aa" ,
2093
+ swap_op = "0x1234567890123456" ,
2094
+ swapped = "0x5634129078563412" ,
2095
+ reversed = "0x6a2c48091e6a2c48" ,
1732
2096
}
1733
2097
1734
2098
nonzero_integer ! {
1735
2099
Self = NonZeroI8 ,
1736
2100
Primitive = signed i8 ,
1737
2101
UnsignedPrimitive = u8 ,
2102
+ rot = 2 ,
2103
+ rot_op = "-0x7e" ,
2104
+ rot_result = "0xa" ,
2105
+ swap_op = "0x12" ,
2106
+ swapped = "0x12" ,
2107
+ reversed = "0x48" ,
1738
2108
}
1739
2109
1740
2110
nonzero_integer ! {
1741
2111
Self = NonZeroI16 ,
1742
2112
Primitive = signed i16 ,
1743
2113
UnsignedPrimitive = u16 ,
2114
+ rot = 4 ,
2115
+ rot_op = "-0x5ffd" ,
2116
+ rot_result = "0x3a" ,
2117
+ swap_op = "0x1234" ,
2118
+ swapped = "0x3412" ,
2119
+ reversed = "0x2c48" ,
1744
2120
}
1745
2121
1746
2122
nonzero_integer ! {
1747
2123
Self = NonZeroI32 ,
1748
2124
Primitive = signed i32 ,
1749
2125
UnsignedPrimitive = u32 ,
2126
+ rot = 8 ,
2127
+ rot_op = "0x10000b3" ,
2128
+ rot_result = "0xb301" ,
2129
+ swap_op = "0x12345678" ,
2130
+ swapped = "0x78563412" ,
2131
+ reversed = "0x1e6a2c48" ,
1750
2132
}
1751
2133
1752
2134
nonzero_integer ! {
1753
2135
Self = NonZeroI64 ,
1754
2136
Primitive = signed i64 ,
1755
2137
UnsignedPrimitive = u64 ,
2138
+ rot = 12 ,
2139
+ rot_op = "0xaa00000000006e1" ,
2140
+ rot_result = "0x6e10aa" ,
2141
+ swap_op = "0x1234567890123456" ,
2142
+ swapped = "0x5634129078563412" ,
2143
+ reversed = "0x6a2c48091e6a2c48" ,
1756
2144
}
1757
2145
1758
2146
nonzero_integer ! {
1759
2147
Self = NonZeroI128 ,
1760
2148
Primitive = signed i128 ,
1761
2149
UnsignedPrimitive = u128 ,
2150
+ rot = 16 ,
2151
+ rot_op = "0x13f40000000000000000000000004f76" ,
2152
+ rot_result = "0x4f7613f4" ,
2153
+ swap_op = "0x12345678901234567890123456789012" ,
2154
+ swapped = "0x12907856341290785634129078563412" ,
2155
+ reversed = "0x48091e6a2c48091e6a2c48091e6a2c48" ,
2156
+ }
2157
+
2158
+ #[ cfg( target_pointer_width = "16" ) ]
2159
+ nonzero_integer ! {
2160
+ Self = NonZeroIsize ,
2161
+ Primitive = signed isize ,
2162
+ UnsignedPrimitive = usize ,
2163
+ rot = 4 ,
2164
+ rot_op = "-0x5ffd" ,
2165
+ rot_result = "0x3a" ,
2166
+ swap_op = "0x1234" ,
2167
+ swapped = "0x3412" ,
2168
+ reversed = "0x2c48" ,
2169
+ }
2170
+
2171
+ #[ cfg( target_pointer_width = "32" ) ]
2172
+ nonzero_integer ! {
2173
+ Self = NonZeroIsize ,
2174
+ Primitive = signed isize ,
2175
+ UnsignedPrimitive = usize ,
2176
+ rot = 8 ,
2177
+ rot_op = "0x10000b3" ,
2178
+ rot_result = "0xb301" ,
2179
+ swap_op = "0x12345678" ,
2180
+ swapped = "0x78563412" ,
2181
+ reversed = "0x1e6a2c48" ,
1762
2182
}
1763
2183
2184
+ #[ cfg( target_pointer_width = "64" ) ]
1764
2185
nonzero_integer ! {
1765
2186
Self = NonZeroIsize ,
1766
2187
Primitive = signed isize ,
1767
2188
UnsignedPrimitive = usize ,
2189
+ rot = 12 ,
2190
+ rot_op = "0xaa00000000006e1" ,
2191
+ rot_result = "0x6e10aa" ,
2192
+ swap_op = "0x1234567890123456" ,
2193
+ swapped = "0x5634129078563412" ,
2194
+ reversed = "0x6a2c48091e6a2c48" ,
1768
2195
}
0 commit comments