1#![no_std]
84#![cfg_attr(docsrs, feature(doc_auto_cfg))]
85#![warn(missing_docs)]
86#![warn(rust_2018_idioms)]
87
88#[macro_use]
89mod internal_macros;
90
91use core::cmp::Ordering;
92use core::iter::{Product, Sum};
93use core::num::TryFromIntError;
94use core::ops::{
95 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
96 Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
97};
98use core::{fmt, mem};
99
100#[cfg_attr(
116 feature = "bytemuck",
117 derive(bytemuck_derive::Zeroable, bytemuck_derive::Pod)
118)]
119#[cfg_attr(
120 feature = "zerocopy",
121 derive(
122 zerocopy_derive::KnownLayout,
123 zerocopy_derive::Immutable,
124 zerocopy_derive::FromBytes,
125 zerocopy_derive::IntoBytes,
126 )
127)]
128#[derive(Default, Hash, PartialEq, Eq, Clone, Copy)]
129#[repr(transparent)]
130pub struct Be<T>(pub T);
131
132#[cfg_attr(
148 feature = "bytemuck",
149 derive(bytemuck_derive::Zeroable, bytemuck_derive::Pod)
150)]
151#[cfg_attr(
152 feature = "zerocopy",
153 derive(
154 zerocopy_derive::KnownLayout,
155 zerocopy_derive::Immutable,
156 zerocopy_derive::FromBytes,
157 zerocopy_derive::IntoBytes,
158 )
159)]
160#[derive(Default, Hash, PartialEq, Eq, Clone, Copy)]
161#[repr(transparent)]
162pub struct Le<T>(pub T);
163
164macro_rules! impl_fmt {
165 (impl<T> $Trait:ident for Xe<T>) => {
166 impl_fmt!(impl<T> $Trait for Be<T>);
167 impl_fmt!(impl<T> $Trait for Le<T>);
168 };
169 (impl<T> $Trait:ident for $SelfT:ident<T>) => {
170 impl<T> fmt::$Trait for $SelfT<T>
171 where
172 Self: Copy + Into<T>,
173 T: fmt::$Trait,
174 {
175 #[inline]
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 (*self).into().fmt(f)
178 }
179 }
180 };
181}
182
183impl_fmt! { impl<T> Debug for Xe<T> }
184impl_fmt! { impl<T> Display for Xe<T> }
185impl_fmt! { impl<T> Binary for Xe<T> }
186impl_fmt! { impl<T> Octal for Xe<T> }
187impl_fmt! { impl<T> LowerHex for Xe<T> }
188impl_fmt! { impl<T> UpperHex for Xe<T> }
189impl_fmt! { impl<T> LowerExp for Xe<T> }
190impl_fmt! { impl<T> UpperExp for Xe<T> }
191
192macro_rules! unop_impl {
193 (impl $Trait:ident, $method:ident for $T:ty) => {
194 impl $Trait for $T {
195 type Output = Self;
196
197 #[inline]
198 #[track_caller]
199 fn $method(self) -> Self::Output {
200 Self::Output::from_ne($Trait::$method(self.to_ne()))
201 }
202 }
203 };
204}
205
206macro_rules! binop_impl {
207 (impl $Trait:ident<Self>, $method:ident for $T:ty) => {
208 impl $Trait<Self> for $T {
209 type Output = Self;
210
211 #[inline]
212 #[track_caller]
213 fn $method(self, rhs: Self) -> Self::Output {
214 Self::Output::from_ne($Trait::$method(self.to_ne(), rhs.to_ne()))
215 }
216 }
217 };
218 (impl $Trait:ident<$Rhs:ty>, $method:ident for $T:ty) => {
219 impl $Trait<$Rhs> for $T {
220 type Output = Self;
221
222 #[inline]
223 #[track_caller]
224 fn $method(self, rhs: $Rhs) -> Self::Output {
225 Self::Output::from_ne($Trait::$method(self.to_ne(), rhs))
226 }
227 }
228 };
229}
230
231macro_rules! op_assign_impl {
232 (impl $Trait:ident<$Rhs:ty>, $method:ident for $T:ty, $binop:path) => {
233 impl $Trait<$Rhs> for $T {
234 #[inline]
235 #[track_caller]
236 fn $method(&mut self, rhs: $Rhs) {
237 *self = $binop(*self, rhs);
238 }
239 }
240 };
241}
242
243macro_rules! endian_impl {
244 ($(Xe<$T:ty>)*) => {$(
245 endian_impl! { Be<$T> }
246 endian_impl! { Le<$T> }
247 )*};
248 ($($Xe:ident<$T:ty>)*) => {$(
249 impl PartialOrd for $Xe<$T> {
250 #[inline]
251 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
252 Some(self.cmp(rhs))
253 }
254 }
255
256 impl Ord for $Xe<$T> {
257 #[inline]
258 fn cmp(&self, rhs: &Self) -> Ordering {
259 Ord::cmp(&self.to_ne(), &rhs.to_ne())
260 }
261 }
262
263 unop_impl! { impl Not, not for $Xe<$T> }
264
265 forward_ref_unop! { impl Not, not for $Xe<$T> }
266
267 binop_impl! { impl Add<Self>, add for $Xe<$T> }
268 binop_impl! { impl BitAnd<Self>, bitand for $Xe<$T> }
269 binop_impl! { impl BitOr<Self>, bitor for $Xe<$T> }
270 binop_impl! { impl BitXor<Self>, bitxor for $Xe<$T> }
271 binop_impl! { impl Div<Self>, div for $Xe<$T> }
272 binop_impl! { impl Mul<Self>, mul for $Xe<$T> }
273 binop_impl! { impl Rem<Self>, rem for $Xe<$T> }
274 binop_impl! { impl Sub<Self>, sub for $Xe<$T> }
275
276 forward_ref_binop! { impl Add<$Xe<$T>>, add for $Xe<$T> }
277 forward_ref_binop! { impl BitAnd<$Xe<$T>>, bitand for $Xe<$T> }
278 forward_ref_binop! { impl BitOr<$Xe<$T>>, bitor for $Xe<$T> }
279 forward_ref_binop! { impl BitXor<$Xe<$T>>, bitxor for $Xe<$T> }
280 forward_ref_binop! { impl Div<$Xe<$T>>, div for $Xe<$T> }
281 forward_ref_binop! { impl Mul<$Xe<$T>>, mul for $Xe<$T> }
282 forward_ref_binop! { impl Rem<$Xe<$T>>, rem for $Xe<$T> }
283 forward_ref_binop! { impl Sub<$Xe<$T>>, sub for $Xe<$T> }
284
285 op_assign_impl! { impl AddAssign<Self>, add_assign for $Xe<$T>, Add::add }
286 op_assign_impl! { impl BitAndAssign<Self>, bitand_assign for $Xe<$T>, BitAnd::bitand }
287 op_assign_impl! { impl BitOrAssign<Self>, bitor_assign for $Xe<$T>, BitOr::bitor }
288 op_assign_impl! { impl BitXorAssign<Self>, bitxor_assign for $Xe<$T>, BitXor::bitxor }
289 op_assign_impl! { impl DivAssign<Self>, div_assign for $Xe<$T>, Div::div }
290 op_assign_impl! { impl MulAssign<Self>, mul_assign for $Xe<$T>, Mul::mul }
291 op_assign_impl! { impl RemAssign<Self>, rem_assign for $Xe<$T>, Rem::rem }
292 op_assign_impl! { impl SubAssign<Self>, sub_assign for $Xe<$T>, Sub::sub }
293
294 forward_ref_op_assign! { impl AddAssign<$Xe<$T>>, add_assign for $Xe<$T> }
295 forward_ref_op_assign! { impl BitAndAssign<$Xe<$T>>, bitand_assign for $Xe<$T> }
296 forward_ref_op_assign! { impl BitOrAssign<$Xe<$T>>, bitor_assign for $Xe<$T> }
297 forward_ref_op_assign! { impl BitXorAssign<$Xe<$T>>, bitxor_assign for $Xe<$T> }
298 forward_ref_op_assign! { impl DivAssign<$Xe<$T>>, div_assign for $Xe<$T> }
299 forward_ref_op_assign! { impl MulAssign<$Xe<$T>>, mul_assign for $Xe<$T> }
300 forward_ref_op_assign! { impl RemAssign<$Xe<$T>>, rem_assign for $Xe<$T> }
301 forward_ref_op_assign! { impl SubAssign<$Xe<$T>>, sub_assign for $Xe<$T> }
302
303 binop_impl! { impl Shl<u8>, shl for $Xe<$T> }
304 binop_impl! { impl Shl<u16>, shl for $Xe<$T> }
305 binop_impl! { impl Shl<u32>, shl for $Xe<$T> }
306 binop_impl! { impl Shl<u64>, shl for $Xe<$T> }
307 binop_impl! { impl Shl<u128>, shl for $Xe<$T> }
308 binop_impl! { impl Shl<usize>, shl for $Xe<$T> }
309 binop_impl! { impl Shl<i8>, shl for $Xe<$T> }
310 binop_impl! { impl Shl<i16>, shl for $Xe<$T> }
311 binop_impl! { impl Shl<i32>, shl for $Xe<$T> }
312 binop_impl! { impl Shl<i64>, shl for $Xe<$T> }
313 binop_impl! { impl Shl<i128>, shl for $Xe<$T> }
314 binop_impl! { impl Shl<isize>, shl for $Xe<$T> }
315
316 binop_impl! { impl Shr<u8>, shr for $Xe<$T> }
317 binop_impl! { impl Shr<u16>, shr for $Xe<$T> }
318 binop_impl! { impl Shr<u32>, shr for $Xe<$T> }
319 binop_impl! { impl Shr<u64>, shr for $Xe<$T> }
320 binop_impl! { impl Shr<u128>, shr for $Xe<$T> }
321 binop_impl! { impl Shr<usize>, shr for $Xe<$T> }
322 binop_impl! { impl Shr<i8>, shr for $Xe<$T> }
323 binop_impl! { impl Shr<i16>, shr for $Xe<$T> }
324 binop_impl! { impl Shr<i32>, shr for $Xe<$T> }
325 binop_impl! { impl Shr<i64>, shr for $Xe<$T> }
326 binop_impl! { impl Shr<i128>, shr for $Xe<$T> }
327 binop_impl! { impl Shr<isize>, shr for $Xe<$T> }
328
329 forward_ref_binop! { impl Shl<u8>, shl for $Xe<$T> }
330 forward_ref_binop! { impl Shl<u16>, shl for $Xe<$T> }
331 forward_ref_binop! { impl Shl<u32>, shl for $Xe<$T> }
332 forward_ref_binop! { impl Shl<u64>, shl for $Xe<$T> }
333 forward_ref_binop! { impl Shl<u128>, shl for $Xe<$T> }
334 forward_ref_binop! { impl Shl<usize>, shl for $Xe<$T> }
335 forward_ref_binop! { impl Shl<i8>, shl for $Xe<$T> }
336 forward_ref_binop! { impl Shl<i16>, shl for $Xe<$T> }
337 forward_ref_binop! { impl Shl<i32>, shl for $Xe<$T> }
338 forward_ref_binop! { impl Shl<i64>, shl for $Xe<$T> }
339 forward_ref_binop! { impl Shl<i128>, shl for $Xe<$T> }
340 forward_ref_binop! { impl Shl<isize>, shl for $Xe<$T> }
341
342 forward_ref_binop! { impl Shr<u8>, shr for $Xe<$T> }
343 forward_ref_binop! { impl Shr<u16>, shr for $Xe<$T> }
344 forward_ref_binop! { impl Shr<u32>, shr for $Xe<$T> }
345 forward_ref_binop! { impl Shr<u64>, shr for $Xe<$T> }
346 forward_ref_binop! { impl Shr<u128>, shr for $Xe<$T> }
347 forward_ref_binop! { impl Shr<usize>, shr for $Xe<$T> }
348 forward_ref_binop! { impl Shr<i8>, shr for $Xe<$T> }
349 forward_ref_binop! { impl Shr<i16>, shr for $Xe<$T> }
350 forward_ref_binop! { impl Shr<i32>, shr for $Xe<$T> }
351 forward_ref_binop! { impl Shr<i64>, shr for $Xe<$T> }
352 forward_ref_binop! { impl Shr<i128>, shr for $Xe<$T> }
353 forward_ref_binop! { impl Shr<isize>, shr for $Xe<$T> }
354
355 op_assign_impl! { impl ShlAssign<u8>, shl_assign for $Xe<$T>, Shl::shl }
356 op_assign_impl! { impl ShlAssign<u16>, shl_assign for $Xe<$T>, Shl::shl }
357 op_assign_impl! { impl ShlAssign<u32>, shl_assign for $Xe<$T>, Shl::shl }
358 op_assign_impl! { impl ShlAssign<u64>, shl_assign for $Xe<$T>, Shl::shl }
359 op_assign_impl! { impl ShlAssign<u128>, shl_assign for $Xe<$T>, Shl::shl }
360 op_assign_impl! { impl ShlAssign<usize>, shl_assign for $Xe<$T>, Shl::shl }
361 op_assign_impl! { impl ShlAssign<i8>, shl_assign for $Xe<$T>, Shl::shl }
362 op_assign_impl! { impl ShlAssign<i16>, shl_assign for $Xe<$T>, Shl::shl }
363 op_assign_impl! { impl ShlAssign<i32>, shl_assign for $Xe<$T>, Shl::shl }
364 op_assign_impl! { impl ShlAssign<i64>, shl_assign for $Xe<$T>, Shl::shl }
365 op_assign_impl! { impl ShlAssign<i128>, shl_assign for $Xe<$T>, Shl::shl }
366 op_assign_impl! { impl ShlAssign<isize>, shl_assign for $Xe<$T>, Shl::shl }
367
368 op_assign_impl! { impl ShrAssign<u8>, shr_assign for $Xe<$T>, Shr::shr }
369 op_assign_impl! { impl ShrAssign<u16>, shr_assign for $Xe<$T>, Shr::shr }
370 op_assign_impl! { impl ShrAssign<u32>, shr_assign for $Xe<$T>, Shr::shr }
371 op_assign_impl! { impl ShrAssign<u64>, shr_assign for $Xe<$T>, Shr::shr }
372 op_assign_impl! { impl ShrAssign<u128>, shr_assign for $Xe<$T>, Shr::shr }
373 op_assign_impl! { impl ShrAssign<usize>, shr_assign for $Xe<$T>, Shr::shr }
374 op_assign_impl! { impl ShrAssign<i8>, shr_assign for $Xe<$T>, Shr::shr }
375 op_assign_impl! { impl ShrAssign<i16>, shr_assign for $Xe<$T>, Shr::shr }
376 op_assign_impl! { impl ShrAssign<i32>, shr_assign for $Xe<$T>, Shr::shr }
377 op_assign_impl! { impl ShrAssign<i64>, shr_assign for $Xe<$T>, Shr::shr }
378 op_assign_impl! { impl ShrAssign<i128>, shr_assign for $Xe<$T>, Shr::shr }
379 op_assign_impl! { impl ShrAssign<isize>, shr_assign for $Xe<$T>, Shr::shr }
380
381 forward_ref_op_assign! { impl ShlAssign<u8>, shl_assign for $Xe<$T> }
382 forward_ref_op_assign! { impl ShlAssign<u16>, shl_assign for $Xe<$T> }
383 forward_ref_op_assign! { impl ShlAssign<u32>, shl_assign for $Xe<$T> }
384 forward_ref_op_assign! { impl ShlAssign<u64>, shl_assign for $Xe<$T> }
385 forward_ref_op_assign! { impl ShlAssign<u128>, shl_assign for $Xe<$T> }
386 forward_ref_op_assign! { impl ShlAssign<usize>, shl_assign for $Xe<$T> }
387 forward_ref_op_assign! { impl ShlAssign<i8>, shl_assign for $Xe<$T> }
388 forward_ref_op_assign! { impl ShlAssign<i16>, shl_assign for $Xe<$T> }
389 forward_ref_op_assign! { impl ShlAssign<i32>, shl_assign for $Xe<$T> }
390 forward_ref_op_assign! { impl ShlAssign<i64>, shl_assign for $Xe<$T> }
391 forward_ref_op_assign! { impl ShlAssign<i128>, shl_assign for $Xe<$T> }
392 forward_ref_op_assign! { impl ShlAssign<isize>, shl_assign for $Xe<$T> }
393
394 forward_ref_op_assign! { impl ShrAssign<u8>, shr_assign for $Xe<$T> }
395 forward_ref_op_assign! { impl ShrAssign<u16>, shr_assign for $Xe<$T> }
396 forward_ref_op_assign! { impl ShrAssign<u32>, shr_assign for $Xe<$T> }
397 forward_ref_op_assign! { impl ShrAssign<u64>, shr_assign for $Xe<$T> }
398 forward_ref_op_assign! { impl ShrAssign<u128>, shr_assign for $Xe<$T> }
399 forward_ref_op_assign! { impl ShrAssign<usize>, shr_assign for $Xe<$T> }
400 forward_ref_op_assign! { impl ShrAssign<i8>, shr_assign for $Xe<$T> }
401 forward_ref_op_assign! { impl ShrAssign<i16>, shr_assign for $Xe<$T> }
402 forward_ref_op_assign! { impl ShrAssign<i32>, shr_assign for $Xe<$T> }
403 forward_ref_op_assign! { impl ShrAssign<i64>, shr_assign for $Xe<$T> }
404 forward_ref_op_assign! { impl ShrAssign<i128>, shr_assign for $Xe<$T> }
405 forward_ref_op_assign! { impl ShrAssign<isize>, shr_assign for $Xe<$T> }
406 )*};
407}
408
409endian_impl! { Xe<u8> Xe<u16> Xe<u32> Xe<u64> Xe<u128> Xe<usize> Xe<i8> Xe<i16> Xe<i32> Xe<i64> Xe<i128> Xe<isize> }
410
411macro_rules! impl_from {
412 (Xe<$Small:ty> => Xe<$Large:ty>) => {
413 impl_from!(Be<$Small> => Be<$Large>);
414 impl_from!(Le<$Small> => Le<$Large>);
415 };
416 ($Small:ty => $Large:ty) => {
417 impl From<$Small> for $Large {
418 #[doc = concat!("Converts [`", stringify!($Small), "`] to [`", stringify!($Large), "`] losslessly.")]
419 #[inline]
420 fn from(small: $Small) -> Self {
421 Self::from_ne(small.to_ne().into())
422 }
423 }
424 };
425}
426
427impl_from!(Xe<u8> => Xe<u16>);
429impl_from!(Xe<u8> => Xe<u32>);
430impl_from!(Xe<u8> => Xe<u64>);
431impl_from!(Xe<u8> => Xe<u128>);
432impl_from!(Xe<u8> => Xe<usize>);
433impl_from!(Xe<u16> => Xe<u32>);
434impl_from!(Xe<u16> => Xe<u64>);
435impl_from!(Xe<u16> => Xe<u128>);
436impl_from!(Xe<u32> => Xe<u64>);
437impl_from!(Xe<u32> => Xe<u128>);
438impl_from!(Xe<u64> => Xe<u128>);
439
440impl_from!(Xe<i8> => Xe<i16>);
442impl_from!(Xe<i8> => Xe<i32>);
443impl_from!(Xe<i8> => Xe<i64>);
444impl_from!(Xe<i8> => Xe<i128>);
445impl_from!(Xe<i8> => Xe<isize>);
446impl_from!(Xe<i16> => Xe<i32>);
447impl_from!(Xe<i16> => Xe<i64>);
448impl_from!(Xe<i16> => Xe<i128>);
449impl_from!(Xe<i32> => Xe<i64>);
450impl_from!(Xe<i32> => Xe<i128>);
451impl_from!(Xe<i64> => Xe<i128>);
452
453impl_from!(Xe<u8> => Xe<i16>);
455impl_from!(Xe<u8> => Xe<i32>);
456impl_from!(Xe<u8> => Xe<i64>);
457impl_from!(Xe<u8> => Xe<i128>);
458impl_from!(Xe<u16> => Xe<i32>);
459impl_from!(Xe<u16> => Xe<i64>);
460impl_from!(Xe<u16> => Xe<i128>);
461impl_from!(Xe<u32> => Xe<i64>);
462impl_from!(Xe<u32> => Xe<i128>);
463impl_from!(Xe<u64> => Xe<i128>);
464
465impl_from!(Xe<u16> => Xe<usize>);
469impl_from!(Xe<u8> => Xe<isize>);
470impl_from!(Xe<i16> => Xe<isize>);
471
472macro_rules! impl_try_from {
473 (Xe<$source:ty> => $(Xe<$target:ty>),+) => {$(
474 impl_try_from!(Be<$source> => Be<$target>);
475 impl_try_from!(Le<$source> => Le<$target>);
476 )*};
477 ($Xe:ident<$source:ty> => $Xe2:ident<$target:ty>) => {
478 impl TryFrom<$Xe<$source>> for $Xe<$target> {
479 type Error = TryFromIntError;
480
481 #[inline]
485 fn try_from(u: $Xe<$source>) -> Result<Self, Self::Error> {
486 <$target>::try_from(u.to_ne()).map(Self::from_ne)
487 }
488 }
489 };
490}
491
492impl_try_from!(Xe<u16> => Xe<u8>);
494impl_try_from!(Xe<u32> => Xe<u8>, Xe<u16>);
495impl_try_from!(Xe<u64> => Xe<u8>, Xe<u16>, Xe<u32>);
496impl_try_from!(Xe<u128> => Xe<u8>, Xe<u16>, Xe<u32>, Xe<u64>);
497
498impl_try_from!(Xe<i16> => Xe<i8>);
500impl_try_from!(Xe<i32> => Xe<i8>, Xe<i16>);
501impl_try_from!(Xe<i64> => Xe<i8>, Xe<i16>, Xe<i32>);
502impl_try_from!(Xe<i128> => Xe<i8>, Xe<i16>, Xe<i32>, Xe<i64>);
503
504impl_try_from!(Xe<u8> => Xe<i8>);
506impl_try_from!(Xe<u16> => Xe<i8>, Xe<i16>);
507impl_try_from!(Xe<u32> => Xe<i8>, Xe<i16>, Xe<i32>);
508impl_try_from!(Xe<u64> => Xe<i8>, Xe<i16>, Xe<i32>, Xe<i64>);
509impl_try_from!(Xe<u128> => Xe<i8>, Xe<i16>, Xe<i32>, Xe<i64>, Xe<i128>);
510
511impl_try_from!(Xe<i8> => Xe<u8>, Xe<u16>, Xe<u32>, Xe<u64>, Xe<u128>);
513impl_try_from!(Xe<i16> => Xe<u8>);
514impl_try_from!(Xe<i16> => Xe<u16>, Xe<u32>, Xe<u64>, Xe<u128>);
515impl_try_from!(Xe<i32> => Xe<u8>, Xe<u16>);
516impl_try_from!(Xe<i32> => Xe<u32>, Xe<u64>, Xe<u128>);
517impl_try_from!(Xe<i64> => Xe<u8>, Xe<u16>, Xe<u32>);
518impl_try_from!(Xe<i64> => Xe<u64>, Xe<u128>);
519impl_try_from!(Xe<i128> => Xe<u8>, Xe<u16>, Xe<u32>, Xe<u64>);
520impl_try_from!(Xe<i128> => Xe<u128>);
521
522impl_try_from!(Xe<usize> => Xe<isize>);
524impl_try_from!(Xe<isize> => Xe<usize>);
525
526macro_rules! impl_sum_product {
527 ($(Xe<$T:ty>)*) => {$(
528 impl_sum_product!(Be<$T>);
529 impl_sum_product!(Le<$T>);
530 )*};
531 ($Xe:ty) => (
532 impl Sum for $Xe {
533 fn sum<I: Iterator<Item=Self>>(iter: I) -> Self {
534 iter.fold(<$Xe>::from_ne(0), |a, b| a + b)
535 }
536 }
537
538 impl Product for $Xe {
539 fn product<I: Iterator<Item=Self>>(iter: I) -> Self {
540 iter.fold(<$Xe>::from_ne(1), |a, b| a * b)
541 }
542 }
543
544 impl<'a> Sum<&'a $Xe> for $Xe {
545 fn sum<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
546 iter.fold(<$Xe>::from_ne(0), |a, b| a + b)
547 }
548 }
549
550 impl<'a> Product<&'a $Xe> for $Xe {
551 fn product<I: Iterator<Item=&'a Self>>(iter: I) -> Self {
552 iter.fold(<$Xe>::from_ne(1), |a, b| a * b)
553 }
554 }
555 );
556}
557
558impl_sum_product! { Xe<i8> Xe<i16> Xe<i32> Xe<i64> Xe<i128> Xe<isize> Xe<u8> Xe<u16> Xe<u32> Xe<u64> Xe<u128> Xe<usize> }
559
560#[cfg(target_pointer_width = "16")]
561macro_rules! usize_macro {
562 ($macro:ident) => {
563 $macro!(u16)
564 };
565}
566
567#[cfg(target_pointer_width = "32")]
568macro_rules! usize_macro {
569 ($macro:ident) => {
570 $macro!(u32)
571 };
572}
573
574#[cfg(target_pointer_width = "64")]
575macro_rules! usize_macro {
576 ($macro:ident) => {
577 $macro!(u64)
578 };
579}
580
581#[rustfmt::skip]
582macro_rules! rot {
583 (u8) => { 2 };
584 (u16) => { 4 };
585 (u32) => { 8 };
586 (u64) => { 12 };
587 (u128) => { 16 };
588 (usize) => { usize_macro!(rot) };
589 (i8) => { rot!(u8) };
590 (i16) => { rot!(u16) };
591 (i32) => { rot!(u32) };
592 (i64) => { rot!(u64) };
593 (i128) => { rot!(u128) };
594 (isize) => { rot!(usize) };
595}
596
597#[rustfmt::skip]
598macro_rules! rot_op {
599 (u8) => { "0x82" };
600 (u16) => { "0xa003" };
601 (u32) => { "0x10000b3" };
602 (u64) => { "0xaa00000000006e1" };
603 (u128) => { "0x13f40000000000000000000000004f76" };
604 (usize) => { usize_macro!(rot_op) };
605 (i8) => { "-0x7e" };
606 (i16) => { "-0x5ffd" };
607 (i32) => { rot_op!(u32) };
608 (i64) => { rot_op!(u64) };
609 (i128) => { rot_op!(u128) };
610 (isize) => { rot_op!(usize) };
611}
612
613#[rustfmt::skip]
614macro_rules! rot_result {
615 (u8) => { "0xa" };
616 (u16) => { "0x3a" };
617 (u32) => { "0xb301" };
618 (u64) => { "0x6e10aa" };
619 (u128) => { "0x4f7613f4" };
620 (usize) => { usize_macro!(rot_result) };
621 (i8) => { rot_result!(u8) };
622 (i16) => { rot_result!(u16) };
623 (i32) => { rot_result!(u32) };
624 (i64) => { rot_result!(u64) };
625 (i128) => { rot_result!(u128) };
626 (isize) => { rot_result!(usize) };
627}
628
629#[rustfmt::skip]
630macro_rules! swap_op {
631 (u8) => { "0x12" };
632 (u16) => { "0x1234" };
633 (u32) => { "0x12345678" };
634 (u64) => { "0x1234567890123456" };
635 (u128) => { "0x12345678901234567890123456789012" };
636 (usize) => { usize_macro!(swap_op) };
637 (i8) => { swap_op!(u8) };
638 (i16) => { swap_op!(u16) };
639 (i32) => { swap_op!(u32) };
640 (i64) => { swap_op!(u64) };
641 (i128) => { swap_op!(u128) };
642 (isize) => { swap_op!(usize) };
643}
644
645#[rustfmt::skip]
646macro_rules! swapped {
647 (u8) => { "0x12" };
648 (u16) => { "0x3412" };
649 (u32) => { "0x78563412" };
650 (u64) => { "0x5634129078563412" };
651 (u128) => { "0x12907856341290785634129078563412" };
652 (usize) => { usize_macro!(swapped) };
653 (i8) => { swapped!(u8) };
654 (i16) => { swapped!(u16) };
655 (i32) => { swapped!(u32) };
656 (i64) => { swapped!(u64) };
657 (i128) => { swapped!(u128) };
658 (isize) => { swapped!(usize) };
659}
660
661#[rustfmt::skip]
662macro_rules! reversed {
663 (u8) => { "0x48" };
664 (u16) => { "0x2c48" };
665 (u32) => { "0x1e6a2c48" };
666 (u64) => { "0x6a2c48091e6a2c48" };
667 (u128) => { "0x48091e6a2c48091e6a2c48091e6a2c48" };
668 (usize) => { usize_macro!(reversed) };
669 (i8) => { reversed!(u8) };
670 (i16) => { reversed!(u16) };
671 (i32) => { reversed!(u32) };
672 (i64) => { reversed!(u64) };
673 (i128) => { reversed!(u128) };
674 (isize) => { reversed!(usize) };
675}
676
677macro_rules! be_bytes {
678 (u8) => { "[0x12]" };
679 (u16) => { "[0x12, 0x34]" };
680 (u32) => { "[0x12, 0x34, 0x56, 0x78]" };
681 (u64) => { "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" };
682 (u128) => { "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]" };
683 (usize) => { usize_macro!(be_bytes) };
684 (i8) => { be_bytes!(u8) };
685 (i16) => { be_bytes!(u16) };
686 (i32) => { be_bytes!(u32) };
687 (i64) => { be_bytes!(u64) };
688 (i128) => { be_bytes!(u128) };
689 (isize) => { be_bytes!(usize) };
690}
691
692macro_rules! le_bytes {
693 (u8) => { "[0x12]" };
694 (u16) => { "[0x34, 0x12]" };
695 (u32) => { "[0x78, 0x56, 0x34, 0x12]" };
696 (u64) => { "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]" };
697 (u128) => { "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]" };
698 (usize) => { usize_macro!(le_bytes) };
699 (i8) => { le_bytes!(u8) };
700 (i16) => { le_bytes!(u16) };
701 (i32) => { le_bytes!(u32) };
702 (i64) => { le_bytes!(u64) };
703 (i128) => { le_bytes!(u128) };
704 (isize) => { le_bytes!(usize) };
705}
706
707macro_rules! endian_int_impl {
708 ($(Xe<$T:ident>)*) => {$(
709 endian_int_impl! { Be<$T>, from_be, to_be, "big", Le, from_le, to_le, "little" }
710 endian_int_impl! { Le<$T>, from_le, to_le, "little", Be, from_be, to_be, "big" }
711 )*};
712 ($Xe:ident<$T:ident>, $from_xe:ident, $to_xe:ident, $order:literal, $Other:ident, $from_other:ident, $to_other:ident, $order_other:literal) => {
713 impl $Xe<$T> {
714 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
722 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::MIN, ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", stringify!($T), "::MIN));")]
724 pub const MIN: Self = Self::from_ne(<$T>::MIN);
726
727 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
735 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::MAX, ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", stringify!($T), "::MAX));")]
737 pub const MAX: Self = Self::from_ne(<$T>::MAX);
739
740 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
748 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::BITS, ", stringify!($T), "::BITS);")]
750 pub const BITS: u32 = <$T>::BITS;
752
753 #[doc = concat!("Creates a new ", $order, "-endian integer from a native-endian integer.")]
754 #[doc = concat!("On ", $order, " endian, this is a no-op. On ", $order_other, " endian, the bytes are swapped.")]
756 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
763 #[doc = concat!("let n = 0x1A", stringify!($T), ";")]
765 #[doc = concat!("if cfg!(target_endian = \"", $order, "\") {")]
767 #[doc = concat!(" assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(n).0, n);")]
768 #[doc = concat!(" assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(n).0, n.swap_bytes());")]
770 #[must_use]
773 #[inline]
774 pub const fn from_ne(n: $T) -> Self {
775 Self(n.$to_xe())
776 }
777
778 #[doc = concat!("Creates a new ", $order, "-endian integer from a ", $order_other, "-endian integer.")]
779 #[doc = concat!("use endian_num::{Be, Le};")]
786 #[doc = concat!("let n = 0x1A", stringify!($T), ";")]
788 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::", stringify!($from_other), "(", stringify!($Other), "(n)).0, n.swap_bytes());")]
790 #[must_use]
792 #[inline]
793 pub const fn $from_other(n: $Other<$T>) -> Self {
794 Self(n.0.swap_bytes())
795 }
796
797 #[doc = concat!("On ", $order, " endian, this is a no-op. On ", $order_other, " endian, the bytes are swapped.")]
800 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
807 #[doc = concat!("let n = 0x1A", stringify!($T), ";")]
809 #[doc = concat!("if cfg!(target_endian = \"", $order, "\") {")]
811 #[doc = concat!(" assert_eq!(", stringify!($Xe), "(n).to_ne(), n);")]
812 #[doc = concat!(" assert_eq!(", stringify!($Xe), "(n).to_ne(), n.swap_bytes());")]
814 #[must_use = "this returns the result of the operation, \
817 without modifying the original"]
818 #[inline]
819 pub const fn to_ne(self) -> $T {
820 <$T>::$from_xe(self.0)
821 }
822
823 #[doc = concat!("Returns the integer in ", $order_other, "-endian byte order.")]
824 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
833 #[doc = concat!("let n = 0x1A", stringify!($T), ";")]
835 #[doc = concat!("assert_eq!(", stringify!($Xe), "(n).", stringify!($to_other), "().0, n.swap_bytes());")]
837 #[must_use = "this returns the result of the operation, \
839 without modifying the original"]
840 #[inline]
841 pub const fn $to_other(self) -> $Other<$T> {
842 $Other(self.0.swap_bytes())
843 }
844
845 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
851 #[doc = concat!("let bytes = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", swap_op!($T), ").to_be_bytes();")]
853 #[doc = concat!("assert_eq!(bytes, ", be_bytes!($T), ");")]
854 #[must_use = "this returns the result of the operation, \
856 without modifying the original"]
857 #[inline]
858 pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
859 self.to_ne().to_be_bytes()
860 }
861
862 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
868 #[doc = concat!("let bytes = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", swap_op!($T), ").to_le_bytes();")]
870 #[doc = concat!("assert_eq!(bytes, ", le_bytes!($T), ");")]
871 #[must_use = "this returns the result of the operation, \
873 without modifying the original"]
874 #[inline]
875 pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
876 self.to_ne().to_le_bytes()
877 }
878
879 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
893 #[doc = concat!("let bytes = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", swap_op!($T), ").to_ne_bytes();")]
895 #[doc = concat!(" ", be_bytes!($T))]
899 #[doc = concat!(" ", le_bytes!($T))]
901 #[must_use = "this returns the result of the operation, \
905 without modifying the original"]
906 #[inline]
907 pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
908 self.to_ne().to_ne_bytes()
909 }
910
911 #[doc = concat!("Create a ", $order, " endian integer value from its representation as a byte array in ", $order, " endian.")]
912 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
917 #[doc = concat!("let value = ", stringify!($Xe), "::<", stringify!($T), ">::from_be_bytes(", be_bytes!($T), ");")]
919 #[doc = concat!("assert_eq!(value.to_ne(), ", swap_op!($T), ");")]
920 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
926 #[doc = concat!("fn read_be_", stringify!($T), "(input: &mut &[u8]) -> ", stringify!($Xe), "<", stringify!($T), "> {")]
928 #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($Xe), "<", stringify!($T), ">>());")]
929 #[doc = concat!(" ", stringify!($Xe), "::<", stringify!($T), ">::from_be_bytes(int_bytes.try_into().unwrap())")]
931 #[must_use]
934 #[inline]
935 pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
936 Self::from_ne(<$T>::from_be_bytes(bytes))
937 }
938
939 #[doc = concat!("Create a ", $order, " endian integer value from its representation as a byte array in ", $order_other, " endian.")]
940 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
945 #[doc = concat!("let value = ", stringify!($Xe), "::<", stringify!($T), ">::from_le_bytes(", le_bytes!($T), ");")]
947 #[doc = concat!("assert_eq!(value.to_ne(), ", swap_op!($T), ");")]
948 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
954 #[doc = concat!("fn read_le_", stringify!($T), "(input: &mut &[u8]) -> ", stringify!($Xe), "<", stringify!($T), "> {")]
956 #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($Xe), "<", stringify!($T), ">>());")]
957 #[doc = concat!(" ", stringify!($Xe), "::<", stringify!($T), ">::from_le_bytes(int_bytes.try_into().unwrap())")]
959 #[must_use]
962 #[inline]
963 pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
964 Self::from_ne(<$T>::from_le_bytes(bytes))
965 }
966
967 #[doc = concat!("Create a ", $order, " endian integer value from its memory representation as a byte array in native endianness.")]
968 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
980 #[doc = concat!("let value = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne_bytes(if cfg!(target_endian = \"big\") {")]
982 #[doc = concat!(" ", be_bytes!($T))]
983 #[doc = concat!(" ", le_bytes!($T))]
985 #[doc = concat!("assert_eq!(value.to_ne(), ", swap_op!($T), ");")]
987 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
993 #[doc = concat!("fn read_ne_", stringify!($T), "(input: &mut &[u8]) -> ", stringify!($Xe), "<", stringify!($T), "> {")]
995 #[doc = concat!(" let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($Xe), "<", stringify!($T), ">>());")]
996 #[doc = concat!(" ", stringify!($Xe), "::<", stringify!($T), ">::from_ne_bytes(int_bytes.try_into().unwrap())")]
998 #[must_use]
1001 #[inline]
1002 pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
1003 Self::from_ne(<$T>::from_ne_bytes(bytes))
1004 }
1005
1006 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1017 #[doc = concat!("let n = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", rot_op!($T), ");")]
1019 #[doc = concat!("let m = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", rot_result!($T), ");")]
1020 #[doc = concat!("assert_eq!(n.rotate_left(", rot!($T), "), m);")]
1022 #[must_use = "this returns the result of the operation, \
1024 without modifying the original"]
1025 #[inline]
1026 pub const fn rotate_left(self, n: u32) -> Self {
1027 Self::from_ne(self.to_ne().rotate_left(n))
1028 }
1029
1030 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1042 #[doc = concat!("let n = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", rot_result!($T), ");")]
1044 #[doc = concat!("let m = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", rot_op!($T), ");")]
1045 #[doc = concat!("assert_eq!(n.rotate_right(", rot!($T), "), m);")]
1047 #[must_use = "this returns the result of the operation, \
1049 without modifying the original"]
1050 #[inline]
1051 pub const fn rotate_right(self, n: u32) -> Self {
1052 Self::from_ne(self.to_ne().rotate_right(n))
1053 }
1054
1055 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1063 #[doc = concat!("let n = ", stringify!($Xe), "(", swap_op!($T), stringify!($T), ");")]
1065 #[doc = concat!("assert_eq!(m, ", stringify!($Xe), "(", swapped!($T), "));")]
1068 #[must_use = "this returns the result of the operation, \
1070 without modifying the original"]
1071 #[inline]
1072 pub const fn swap_bytes(self) -> Self {
1073 Self(self.0.swap_bytes())
1074 }
1075
1076 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1087 #[doc = concat!("let n = ", stringify!($Xe), "(", swap_op!($T), stringify!($T), ");")]
1089 #[doc = concat!("assert_eq!(m, ", stringify!($Xe), "(", reversed!($T), "));")]
1092 #[doc = concat!("assert_eq!(", stringify!($Xe), "(0), ", stringify!($Xe), "(0", stringify!($T), ").reverse_bits());")]
1093 #[must_use = "this returns the result of the operation, \
1095 without modifying the original"]
1096 #[inline]
1097 pub const fn reverse_bits(self) -> Self {
1098 Self(self.0.reverse_bits())
1099 }
1100
1101 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1109 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(2).pow(5).to_ne(), 32);")]
1111 #[must_use = "this returns the result of the operation, \
1113 without modifying the original"]
1114 #[inline]
1115 pub const fn pow(self, exp: u32) -> Self {
1116 Self::from_ne(self.to_ne().pow(exp))
1117 }
1118 }
1119
1120 impl From<$T> for $Xe<$T> {
1121 #[inline]
1122 fn from(value: $T) -> Self {
1123 Self::from_ne(value)
1124 }
1125 }
1126
1127 impl From<$Xe<$T>> for $T {
1128 #[inline]
1129 fn from(value: $Xe<$T>) -> Self {
1130 value.to_ne()
1131 }
1132 }
1133
1134 impl From<$Other<$T>> for $Xe<$T> {
1135 #[inline]
1136 fn from(value: $Other<$T>) -> Self {
1137 Self::$from_other(value)
1138 }
1139 }
1140
1141 #[cfg(feature = "bitflags")]
1142 impl bitflags::Bits for $Xe<$T> {
1143 const EMPTY: Self = Self::MIN;
1144
1145 const ALL: Self = Self::MAX;
1146 }
1147
1148 #[cfg(feature = "bitflags")]
1149 impl bitflags::parser::ParseHex for $Xe<$T>
1150 {
1151 fn parse_hex(input: &str) -> Result<Self, bitflags::parser::ParseError> {
1152 <$T>::parse_hex(input).map($Xe::<$T>::from_ne)
1153 }
1154 }
1155
1156 #[cfg(feature = "bitflags")]
1157 impl bitflags::parser::WriteHex for $Xe<$T>
1158 {
1159 fn write_hex<W: fmt::Write>(&self, writer: W) -> fmt::Result {
1160 self.to_ne().write_hex(writer)
1161 }
1162 }
1163 };
1164}
1165
1166endian_int_impl! { Xe<u8> Xe<u16> Xe<u32> Xe<u64> Xe<u128> Xe<usize> Xe<i8> Xe<i16> Xe<i32> Xe<i64> Xe<i128> Xe<isize> }
1167
1168macro_rules! endian_int_impl_signed {
1169 ($(Xe<$T:ty>)*) => {$(
1170 endian_int_impl_signed! { Be<$T> }
1171 endian_int_impl_signed! { Le<$T> }
1172 )*};
1173 ($Xe:ident<$T:ty>) => {
1174 unop_impl! { impl Neg, neg for $Xe<$T> }
1175 forward_ref_unop! { impl Neg, neg for $Xe<$T> }
1176
1177 impl $Xe<$T> {
1178 #[doc = concat!("See [`", stringify!($T), "::abs`]")]
1181 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1189 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(10).abs(), ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(10));")]
1191 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(-10).abs(), ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(10));")]
1192 #[must_use = "this returns the result of the operation, \
1194 without modifying the original"]
1195 #[inline]
1196 pub const fn abs(self) -> Self {
1197 Self::from_ne(self.to_ne().abs())
1198 }
1199
1200 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1212 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(10).signum().to_ne(), 1);")]
1214 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(0).signum().to_ne(), 0);")]
1215 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(-10).signum().to_ne(), -1);")]
1216 #[must_use = "this returns the result of the operation, \
1218 without modifying the original"]
1219 #[inline]
1220 pub const fn signum(self) -> Self {
1221 Self::from_ne(self.to_ne().signum())
1222 }
1223
1224 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1233 #[doc = concat!("assert!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(10).is_positive());")]
1235 #[doc = concat!("assert!(!", stringify!($Xe), "::<", stringify!($T), ">::from_ne(-10).is_positive());")]
1236 #[must_use]
1238 #[inline]
1239 pub const fn is_positive(self) -> bool {
1240 self.to_ne().is_positive()
1241 }
1242
1243 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1252 #[doc = concat!("assert!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(-10).is_negative());")]
1254 #[doc = concat!("assert!(!", stringify!($Xe), "::<", stringify!($T), ">::from_ne(10).is_negative());")]
1255 #[must_use]
1257 #[inline]
1258 pub const fn is_negative(self) -> bool {
1259 self.to_ne().is_negative()
1260 }
1261
1262 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1270 #[doc = concat!("let n = ", stringify!($Xe), "(0b100_0000", stringify!($T), ");")]
1272 #[doc(alias = "popcount")]
1276 #[doc(alias = "popcnt")]
1277 #[must_use = "this returns the result of the operation, \
1278 without modifying the original"]
1279 #[inline]
1280 pub const fn count_ones(self) -> u32 {
1281 self.0.count_ones()
1282 }
1283
1284 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1292 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::MAX.count_zeros(), 1);")]
1294 #[must_use = "this returns the result of the operation, \
1296 without modifying the original"]
1297 #[inline]
1298 pub const fn count_zeros(self) -> u32 {
1299 self.0.count_zeros()
1300 }
1301
1302 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1310 #[doc = concat!("let n = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(-1);")]
1312 #[must_use = "this returns the result of the operation, \
1316 without modifying the original"]
1317 #[inline]
1318 pub const fn leading_zeros(self) -> u32 {
1319 self.to_ne().leading_zeros()
1320 }
1321
1322 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1330 #[doc = concat!("let n = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(-4);")]
1332 #[must_use = "this returns the result of the operation, \
1336 without modifying the original"]
1337 #[inline]
1338 pub const fn trailing_zeros(self) -> u32 {
1339 self.to_ne().trailing_zeros()
1340 }
1341 }
1342 };
1343}
1344
1345endian_int_impl_signed! { Xe<i8> Xe<i16> Xe<i32> Xe<i64> Xe<i128> Xe<isize> }
1346
1347macro_rules! endian_int_impl_unsigned {
1348 ($(Xe<$T:ty>)*) => {$(
1349 endian_int_impl_unsigned! { Be<$T> }
1350 endian_int_impl_unsigned! { Le<$T> }
1351 )*};
1352 ($Xe:ident<$T:ty>) => {
1353 impl $Xe<$T> {
1354 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1362 #[doc = concat!("let n = ", stringify!($Xe), "(0b01001100", stringify!($T), ");")]
1364 #[doc(alias = "popcount")]
1368 #[doc(alias = "popcnt")]
1369 #[must_use = "this returns the result of the operation, \
1370 without modifying the original"]
1371 #[inline]
1372 pub const fn count_ones(self) -> u32 {
1373 self.0.count_ones()
1374 }
1375
1376 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1384 #[doc = concat!("assert_eq!(", stringify!($Xe), "::<", stringify!($T), ">::MAX.count_zeros(), 0);")]
1386 #[must_use = "this returns the result of the operation, \
1388 without modifying the original"]
1389 #[inline]
1390 pub const fn count_zeros(self) -> u32 {
1391 self.0.count_zeros()
1392 }
1393
1394 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1402 #[doc = concat!("let n = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(", stringify!($T), "::MAX >> 2);")]
1404 #[must_use = "this returns the result of the operation, \
1408 without modifying the original"]
1409 #[inline]
1410 pub const fn leading_zeros(self) -> u32 {
1411 self.to_ne().leading_zeros()
1412 }
1413
1414 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1422 #[doc = concat!("let n = ", stringify!($Xe), "::<", stringify!($T), ">::from_ne(0b0101000);")]
1424 #[must_use = "this returns the result of the operation, \
1428 without modifying the original"]
1429 #[inline]
1430 pub const fn trailing_zeros(self) -> u32 {
1431 self.to_ne().trailing_zeros()
1432 }
1433
1434 #[doc = concat!("use endian_num::", stringify!($Xe), ";")]
1442 #[doc = concat!("assert!(", stringify!($Xe), "::<", stringify!($T), ">::from_ne(16).is_power_of_two());")]
1444 #[doc = concat!("assert!(!", stringify!($Xe), "::<", stringify!($T), ">::from_ne(10).is_power_of_two());")]
1445 #[must_use = "this returns the result of the operation, \
1447 without modifying the original"]
1448 #[inline]
1449 pub const fn is_power_of_two(self) -> bool {
1450 self.to_ne().is_power_of_two()
1451 }
1452 }
1453 };
1454}
1455
1456endian_int_impl_unsigned! { Xe<u8> Xe<u16> Xe<u32> Xe<u64> Xe<u128> Xe<usize> }
1457
1458macro_rules! impl_from_array {
1459 (Xe<$Large:ty>, [Xe<$Small:ty>; $i:literal]) => {
1460 impl_from_array!(Be<$Large>, [Be<$Small>; $i], "big");
1461 impl_from_array!(Le<$Large>, [Le<$Small>; $i], "little");
1462 };
1463 ($Large:ty, [$Small:ty; $i:literal], $order:literal) => {
1464 impl From<[$Small; $i]> for $Large {
1465 #[doc = concat!("Create an integer from its representation as a [`", stringify!($Small), "`] array in ", $order, " endian.")]
1466 #[inline]
1467 fn from(value: [$Small; $i]) -> Self {
1468 unsafe { mem::transmute(value) }
1470 }
1471 }
1472
1473 impl From<$Large> for [$Small; $i] {
1474 #[doc = concat!("Return the memory representation of this integer as a [`", stringify!($Small), "`] array in ", $order, "-endian byte order.")]
1475 #[inline]
1476 fn from(value: $Large) -> Self {
1477 unsafe { mem::transmute(value) }
1480 }
1481 }
1482 };
1483}
1484
1485impl_from_array!(Xe<u16>, [Xe<u8>; 2]);
1486impl_from_array!(Xe<u32>, [Xe<u8>; 4]);
1487impl_from_array!(Xe<u32>, [Xe<u16>; 2]);
1488impl_from_array!(Xe<u64>, [Xe<u8>; 8]);
1489impl_from_array!(Xe<u64>, [Xe<u16>; 4]);
1490impl_from_array!(Xe<u64>, [Xe<u32>; 2]);
1491impl_from_array!(Xe<u128>, [Xe<u8>; 16]);
1492impl_from_array!(Xe<u128>, [Xe<u16>; 8]);
1493impl_from_array!(Xe<u128>, [Xe<u32>; 4]);
1494impl_from_array!(Xe<u128>, [Xe<u64>; 2]);
1495
1496macro_rules! type_alias {
1497 (#[$cfg:meta], $alias:ident = $SelfT:ty, $bits:expr, $order:expr) => {
1498 #[doc = concat!("A ", stringify!($bits), "-bit unsigned integer stored in ", $order, "-endian byte order.")]
1499 #[doc = concat!("use endian_num::", stringify!($alias), ";")]
1506 #[doc = concat!("let n = 0x1A;")]
1508 #[doc = concat!("if cfg!(target_endian = \"", $order, "\") {")]
1510 #[doc = concat!(" assert_eq!(", stringify!($alias), "::from_ne(n).0, n);")]
1511 #[doc = concat!(" assert_eq!(", stringify!($alias), "::from_ne(n).0, n.swap_bytes());")]
1513 #[$cfg]
1516 #[allow(non_camel_case_types)]
1517 pub type $alias = $SelfT;
1518 };
1519}
1520
1521type_alias!(#[cfg(feature = "linux-types")], be16 = Be<u16>, 16, "big");
1522type_alias!(#[cfg(feature = "linux-types")], be32 = Be<u32>, 32, "big");
1523type_alias!(#[cfg(feature = "linux-types")], be64 = Be<u64>, 64, "big");
1524type_alias!(#[cfg(feature = "linux-types")], be128 = Be<u128>, 128, "big");
1525type_alias!(#[cfg(feature = "linux-types")], le16 = Le<u16>, 16, "little");
1526type_alias!(#[cfg(feature = "linux-types")], le32 = Le<u32>, 32, "little");
1527type_alias!(#[cfg(feature = "linux-types")], le64 = Le<u64>, 64, "little");
1528type_alias!(#[cfg(feature = "linux-types")], le128 = Le<u128>, 128, "little");