devela/num/primitive/
split.rs
1use crate::{paste, Cast};
11
12pub trait PrimitiveSplit<T, const LEN: usize> {
17 #[must_use]
19 fn into_array_be(self) -> [T; LEN];
20 #[must_use]
22 fn into_array_le(self) -> [T; LEN];
23 #[must_use]
25 fn into_array_ne(self) -> [T; LEN];
26}
27
28macro_rules! impl_into_trait {
30 ( $( $P:ident, $T:ident, $LEN:literal );+ $(;)? ) => {
31 $( impl_into_trait![@$P, $T, $LEN]; )+
32 };
33 (@$P:ident, $T:ident, $LEN:literal) => { paste! {
34 impl PrimitiveSplit<$T, $LEN> for $P {
35 fn into_array_be(self) -> [$T; $LEN] { Cast(self).[<into_ $T _be>]() }
36 fn into_array_le(self) -> [$T; $LEN] { Cast(self).[<into_ $T _le>]() }
37 fn into_array_ne(self) -> [$T; $LEN] { Cast(self).[<into_ $T _ne>]() }
38 }
39 }};
40}
41impl_into_trait![
42 u128, u64, 2; u128, u32, 4; u128, u16, 8; u128, u8, 16;
43 u64, u32, 2; u64, u16, 4; u64, u8, 8;
44 u32, u16, 2; u32, u8, 4;
45 u16, u8, 2;
46];
47
48#[rustfmt::skip]
51#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "split")))]
52impl Cast<u16> {
53 #[must_use]
55 pub const fn into_u8_be(self) -> [u8; 2] { self.0.to_be_bytes() }
56
57 #[must_use]
59 pub const fn into_u8_le(self) -> [u8; 2] { self.0.to_le_bytes() }
60
61 #[must_use]
63 pub const fn into_u8_ne(self) -> [u8; 2] { self.0.to_ne_bytes() }
64}
65
66#[rustfmt::skip]
67#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "split")))]
68impl Cast<u32> {
69 #[must_use]
71 pub const fn into_u16_be(self) -> [u16; 2] {
72 let v0: u16 = ((self.0 >> 16) & u16::MAX as u32) as u16;
73 let v1: u16 = (self.0 & u16::MAX as u32) as u16;
74 [v0, v1]
75 }
76
77 #[must_use]
79 pub const fn into_u16_le(self) -> [u16; 2] {
80 let v1: u16 = ((self.0 >> 16) & u16::MAX as u32) as u16;
81 let v0: u16 = (self.0 & u16::MAX as u32) as u16;
82 [v0, v1]
83 }
84
85 #[must_use]
87 pub const fn into_u16_ne(self) -> [u16; 2] {
88 if cfg!(target_endian = "big") {
89 Cast::<u32>::into_u16_be(self)
90 } else {
91 Cast::<u32>::into_u16_le(self)
92 }
93 }
94
95 #[must_use]
97 pub const fn into_u8_be(self) -> [u8; 4] { self.0.to_be_bytes() }
98
99 #[must_use]
101 pub const fn into_u8_le(self) -> [u8; 4] { self.0.to_le_bytes() }
102
103 #[must_use]
105 pub const fn into_u8_ne(self) -> [u8; 4] { self.0.to_ne_bytes() }
106}
107
108#[rustfmt::skip]
109#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "split")))]
110impl Cast<u64> {
111 #[must_use]
113 pub const fn into_u32_be(self) -> [u32; 2] {
114 let v0: u32 = ((self.0 >> 32) & u32::MAX as u64) as u32;
115 let v1: u32 = (self.0 & u32::MAX as u64) as u32;
116 [v0, v1]
117 }
118
119 #[must_use]
121 pub const fn into_u32_le(self) -> [u32; 2] {
122 let v1: u32 = ((self.0 >> 32) & u32::MAX as u64) as u32;
123 let v0: u32 = (self.0 & u32::MAX as u64) as u32;
124 [v0, v1]
125 }
126
127 #[must_use]
129 pub const fn into_u32_ne(self) -> [u32; 2] {
130 if cfg!(target_endian = "big") {
131 Cast::<u64>::into_u32_be(self)
132 } else {
133 Cast::<u64>::into_u32_le(self)
134 }
135 }
136
137 #[must_use]
139 pub const fn into_u16_be(self) -> [u16; 4] {
140 let v0: u16 = ((self.0 >> (16 * 3)) & u16::MAX as u64) as u16;
141 let v1: u16 = ((self.0 >> (16 * 2)) & u16::MAX as u64) as u16;
142 let v2: u16 = ((self.0 >> 16) & u16::MAX as u64) as u16;
143 let v3: u16 = (self.0 & u16::MAX as u64) as u16;
144 [v0, v1, v2, v3]
145 }
146
147 #[must_use]
149 pub const fn into_u16_le(self) -> [u16; 4] {
150 let v3: u16 = ((self.0 >> (16 * 3)) & u16::MAX as u64) as u16;
151 let v2: u16 = ((self.0 >> (16 * 2)) & u16::MAX as u64) as u16;
152 let v1: u16 = ((self.0 >> 16) & u16::MAX as u64) as u16;
153 let v0: u16 = (self.0 & u16::MAX as u64) as u16;
154 [v0, v1, v2, v3]
155 }
156
157 #[must_use]
159 pub const fn into_u16_ne(self) -> [u16; 4] {
160 if cfg!(target_endian = "big") {
161 Cast::<u64>::into_u16_be(self)
162 } else {
163 Cast::<u64>::into_u16_le(self)
164 }
165 }
166
167 #[must_use]
169 pub const fn into_u8_be(self) -> [u8; 8] { self.0.to_be_bytes() }
170
171 #[must_use]
173 pub const fn into_u8_le(self) -> [u8; 8] { self.0.to_le_bytes() }
174
175 #[must_use]
177 pub const fn into_u8_ne(self) -> [u8; 8] {
178 if cfg!(target_endian = "big") {
179 Cast::<u64>::into_u8_be(self)
180 } else {
181 Cast::<u64>::into_u8_le(self)
182 }
183 }
184}
185
186#[rustfmt::skip]
187#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "split")))]
188impl Cast<u128> {
189 #[must_use]
191 pub const fn into_u64_be(self) -> [u64; 2] {
192 let v0: u64 = (self.0 >> 64) as u64;
193 let v1: u64 = (self.0 & u64::MAX as u128) as u64;
194 [v0, v1]
195 }
196
197 #[must_use]
199 pub const fn into_u64_le(self) -> [u64; 2] {
200 let v1: u64 = (self.0 >> 64) as u64;
201 let v0: u64 = (self.0 & u64::MAX as u128) as u64;
202 [v0, v1]
203 }
204
205 #[must_use]
207 pub const fn into_u64_ne(self) -> [u64; 2] {
208 if cfg!(target_endian = "big") {
209 Cast::<u128>::into_u64_be(self)
210 } else {
211 Cast::<u128>::into_u64_le(self)
212 }
213 }
214
215 #[must_use]
217 pub const fn into_u32_be(self) -> [u32; 4] {
218 let v0: u32 = (self.0 >> (32 * 3)) as u32;
219 let v1: u32 = ((self.0 >> (32 * 2)) & u32::MAX as u128) as u32;
220 let v2: u32 = ((self.0 >> 32) & u32::MAX as u128) as u32;
221 let v3: u32 = (self.0 & u32::MAX as u128) as u32;
222 [v0, v1, v2, v3]
223 }
224
225 #[must_use]
227 pub const fn into_u32_le(self) -> [u32; 4] {
228 let v3: u32 = (self.0 >> (32 * 3)) as u32;
229 let v2: u32 = ((self.0 >> (32 * 2)) & u32::MAX as u128) as u32;
230 let v1: u32 = ((self.0 >> 32) & u32::MAX as u128) as u32;
231 let v0: u32 = (self.0 & u32::MAX as u128) as u32;
232 [v0, v1, v2, v3]
233 }
234
235 #[must_use]
237 pub const fn into_u32_ne(self) -> [u32; 4] {
238 if cfg!(target_endian = "big") {
239 Cast::<u128>::into_u32_be(self)
240 } else {
241 Cast::<u128>::into_u32_le(self)
242 }
243 }
244
245 #[must_use]
247 pub const fn into_u16_be(self) -> [u16; 8] {
248 let v0: u16 = (self.0 >> (16 * 7)) as u16;
249 let v1: u16 = ((self.0 >> (16 * 6)) & u16::MAX as u128) as u16;
250 let v2: u16 = ((self.0 >> (16 * 5)) & u16::MAX as u128) as u16;
251 let v3: u16 = ((self.0 >> (16 * 4)) & u16::MAX as u128) as u16;
252 let v4: u16 = ((self.0 >> (16 * 3)) & u16::MAX as u128) as u16;
253 let v5: u16 = ((self.0 >> (16 * 2)) & u16::MAX as u128) as u16;
254 let v6: u16 = ((self.0 >> 16) & u16::MAX as u128) as u16;
255 let v7: u16 = (self.0 & u16::MAX as u128) as u16;
256 [v0, v1, v2, v3, v4, v5, v6, v7]
257 }
258
259 #[must_use]
261 pub const fn into_u16_le(self) -> [u16; 8] {
262 let v7: u16 = (self.0 >> (16 * 7)) as u16;
263 let v6: u16 = ((self.0 >> (16 * 6)) & u16::MAX as u128) as u16;
264 let v5: u16 = ((self.0 >> (16 * 5)) & u16::MAX as u128) as u16;
265 let v4: u16 = ((self.0 >> (16 * 4)) & u16::MAX as u128) as u16;
266 let v3: u16 = ((self.0 >> (16 * 3)) & u16::MAX as u128) as u16;
267 let v2: u16 = ((self.0 >> (16 * 2)) & u16::MAX as u128) as u16;
268 let v1: u16 = ((self.0 >> 16) & u16::MAX as u128) as u16;
269 let v0: u16 = (self.0 & u16::MAX as u128) as u16;
270 [v0, v1, v2, v3, v4, v5, v6, v7]
271 }
272
273 #[must_use]
275 pub const fn into_u16_ne(self) -> [u16; 8] {
276 if cfg!(target_endian = "big") {
277 Cast::<u128>::into_u16_be(self)
278 } else {
279 Cast::<u128>::into_u16_le(self)
280 }
281 }
282
283 #[must_use]
285 pub const fn into_u8_be(self) -> [u8; 16] { self.0.to_be_bytes() }
286
287 #[must_use]
289 pub const fn into_u8_le(self) -> [u8; 16] { self.0.to_le_bytes() }
290
291 #[must_use]
293 pub const fn into_u8_ne(self) -> [u8; 16] { self.0.to_ne_bytes() }
294}