/rust/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/byteorder.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2019 The Fuchsia Authors |
2 | | // |
3 | | // Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0 |
4 | | // <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT |
5 | | // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option. |
6 | | // This file may not be copied, modified, or distributed except according to |
7 | | // those terms. |
8 | | |
9 | | //! Byte order-aware numeric primitives. |
10 | | //! |
11 | | //! This module contains equivalents of the native multi-byte integer types with |
12 | | //! no alignment requirement and supporting byte order conversions. |
13 | | //! |
14 | | //! For each native multi-byte integer type - `u16`, `i16`, `u32`, etc - and |
15 | | //! floating point type - `f32` and `f64` - an equivalent type is defined by |
16 | | //! this module - [`U16`], [`I16`], [`U32`], [`F64`], etc. Unlike their native |
17 | | //! counterparts, these types have alignment 1, and take a type parameter |
18 | | //! specifying the byte order in which the bytes are stored in memory. Each type |
19 | | //! implements the [`FromBytes`], [`AsBytes`], and [`Unaligned`] traits. |
20 | | //! |
21 | | //! These two properties, taken together, make these types useful for defining |
22 | | //! data structures whose memory layout matches a wire format such as that of a |
23 | | //! network protocol or a file format. Such formats often have multi-byte values |
24 | | //! at offsets that do not respect the alignment requirements of the equivalent |
25 | | //! native types, and stored in a byte order not necessarily the same as that of |
26 | | //! the target platform. |
27 | | //! |
28 | | //! Type aliases are provided for common byte orders in the [`big_endian`], |
29 | | //! [`little_endian`], [`network_endian`], and [`native_endian`] submodules. |
30 | | //! |
31 | | //! # Example |
32 | | //! |
33 | | //! One use of these types is for representing network packet formats, such as |
34 | | //! UDP: |
35 | | //! |
36 | | //! ```rust,edition2021 |
37 | | //! # #[cfg(feature = "derive")] { // This example uses derives, and won't compile without them |
38 | | //! use zerocopy::{AsBytes, ByteSlice, FromBytes, FromZeroes, Ref, Unaligned}; |
39 | | //! use zerocopy::byteorder::network_endian::U16; |
40 | | //! |
41 | | //! #[derive(FromZeroes, FromBytes, AsBytes, Unaligned)] |
42 | | //! #[repr(C)] |
43 | | //! struct UdpHeader { |
44 | | //! src_port: U16, |
45 | | //! dst_port: U16, |
46 | | //! length: U16, |
47 | | //! checksum: U16, |
48 | | //! } |
49 | | //! |
50 | | //! struct UdpPacket<B: ByteSlice> { |
51 | | //! header: Ref<B, UdpHeader>, |
52 | | //! body: B, |
53 | | //! } |
54 | | //! |
55 | | //! impl<B: ByteSlice> UdpPacket<B> { |
56 | | //! fn parse(bytes: B) -> Option<UdpPacket<B>> { |
57 | | //! let (header, body) = Ref::new_from_prefix(bytes)?; |
58 | | //! Some(UdpPacket { header, body }) |
59 | | //! } |
60 | | //! |
61 | | //! fn src_port(&self) -> u16 { |
62 | | //! self.header.src_port.get() |
63 | | //! } |
64 | | //! |
65 | | //! // more getters... |
66 | | //! } |
67 | | //! # } |
68 | | //! ``` |
69 | | |
70 | | use core::{ |
71 | | convert::{TryFrom, TryInto}, |
72 | | fmt::{self, Binary, Debug, Display, Formatter, LowerHex, Octal, UpperHex}, |
73 | | marker::PhantomData, |
74 | | num::TryFromIntError, |
75 | | }; |
76 | | |
77 | | // We don't reexport `WriteBytesExt` or `ReadBytesExt` because those are only |
78 | | // available with the `std` feature enabled, and zerocopy is `no_std` by |
79 | | // default. |
80 | | pub use ::byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian, NetworkEndian, BE, LE}; |
81 | | |
82 | | use super::*; |
83 | | |
84 | | macro_rules! impl_fmt_trait { |
85 | | ($name:ident, $native:ident, $trait:ident) => { |
86 | | impl<O: ByteOrder> $trait for $name<O> { |
87 | | #[inline(always)] |
88 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
89 | 0 | $trait::fmt(&self.get(), f) |
90 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::fmt::Octal>::fmt Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::fmt::LowerHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::fmt::UpperHex>::fmt Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::fmt::Binary>::fmt Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::fmt::Display>::fmt Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::fmt::Display>::fmt |
91 | | } |
92 | | }; |
93 | | } |
94 | | |
95 | | macro_rules! impl_fmt_traits { |
96 | | ($name:ident, $native:ident, "floating point number") => { |
97 | | impl_fmt_trait!($name, $native, Display); |
98 | | }; |
99 | | ($name:ident, $native:ident, "unsigned integer") => { |
100 | | impl_fmt_traits!($name, $native, @all_types); |
101 | | }; |
102 | | ($name:ident, $native:ident, "signed integer") => { |
103 | | impl_fmt_traits!($name, $native, @all_types); |
104 | | }; |
105 | | ($name:ident, $native:ident, @all_types) => { |
106 | | impl_fmt_trait!($name, $native, Display); |
107 | | impl_fmt_trait!($name, $native, Octal); |
108 | | impl_fmt_trait!($name, $native, LowerHex); |
109 | | impl_fmt_trait!($name, $native, UpperHex); |
110 | | impl_fmt_trait!($name, $native, Binary); |
111 | | }; |
112 | | } |
113 | | |
114 | | macro_rules! impl_ops_traits { |
115 | | ($name:ident, $native:ident, "floating point number") => { |
116 | | impl_ops_traits!($name, $native, @all_types); |
117 | | impl_ops_traits!($name, $native, @signed_integer_floating_point); |
118 | | }; |
119 | | ($name:ident, $native:ident, "unsigned integer") => { |
120 | | impl_ops_traits!($name, $native, @signed_unsigned_integer); |
121 | | impl_ops_traits!($name, $native, @all_types); |
122 | | }; |
123 | | ($name:ident, $native:ident, "signed integer") => { |
124 | | impl_ops_traits!($name, $native, @signed_unsigned_integer); |
125 | | impl_ops_traits!($name, $native, @signed_integer_floating_point); |
126 | | impl_ops_traits!($name, $native, @all_types); |
127 | | }; |
128 | | ($name:ident, $native:ident, @signed_unsigned_integer) => { |
129 | | impl_ops_traits!(@without_byteorder_swap $name, $native, BitAnd, bitand, BitAndAssign, bitand_assign); |
130 | | impl_ops_traits!(@without_byteorder_swap $name, $native, BitOr, bitor, BitOrAssign, bitor_assign); |
131 | | impl_ops_traits!(@without_byteorder_swap $name, $native, BitXor, bitxor, BitXorAssign, bitxor_assign); |
132 | | impl_ops_traits!(@with_byteorder_swap $name, $native, Shl, shl, ShlAssign, shl_assign); |
133 | | impl_ops_traits!(@with_byteorder_swap $name, $native, Shr, shr, ShrAssign, shr_assign); |
134 | | |
135 | | impl<O> core::ops::Not for $name<O> { |
136 | | type Output = $name<O>; |
137 | | |
138 | | #[inline(always)] |
139 | 0 | fn not(self) -> $name<O> { |
140 | 0 | let self_native = $native::from_ne_bytes(self.0); |
141 | 0 | $name((!self_native).to_ne_bytes(), PhantomData) |
142 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::Not>::not Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::Not>::not Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::Not>::not Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::Not>::not Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::Not>::not Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::Not>::not Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::Not>::not Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::Not>::not |
143 | | } |
144 | | }; |
145 | | ($name:ident, $native:ident, @signed_integer_floating_point) => { |
146 | | impl<O: ByteOrder> core::ops::Neg for $name<O> { |
147 | | type Output = $name<O>; |
148 | | |
149 | | #[inline(always)] |
150 | 0 | fn neg(self) -> $name<O> { |
151 | 0 | let self_native: $native = self.get(); |
152 | 0 | #[allow(clippy::arithmetic_side_effects)] |
153 | 0 | $name::<O>::new(-self_native) |
154 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::Neg>::neg Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::Neg>::neg Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::Neg>::neg Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::Neg>::neg Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::Neg>::neg Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::Neg>::neg |
155 | | } |
156 | | }; |
157 | | ($name:ident, $native:ident, @all_types) => { |
158 | | impl_ops_traits!(@with_byteorder_swap $name, $native, Add, add, AddAssign, add_assign); |
159 | | impl_ops_traits!(@with_byteorder_swap $name, $native, Div, div, DivAssign, div_assign); |
160 | | impl_ops_traits!(@with_byteorder_swap $name, $native, Mul, mul, MulAssign, mul_assign); |
161 | | impl_ops_traits!(@with_byteorder_swap $name, $native, Rem, rem, RemAssign, rem_assign); |
162 | | impl_ops_traits!(@with_byteorder_swap $name, $native, Sub, sub, SubAssign, sub_assign); |
163 | | }; |
164 | | (@with_byteorder_swap $name:ident, $native:ident, $trait:ident, $method:ident, $trait_assign:ident, $method_assign:ident) => { |
165 | | impl<O: ByteOrder> core::ops::$trait for $name<O> { |
166 | | type Output = $name<O>; |
167 | | |
168 | | #[inline(always)] |
169 | 0 | fn $method(self, rhs: $name<O>) -> $name<O> { |
170 | 0 | let self_native: $native = self.get(); |
171 | 0 | let rhs_native: $native = rhs.get(); |
172 | 0 | let result_native = core::ops::$trait::$method(self_native, rhs_native); |
173 | 0 | $name::<O>::new(result_native) |
174 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::Shl>::shl Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::Shr>::shr Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::Add>::add Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::Div>::div Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::Rem>::rem Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::Sub>::sub |
175 | | } |
176 | | |
177 | | impl<O: ByteOrder> core::ops::$trait_assign for $name<O> { |
178 | | #[inline(always)] |
179 | 0 | fn $method_assign(&mut self, rhs: $name<O>) { |
180 | 0 | *self = core::ops::$trait::$method(*self, rhs); |
181 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::ShlAssign>::shl_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::ShrAssign>::shr_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::RemAssign>::rem_assign Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::ops::arith::SubAssign>::sub_assign |
182 | | } |
183 | | }; |
184 | | // Implement traits in terms of the same trait on the native type, but |
185 | | // without performing a byte order swap. This only works for bitwise |
186 | | // operations like `&`, `|`, etc. |
187 | | (@without_byteorder_swap $name:ident, $native:ident, $trait:ident, $method:ident, $trait_assign:ident, $method_assign:ident) => { |
188 | | impl<O: ByteOrder> core::ops::$trait for $name<O> { |
189 | | type Output = $name<O>; |
190 | | |
191 | | #[inline(always)] |
192 | 0 | fn $method(self, rhs: $name<O>) -> $name<O> { |
193 | 0 | let self_native = $native::from_ne_bytes(self.0); |
194 | 0 | let rhs_native = $native::from_ne_bytes(rhs.0); |
195 | 0 | let result_native = core::ops::$trait::$method(self_native, rhs_native); |
196 | 0 | $name(result_native.to_ne_bytes(), PhantomData) |
197 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::BitXor>::bitxor Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::BitXor>::bitxor Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::BitXor>::bitxor Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::BitXor>::bitxor Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::BitXor>::bitxor Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::BitXor>::bitxor Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::BitXor>::bitxor Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::BitAnd>::bitand Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::BitOr>::bitor Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::BitXor>::bitxor |
198 | | } |
199 | | |
200 | | impl<O: ByteOrder> core::ops::$trait_assign for $name<O> { |
201 | | #[inline(always)] |
202 | 0 | fn $method_assign(&mut self, rhs: $name<O>) { |
203 | 0 | *self = core::ops::$trait::$method(*self, rhs); |
204 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::ops::bit::BitXorAssign>::bitxor_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::ops::bit::BitXorAssign>::bitxor_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::ops::bit::BitXorAssign>::bitxor_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::ops::bit::BitXorAssign>::bitxor_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::ops::bit::BitXorAssign>::bitxor_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::ops::bit::BitXorAssign>::bitxor_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::ops::bit::BitXorAssign>::bitxor_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::BitAndAssign>::bitand_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::BitOrAssign>::bitor_assign Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::ops::bit::BitXorAssign>::bitxor_assign |
205 | | } |
206 | | }; |
207 | | } |
208 | | |
209 | | macro_rules! doc_comment { |
210 | | ($x:expr, $($tt:tt)*) => { |
211 | | #[doc = $x] |
212 | | $($tt)* |
213 | | }; |
214 | | } |
215 | | |
216 | | macro_rules! define_max_value_constant { |
217 | | ($name:ident, $bytes:expr, "unsigned integer") => { |
218 | | /// The maximum value. |
219 | | /// |
220 | | /// This constant should be preferred to constructing a new value using |
221 | | /// `new`, as `new` may perform an endianness swap depending on the |
222 | | /// endianness `O` and the endianness of the platform. |
223 | | pub const MAX_VALUE: $name<O> = $name([0xFFu8; $bytes], PhantomData); |
224 | | }; |
225 | | // We don't provide maximum and minimum value constants for signed values |
226 | | // and floats because there's no way to do it generically - it would require |
227 | | // a different value depending on the value of the `ByteOrder` type |
228 | | // parameter. Currently, one workaround would be to provide implementations |
229 | | // for concrete implementations of that trait. In the long term, if we are |
230 | | // ever able to make the `new` constructor a const fn, we could use that |
231 | | // instead. |
232 | | ($name:ident, $bytes:expr, "signed integer") => {}; |
233 | | ($name:ident, $bytes:expr, "floating point number") => {}; |
234 | | } |
235 | | |
236 | | macro_rules! define_type { |
237 | | ($article:ident, |
238 | | $name:ident, |
239 | | $native:ident, |
240 | | $bits:expr, |
241 | | $bytes:expr, |
242 | | $read_method:ident, |
243 | | $write_method:ident, |
244 | | $number_kind:tt, |
245 | | [$($larger_native:ty),*], |
246 | | [$($larger_native_try:ty),*], |
247 | | [$($larger_byteorder:ident),*], |
248 | | [$($larger_byteorder_try:ident),*]) => { |
249 | | doc_comment! { |
250 | | concat!("A ", stringify!($bits), "-bit ", $number_kind, |
251 | | " stored in a given byte order. |
252 | | |
253 | | `", stringify!($name), "` is like the native `", stringify!($native), "` type with |
254 | | two major differences: First, it has no alignment requirement (its alignment is 1). |
255 | | Second, the endianness of its memory layout is given by the type parameter `O`, |
256 | | which can be any type which implements [`ByteOrder`]. In particular, this refers |
257 | | to [`BigEndian`], [`LittleEndian`], [`NativeEndian`], and [`NetworkEndian`]. |
258 | | |
259 | | ", stringify!($article), " `", stringify!($name), "` can be constructed using |
260 | | the [`new`] method, and its contained value can be obtained as a native |
261 | | `",stringify!($native), "` using the [`get`] method, or updated in place with |
262 | | the [`set`] method. In all cases, if the endianness `O` is not the same as the |
263 | | endianness of the current platform, an endianness swap will be performed in |
264 | | order to uphold the invariants that a) the layout of `", stringify!($name), "` |
265 | | has endianness `O` and that, b) the layout of `", stringify!($native), "` has |
266 | | the platform's native endianness. |
267 | | |
268 | | `", stringify!($name), "` implements [`FromBytes`], [`AsBytes`], and [`Unaligned`], |
269 | | making it useful for parsing and serialization. See the module documentation for an |
270 | | example of how it can be used for parsing UDP packets. |
271 | | |
272 | | [`new`]: crate::byteorder::", stringify!($name), "::new |
273 | | [`get`]: crate::byteorder::", stringify!($name), "::get |
274 | | [`set`]: crate::byteorder::", stringify!($name), "::set |
275 | | [`FromBytes`]: crate::FromBytes |
276 | | [`AsBytes`]: crate::AsBytes |
277 | | [`Unaligned`]: crate::Unaligned"), |
278 | | #[derive(Copy, Clone, Eq, PartialEq, Hash)] |
279 | 0 | #[cfg_attr(any(feature = "derive", test), derive(KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned))] Unexecuted instantiation: <zerocopy::byteorder::U16<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U16<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::U32<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U32<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::U64<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U64<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::U128<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U128<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::I16<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I16<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::I32<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I32<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::I64<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I64<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::I128<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I128<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::F32<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F32<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::F64<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F64<_> as zerocopy::KnownLayout>::raw_from_ptr_len Unexecuted instantiation: <zerocopy::byteorder::U16<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U32<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U64<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U128<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I16<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I32<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I64<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I128<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F32<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F64<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U16<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U32<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U64<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U128<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I16<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I32<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I64<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I128<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F32<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F64<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U16<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U32<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U64<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U128<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I16<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I32<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I64<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I128<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F32<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F64<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U16<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U32<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U64<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::U128<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I16<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I32<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I64<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::I128<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F32<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait Unexecuted instantiation: <zerocopy::byteorder::F64<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait |
280 | | #[repr(transparent)] |
281 | | pub struct $name<O>([u8; $bytes], PhantomData<O>); |
282 | | } |
283 | | |
284 | | #[cfg(not(any(feature = "derive", test)))] |
285 | | impl_known_layout!(O => $name<O>); |
286 | | |
287 | | safety_comment! { |
288 | | /// SAFETY: |
289 | | /// `$name<O>` is `repr(transparent)`, and so it has the same layout |
290 | | /// as its only non-zero field, which is a `u8` array. `u8` arrays |
291 | | /// are `FromZeroes`, `FromBytes`, `AsBytes`, and `Unaligned`. |
292 | | impl_or_verify!(O => FromZeroes for $name<O>); |
293 | | impl_or_verify!(O => FromBytes for $name<O>); |
294 | | impl_or_verify!(O => AsBytes for $name<O>); |
295 | | impl_or_verify!(O => Unaligned for $name<O>); |
296 | | } |
297 | | |
298 | | impl<O> Default for $name<O> { |
299 | | #[inline(always)] |
300 | 0 | fn default() -> $name<O> { |
301 | 0 | $name::ZERO |
302 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::default::Default>::default Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::default::Default>::default |
303 | | } |
304 | | |
305 | | impl<O> $name<O> { |
306 | | /// The value zero. |
307 | | /// |
308 | | /// This constant should be preferred to constructing a new value |
309 | | /// using `new`, as `new` may perform an endianness swap depending |
310 | | /// on the endianness and platform. |
311 | | pub const ZERO: $name<O> = $name([0u8; $bytes], PhantomData); |
312 | | |
313 | | define_max_value_constant!($name, $bytes, $number_kind); |
314 | | |
315 | | /// Constructs a new value from bytes which are already in the |
316 | | /// endianness `O`. |
317 | | #[inline(always)] |
318 | 0 | pub const fn from_bytes(bytes: [u8; $bytes]) -> $name<O> { |
319 | 0 | $name(bytes, PhantomData) |
320 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::U32<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::U64<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::U128<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::I16<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::I32<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::I64<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::I128<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::F32<_>>::from_bytes Unexecuted instantiation: <zerocopy::byteorder::F64<_>>::from_bytes |
321 | | } |
322 | | |
323 | | impl<O: ByteOrder> $name<O> { |
324 | | // TODO(joshlf): Make these const fns if the `ByteOrder` methods |
325 | | // ever become const fns. |
326 | | |
327 | | /// Constructs a new value, possibly performing an endianness swap |
328 | | /// to guarantee that the returned value has endianness `O`. |
329 | | #[inline(always)] |
330 | 0 | pub fn new(n: $native) -> $name<O> { |
331 | 0 | let mut out = $name::default(); |
332 | 0 | O::$write_method(&mut out.0[..], n); |
333 | 0 | out |
334 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_>>::new Unexecuted instantiation: <zerocopy::byteorder::U32<_>>::new Unexecuted instantiation: <zerocopy::byteorder::U64<_>>::new Unexecuted instantiation: <zerocopy::byteorder::U128<_>>::new Unexecuted instantiation: <zerocopy::byteorder::I16<_>>::new Unexecuted instantiation: <zerocopy::byteorder::I32<_>>::new Unexecuted instantiation: <zerocopy::byteorder::I64<_>>::new Unexecuted instantiation: <zerocopy::byteorder::I128<_>>::new Unexecuted instantiation: <zerocopy::byteorder::F32<_>>::new Unexecuted instantiation: <zerocopy::byteorder::F64<_>>::new |
335 | | |
336 | | /// Returns the value as a primitive type, possibly performing an |
337 | | /// endianness swap to guarantee that the return value has the |
338 | | /// endianness of the native platform. |
339 | | #[inline(always)] |
340 | 0 | pub fn get(self) -> $native { |
341 | 0 | O::$read_method(&self.0[..]) |
342 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_>>::get Unexecuted instantiation: <zerocopy::byteorder::U32<_>>::get Unexecuted instantiation: <zerocopy::byteorder::U64<_>>::get Unexecuted instantiation: <zerocopy::byteorder::U128<_>>::get Unexecuted instantiation: <zerocopy::byteorder::I16<_>>::get Unexecuted instantiation: <zerocopy::byteorder::I32<_>>::get Unexecuted instantiation: <zerocopy::byteorder::I64<_>>::get Unexecuted instantiation: <zerocopy::byteorder::I128<_>>::get Unexecuted instantiation: <zerocopy::byteorder::F32<_>>::get Unexecuted instantiation: <zerocopy::byteorder::F64<_>>::get |
343 | | |
344 | | /// Updates the value in place as a primitive type, possibly |
345 | | /// performing an endianness swap to guarantee that the stored value |
346 | | /// has the endianness `O`. |
347 | | #[inline(always)] |
348 | 0 | pub fn set(&mut self, n: $native) { |
349 | 0 | O::$write_method(&mut self.0[..], n); |
350 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_>>::set Unexecuted instantiation: <zerocopy::byteorder::U32<_>>::set Unexecuted instantiation: <zerocopy::byteorder::U64<_>>::set Unexecuted instantiation: <zerocopy::byteorder::U128<_>>::set Unexecuted instantiation: <zerocopy::byteorder::I16<_>>::set Unexecuted instantiation: <zerocopy::byteorder::I32<_>>::set Unexecuted instantiation: <zerocopy::byteorder::I64<_>>::set Unexecuted instantiation: <zerocopy::byteorder::I128<_>>::set Unexecuted instantiation: <zerocopy::byteorder::F32<_>>::set Unexecuted instantiation: <zerocopy::byteorder::F64<_>>::set |
351 | | } |
352 | | |
353 | | // The reasoning behind which traits to implement here is to only |
354 | | // implement traits which won't cause inference issues. Notably, |
355 | | // comparison traits like PartialEq and PartialOrd tend to cause |
356 | | // inference issues. |
357 | | |
358 | | impl<O: ByteOrder> From<$name<O>> for [u8; $bytes] { |
359 | | #[inline(always)] |
360 | 0 | fn from(x: $name<O>) -> [u8; $bytes] { |
361 | 0 | x.0 |
362 | 0 | } Unexecuted instantiation: <[u8; 2] as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <[u8; 4] as core::convert::From<zerocopy::byteorder::U32<_>>>::from Unexecuted instantiation: <[u8; 8] as core::convert::From<zerocopy::byteorder::U64<_>>>::from Unexecuted instantiation: <[u8; 16] as core::convert::From<zerocopy::byteorder::U128<_>>>::from Unexecuted instantiation: <[u8; 2] as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <[u8; 4] as core::convert::From<zerocopy::byteorder::I32<_>>>::from Unexecuted instantiation: <[u8; 8] as core::convert::From<zerocopy::byteorder::I64<_>>>::from Unexecuted instantiation: <[u8; 16] as core::convert::From<zerocopy::byteorder::I128<_>>>::from Unexecuted instantiation: <[u8; 4] as core::convert::From<zerocopy::byteorder::F32<_>>>::from Unexecuted instantiation: <[u8; 8] as core::convert::From<zerocopy::byteorder::F64<_>>>::from |
363 | | } |
364 | | |
365 | | impl<O: ByteOrder> From<[u8; $bytes]> for $name<O> { |
366 | | #[inline(always)] |
367 | 0 | fn from(bytes: [u8; $bytes]) -> $name<O> { |
368 | 0 | $name(bytes, PhantomData) |
369 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::From<[u8; 2]>>::from Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::From<[u8; 4]>>::from Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::From<[u8; 8]>>::from Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::convert::From<[u8; 16]>>::from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::From<[u8; 2]>>::from Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::From<[u8; 4]>>::from Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::From<[u8; 8]>>::from Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::convert::From<[u8; 16]>>::from Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::convert::From<[u8; 4]>>::from Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::convert::From<[u8; 8]>>::from |
370 | | } |
371 | | |
372 | | impl<O: ByteOrder> From<$name<O>> for $native { |
373 | | #[inline(always)] |
374 | 0 | fn from(x: $name<O>) -> $native { |
375 | 0 | x.get() |
376 | 0 | } Unexecuted instantiation: <u16 as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <u32 as core::convert::From<zerocopy::byteorder::U32<_>>>::from Unexecuted instantiation: <u64 as core::convert::From<zerocopy::byteorder::U64<_>>>::from Unexecuted instantiation: <u128 as core::convert::From<zerocopy::byteorder::U128<_>>>::from Unexecuted instantiation: <i16 as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <i32 as core::convert::From<zerocopy::byteorder::I32<_>>>::from Unexecuted instantiation: <i64 as core::convert::From<zerocopy::byteorder::I64<_>>>::from Unexecuted instantiation: <i128 as core::convert::From<zerocopy::byteorder::I128<_>>>::from Unexecuted instantiation: <f32 as core::convert::From<zerocopy::byteorder::F32<_>>>::from Unexecuted instantiation: <f64 as core::convert::From<zerocopy::byteorder::F64<_>>>::from |
377 | | } |
378 | | |
379 | | impl<O: ByteOrder> From<$native> for $name<O> { |
380 | | #[inline(always)] |
381 | 0 | fn from(x: $native) -> $name<O> { |
382 | 0 | $name::new(x) |
383 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::From<u16>>::from Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::From<u32>>::from Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::From<u64>>::from Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::convert::From<u128>>::from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::From<i16>>::from Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::From<i32>>::from Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::From<i64>>::from Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::convert::From<i128>>::from Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::convert::From<f32>>::from Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::convert::From<f64>>::from |
384 | | } |
385 | | |
386 | | $( |
387 | | impl<O: ByteOrder> From<$name<O>> for $larger_native { |
388 | | #[inline(always)] |
389 | 0 | fn from(x: $name<O>) -> $larger_native { |
390 | 0 | x.get().into() |
391 | 0 | } Unexecuted instantiation: <u32 as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <u64 as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <u128 as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <usize as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <u64 as core::convert::From<zerocopy::byteorder::U32<_>>>::from Unexecuted instantiation: <u128 as core::convert::From<zerocopy::byteorder::U32<_>>>::from Unexecuted instantiation: <u128 as core::convert::From<zerocopy::byteorder::U64<_>>>::from Unexecuted instantiation: <i32 as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <i64 as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <i128 as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <isize as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <i64 as core::convert::From<zerocopy::byteorder::I32<_>>>::from Unexecuted instantiation: <i128 as core::convert::From<zerocopy::byteorder::I32<_>>>::from Unexecuted instantiation: <i128 as core::convert::From<zerocopy::byteorder::I64<_>>>::from Unexecuted instantiation: <f64 as core::convert::From<zerocopy::byteorder::F32<_>>>::from |
392 | | } |
393 | | )* |
394 | | |
395 | | $( |
396 | | impl<O: ByteOrder> TryFrom<$larger_native_try> for $name<O> { |
397 | | type Error = TryFromIntError; |
398 | | #[inline(always)] |
399 | 0 | fn try_from(x: $larger_native_try) -> Result<$name<O>, TryFromIntError> { |
400 | 0 | $native::try_from(x).map($name::new) |
401 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::TryFrom<u32>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::TryFrom<u64>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::TryFrom<u128>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::TryFrom<usize>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::TryFrom<u64>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::TryFrom<u128>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::TryFrom<u128>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::TryFrom<i32>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::TryFrom<i64>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::TryFrom<i128>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::TryFrom<isize>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::TryFrom<i64>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::TryFrom<i128>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::TryFrom<i128>>::try_from |
402 | | } |
403 | | )* |
404 | | |
405 | | $( |
406 | | impl<O: ByteOrder, P: ByteOrder> From<$name<O>> for $larger_byteorder<P> { |
407 | | #[inline(always)] |
408 | 0 | fn from(x: $name<O>) -> $larger_byteorder<P> { |
409 | 0 | $larger_byteorder::new(x.get().into()) |
410 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::convert::From<zerocopy::byteorder::U16<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::From<zerocopy::byteorder::U32<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::convert::From<zerocopy::byteorder::U32<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::convert::From<zerocopy::byteorder::U64<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::convert::From<zerocopy::byteorder::I16<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::From<zerocopy::byteorder::I32<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::convert::From<zerocopy::byteorder::I32<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::convert::From<zerocopy::byteorder::I64<_>>>::from Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::convert::From<zerocopy::byteorder::F32<_>>>::from |
411 | | } |
412 | | )* |
413 | | |
414 | | $( |
415 | | impl<O: ByteOrder, P: ByteOrder> TryFrom<$larger_byteorder_try<P>> for $name<O> { |
416 | | type Error = TryFromIntError; |
417 | | #[inline(always)] |
418 | 0 | fn try_from(x: $larger_byteorder_try<P>) -> Result<$name<O>, TryFromIntError> { |
419 | 0 | x.get().try_into().map($name::new) |
420 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::TryFrom<zerocopy::byteorder::U32<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::TryFrom<zerocopy::byteorder::U64<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::TryFrom<zerocopy::byteorder::U128<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::TryFrom<zerocopy::byteorder::U64<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::TryFrom<zerocopy::byteorder::U128<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::TryFrom<zerocopy::byteorder::U128<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::TryFrom<zerocopy::byteorder::I32<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::TryFrom<zerocopy::byteorder::I64<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::TryFrom<zerocopy::byteorder::I128<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::TryFrom<zerocopy::byteorder::I64<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::TryFrom<zerocopy::byteorder::I128<_>>>::try_from Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::TryFrom<zerocopy::byteorder::I128<_>>>::try_from |
421 | | } |
422 | | )* |
423 | | |
424 | | impl<O: ByteOrder> AsRef<[u8; $bytes]> for $name<O> { |
425 | | #[inline(always)] |
426 | 0 | fn as_ref(&self) -> &[u8; $bytes] { |
427 | 0 | &self.0 |
428 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::AsRef<[u8; 2]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::AsRef<[u8; 4]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::AsRef<[u8; 8]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::convert::AsRef<[u8; 16]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::AsRef<[u8; 2]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::AsRef<[u8; 4]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::AsRef<[u8; 8]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::convert::AsRef<[u8; 16]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::convert::AsRef<[u8; 4]>>::as_ref Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::convert::AsRef<[u8; 8]>>::as_ref |
429 | | } |
430 | | |
431 | | impl<O: ByteOrder> AsMut<[u8; $bytes]> for $name<O> { |
432 | | #[inline(always)] |
433 | 0 | fn as_mut(&mut self) -> &mut [u8; $bytes] { |
434 | 0 | &mut self.0 |
435 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::convert::AsMut<[u8; 2]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::convert::AsMut<[u8; 4]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::convert::AsMut<[u8; 8]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::convert::AsMut<[u8; 16]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::convert::AsMut<[u8; 2]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::convert::AsMut<[u8; 4]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::convert::AsMut<[u8; 8]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::convert::AsMut<[u8; 16]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::convert::AsMut<[u8; 4]>>::as_mut Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::convert::AsMut<[u8; 8]>>::as_mut |
436 | | } |
437 | | |
438 | | impl<O: ByteOrder> PartialEq<$name<O>> for [u8; $bytes] { |
439 | | #[inline(always)] |
440 | 0 | fn eq(&self, other: &$name<O>) -> bool { |
441 | 0 | self.eq(&other.0) |
442 | 0 | } Unexecuted instantiation: <[u8; 2] as core::cmp::PartialEq<zerocopy::byteorder::U16<_>>>::eq Unexecuted instantiation: <[u8; 4] as core::cmp::PartialEq<zerocopy::byteorder::U32<_>>>::eq Unexecuted instantiation: <[u8; 8] as core::cmp::PartialEq<zerocopy::byteorder::U64<_>>>::eq Unexecuted instantiation: <[u8; 16] as core::cmp::PartialEq<zerocopy::byteorder::U128<_>>>::eq Unexecuted instantiation: <[u8; 2] as core::cmp::PartialEq<zerocopy::byteorder::I16<_>>>::eq Unexecuted instantiation: <[u8; 4] as core::cmp::PartialEq<zerocopy::byteorder::I32<_>>>::eq Unexecuted instantiation: <[u8; 8] as core::cmp::PartialEq<zerocopy::byteorder::I64<_>>>::eq Unexecuted instantiation: <[u8; 16] as core::cmp::PartialEq<zerocopy::byteorder::I128<_>>>::eq Unexecuted instantiation: <[u8; 4] as core::cmp::PartialEq<zerocopy::byteorder::F32<_>>>::eq Unexecuted instantiation: <[u8; 8] as core::cmp::PartialEq<zerocopy::byteorder::F64<_>>>::eq |
443 | | } |
444 | | |
445 | | impl<O: ByteOrder> PartialEq<[u8; $bytes]> for $name<O> { |
446 | | #[inline(always)] |
447 | 0 | fn eq(&self, other: &[u8; $bytes]) -> bool { |
448 | 0 | self.0.eq(other) |
449 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::cmp::PartialEq<[u8; 2]>>::eq Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::cmp::PartialEq<[u8; 4]>>::eq Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::cmp::PartialEq<[u8; 8]>>::eq Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::cmp::PartialEq<[u8; 16]>>::eq Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::cmp::PartialEq<[u8; 2]>>::eq Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::cmp::PartialEq<[u8; 4]>>::eq Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::cmp::PartialEq<[u8; 8]>>::eq Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::cmp::PartialEq<[u8; 16]>>::eq Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::cmp::PartialEq<[u8; 4]>>::eq Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::cmp::PartialEq<[u8; 8]>>::eq |
450 | | } |
451 | | |
452 | | impl_fmt_traits!($name, $native, $number_kind); |
453 | | impl_ops_traits!($name, $native, $number_kind); |
454 | | |
455 | | impl<O: ByteOrder> Debug for $name<O> { |
456 | | #[inline] |
457 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
458 | 0 | // This results in a format like "U16(42)". |
459 | 0 | f.debug_tuple(stringify!($name)).field(&self.get()).finish() |
460 | 0 | } Unexecuted instantiation: <zerocopy::byteorder::U16<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::U32<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::U64<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::U128<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::I16<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::I32<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::I64<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::I128<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::F32<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <zerocopy::byteorder::F64<_> as core::fmt::Debug>::fmt |
461 | | } |
462 | | }; |
463 | | } |
464 | | |
465 | | define_type!( |
466 | | A, |
467 | | U16, |
468 | | u16, |
469 | | 16, |
470 | | 2, |
471 | | read_u16, |
472 | | write_u16, |
473 | | "unsigned integer", |
474 | | [u32, u64, u128, usize], |
475 | | [u32, u64, u128, usize], |
476 | | [U32, U64, U128], |
477 | | [U32, U64, U128] |
478 | | ); |
479 | | define_type!( |
480 | | A, |
481 | | U32, |
482 | | u32, |
483 | | 32, |
484 | | 4, |
485 | | read_u32, |
486 | | write_u32, |
487 | | "unsigned integer", |
488 | | [u64, u128], |
489 | | [u64, u128], |
490 | | [U64, U128], |
491 | | [U64, U128] |
492 | | ); |
493 | | define_type!( |
494 | | A, |
495 | | U64, |
496 | | u64, |
497 | | 64, |
498 | | 8, |
499 | | read_u64, |
500 | | write_u64, |
501 | | "unsigned integer", |
502 | | [u128], |
503 | | [u128], |
504 | | [U128], |
505 | | [U128] |
506 | | ); |
507 | | define_type!(A, U128, u128, 128, 16, read_u128, write_u128, "unsigned integer", [], [], [], []); |
508 | | define_type!( |
509 | | An, |
510 | | I16, |
511 | | i16, |
512 | | 16, |
513 | | 2, |
514 | | read_i16, |
515 | | write_i16, |
516 | | "signed integer", |
517 | | [i32, i64, i128, isize], |
518 | | [i32, i64, i128, isize], |
519 | | [I32, I64, I128], |
520 | | [I32, I64, I128] |
521 | | ); |
522 | | define_type!( |
523 | | An, |
524 | | I32, |
525 | | i32, |
526 | | 32, |
527 | | 4, |
528 | | read_i32, |
529 | | write_i32, |
530 | | "signed integer", |
531 | | [i64, i128], |
532 | | [i64, i128], |
533 | | [I64, I128], |
534 | | [I64, I128] |
535 | | ); |
536 | | define_type!( |
537 | | An, |
538 | | I64, |
539 | | i64, |
540 | | 64, |
541 | | 8, |
542 | | read_i64, |
543 | | write_i64, |
544 | | "signed integer", |
545 | | [i128], |
546 | | [i128], |
547 | | [I128], |
548 | | [I128] |
549 | | ); |
550 | | define_type!(An, I128, i128, 128, 16, read_i128, write_i128, "signed integer", [], [], [], []); |
551 | | define_type!( |
552 | | An, |
553 | | F32, |
554 | | f32, |
555 | | 32, |
556 | | 4, |
557 | | read_f32, |
558 | | write_f32, |
559 | | "floating point number", |
560 | | [f64], |
561 | | [], |
562 | | [F64], |
563 | | [] |
564 | | ); |
565 | | define_type!(An, F64, f64, 64, 8, read_f64, write_f64, "floating point number", [], [], [], []); |
566 | | |
567 | | macro_rules! module { |
568 | | ($name:ident, $trait:ident, $endianness_str:expr) => { |
569 | | /// Numeric primitives stored in |
570 | | #[doc = $endianness_str] |
571 | | /// byte order. |
572 | | pub mod $name { |
573 | | use byteorder::$trait; |
574 | | |
575 | | module!(@ty U16, $trait, "16-bit unsigned integer", $endianness_str); |
576 | | module!(@ty U32, $trait, "32-bit unsigned integer", $endianness_str); |
577 | | module!(@ty U64, $trait, "64-bit unsigned integer", $endianness_str); |
578 | | module!(@ty U128, $trait, "128-bit unsigned integer", $endianness_str); |
579 | | module!(@ty I16, $trait, "16-bit signed integer", $endianness_str); |
580 | | module!(@ty I32, $trait, "32-bit signed integer", $endianness_str); |
581 | | module!(@ty I64, $trait, "64-bit signed integer", $endianness_str); |
582 | | module!(@ty I128, $trait, "128-bit signed integer", $endianness_str); |
583 | | module!(@ty F32, $trait, "32-bit floating point number", $endianness_str); |
584 | | module!(@ty F64, $trait, "64-bit floating point number", $endianness_str); |
585 | | } |
586 | | }; |
587 | | (@ty $ty:ident, $trait:ident, $desc_str:expr, $endianness_str:expr) => { |
588 | | /// A |
589 | | #[doc = $desc_str] |
590 | | /// stored in |
591 | | #[doc = $endianness_str] |
592 | | /// byte order. |
593 | | pub type $ty = crate::byteorder::$ty<$trait>; |
594 | | }; |
595 | | } |
596 | | |
597 | | module!(big_endian, BigEndian, "big-endian"); |
598 | | module!(little_endian, LittleEndian, "little-endian"); |
599 | | module!(network_endian, NetworkEndian, "network-endian"); |
600 | | module!(native_endian, NativeEndian, "native-endian"); |
601 | | |
602 | | #[cfg(any(test, kani))] |
603 | | mod tests { |
604 | | use ::byteorder::NativeEndian; |
605 | | |
606 | | use { |
607 | | super::*, |
608 | | crate::{AsBytes, FromBytes, Unaligned}, |
609 | | }; |
610 | | |
611 | | #[cfg(not(kani))] |
612 | | mod compatibility { |
613 | | pub(super) use rand::{ |
614 | | distributions::{Distribution, Standard}, |
615 | | rngs::SmallRng, |
616 | | Rng, SeedableRng, |
617 | | }; |
618 | | |
619 | | pub(crate) trait Arbitrary {} |
620 | | |
621 | | impl<T> Arbitrary for T {} |
622 | | } |
623 | | |
624 | | #[cfg(kani)] |
625 | | mod compatibility { |
626 | | pub(crate) use kani::Arbitrary; |
627 | | |
628 | | pub(crate) struct SmallRng; |
629 | | |
630 | | impl SmallRng { |
631 | | pub(crate) fn seed_from_u64(_state: u64) -> Self { |
632 | | Self |
633 | | } |
634 | | } |
635 | | |
636 | | pub(crate) trait Rng { |
637 | | fn sample<T, D: Distribution<T>>(&mut self, _distr: D) -> T |
638 | | where |
639 | | T: Arbitrary, |
640 | | { |
641 | | kani::any() |
642 | | } |
643 | | } |
644 | | |
645 | | impl Rng for SmallRng {} |
646 | | |
647 | | pub(crate) trait Distribution<T> {} |
648 | | impl<T, U> Distribution<T> for U {} |
649 | | |
650 | | pub(crate) struct Standard; |
651 | | } |
652 | | |
653 | | use compatibility::*; |
654 | | |
655 | | // A native integer type (u16, i32, etc). |
656 | | #[cfg_attr(kani, allow(dead_code))] |
657 | | trait Native: Arbitrary + FromBytes + AsBytes + Copy + PartialEq + Debug { |
658 | | const ZERO: Self; |
659 | | const MAX_VALUE: Self; |
660 | | |
661 | | type Distribution: Distribution<Self>; |
662 | | const DIST: Self::Distribution; |
663 | | |
664 | | fn rand<R: Rng>(rng: &mut R) -> Self { |
665 | | rng.sample(Self::DIST) |
666 | | } |
667 | | |
668 | | fn checked_add(self, rhs: Self) -> Option<Self>; |
669 | | fn checked_div(self, rhs: Self) -> Option<Self>; |
670 | | fn checked_mul(self, rhs: Self) -> Option<Self>; |
671 | | fn checked_rem(self, rhs: Self) -> Option<Self>; |
672 | | fn checked_sub(self, rhs: Self) -> Option<Self>; |
673 | | fn checked_shl(self, rhs: Self) -> Option<Self>; |
674 | | fn checked_shr(self, rhs: Self) -> Option<Self>; |
675 | | |
676 | | fn is_nan(self) -> bool; |
677 | | |
678 | | /// For `f32` and `f64`, NaN values are not considered equal to |
679 | | /// themselves. This method is like `assert_eq!`, but it treats NaN |
680 | | /// values as equal. |
681 | | fn assert_eq_or_nan(self, other: Self) { |
682 | | let slf = (!self.is_nan()).then(|| self); |
683 | | let other = (!other.is_nan()).then(|| other); |
684 | | assert_eq!(slf, other); |
685 | | } |
686 | | } |
687 | | |
688 | | trait ByteArray: |
689 | | FromBytes + AsBytes + Copy + AsRef<[u8]> + AsMut<[u8]> + Debug + Default + Eq |
690 | | { |
691 | | /// Invert the order of the bytes in the array. |
692 | | fn invert(self) -> Self; |
693 | | } |
694 | | |
695 | | trait ByteOrderType: FromBytes + AsBytes + Unaligned + Copy + Eq + Debug { |
696 | | type Native: Native; |
697 | | type ByteArray: ByteArray; |
698 | | |
699 | | const ZERO: Self; |
700 | | |
701 | | fn new(native: Self::Native) -> Self; |
702 | | fn get(self) -> Self::Native; |
703 | | fn set(&mut self, native: Self::Native); |
704 | | fn from_bytes(bytes: Self::ByteArray) -> Self; |
705 | | fn into_bytes(self) -> Self::ByteArray; |
706 | | |
707 | | /// For `f32` and `f64`, NaN values are not considered equal to |
708 | | /// themselves. This method is like `assert_eq!`, but it treats NaN |
709 | | /// values as equal. |
710 | | fn assert_eq_or_nan(self, other: Self) { |
711 | | let slf = (!self.get().is_nan()).then(|| self); |
712 | | let other = (!other.get().is_nan()).then(|| other); |
713 | | assert_eq!(slf, other); |
714 | | } |
715 | | } |
716 | | |
717 | | trait ByteOrderTypeUnsigned: ByteOrderType { |
718 | | const MAX_VALUE: Self; |
719 | | } |
720 | | |
721 | | macro_rules! impl_byte_array { |
722 | | ($bytes:expr) => { |
723 | | impl ByteArray for [u8; $bytes] { |
724 | | fn invert(mut self) -> [u8; $bytes] { |
725 | | self.reverse(); |
726 | | self |
727 | | } |
728 | | } |
729 | | }; |
730 | | } |
731 | | |
732 | | impl_byte_array!(2); |
733 | | impl_byte_array!(4); |
734 | | impl_byte_array!(8); |
735 | | impl_byte_array!(16); |
736 | | |
737 | | macro_rules! impl_byte_order_type_unsigned { |
738 | | ($name:ident, unsigned) => { |
739 | | impl<O: ByteOrder> ByteOrderTypeUnsigned for $name<O> { |
740 | | const MAX_VALUE: $name<O> = $name::MAX_VALUE; |
741 | | } |
742 | | }; |
743 | | ($name:ident, signed) => {}; |
744 | | } |
745 | | |
746 | | macro_rules! impl_traits { |
747 | | ($name:ident, $native:ident, $bytes:expr, $sign:ident $(, @$float:ident)?) => { |
748 | | impl Native for $native { |
749 | | // For some types, `0 as $native` is required (for example, when |
750 | | // `$native` is a floating-point type; `0` is an integer), but |
751 | | // for other types, it's a trivial cast. In all cases, Clippy |
752 | | // thinks it's dangerous. |
753 | | #[allow(trivial_numeric_casts, clippy::as_conversions)] |
754 | | const ZERO: $native = 0 as $native; |
755 | | const MAX_VALUE: $native = $native::MAX; |
756 | | |
757 | | type Distribution = Standard; |
758 | | const DIST: Standard = Standard; |
759 | | |
760 | | impl_traits!(@float_dependent_methods $(@$float)?); |
761 | | } |
762 | | |
763 | | impl<O: ByteOrder> ByteOrderType for $name<O> { |
764 | | type Native = $native; |
765 | | type ByteArray = [u8; $bytes]; |
766 | | |
767 | | const ZERO: $name<O> = $name::ZERO; |
768 | | |
769 | | fn new(native: $native) -> $name<O> { |
770 | | $name::new(native) |
771 | | } |
772 | | |
773 | | fn get(self) -> $native { |
774 | | $name::get(self) |
775 | | } |
776 | | |
777 | | fn set(&mut self, native: $native) { |
778 | | $name::set(self, native) |
779 | | } |
780 | | |
781 | | fn from_bytes(bytes: [u8; $bytes]) -> $name<O> { |
782 | | $name::from(bytes) |
783 | | } |
784 | | |
785 | | fn into_bytes(self) -> [u8; $bytes] { |
786 | | <[u8; $bytes]>::from(self) |
787 | | } |
788 | | } |
789 | | |
790 | | impl_byte_order_type_unsigned!($name, $sign); |
791 | | }; |
792 | | (@float_dependent_methods) => { |
793 | | fn checked_add(self, rhs: Self) -> Option<Self> { self.checked_add(rhs) } |
794 | | fn checked_div(self, rhs: Self) -> Option<Self> { self.checked_div(rhs) } |
795 | | fn checked_mul(self, rhs: Self) -> Option<Self> { self.checked_mul(rhs) } |
796 | | fn checked_rem(self, rhs: Self) -> Option<Self> { self.checked_rem(rhs) } |
797 | | fn checked_sub(self, rhs: Self) -> Option<Self> { self.checked_sub(rhs) } |
798 | | fn checked_shl(self, rhs: Self) -> Option<Self> { self.checked_shl(rhs.try_into().unwrap_or(u32::MAX)) } |
799 | | fn checked_shr(self, rhs: Self) -> Option<Self> { self.checked_shr(rhs.try_into().unwrap_or(u32::MAX)) } |
800 | | fn is_nan(self) -> bool { false } |
801 | | }; |
802 | | (@float_dependent_methods @float) => { |
803 | | fn checked_add(self, rhs: Self) -> Option<Self> { Some(self + rhs) } |
804 | | fn checked_div(self, rhs: Self) -> Option<Self> { Some(self / rhs) } |
805 | | fn checked_mul(self, rhs: Self) -> Option<Self> { Some(self * rhs) } |
806 | | fn checked_rem(self, rhs: Self) -> Option<Self> { Some(self % rhs) } |
807 | | fn checked_sub(self, rhs: Self) -> Option<Self> { Some(self - rhs) } |
808 | | fn checked_shl(self, _rhs: Self) -> Option<Self> { unimplemented!() } |
809 | | fn checked_shr(self, _rhs: Self) -> Option<Self> { unimplemented!() } |
810 | | fn is_nan(self) -> bool { self.is_nan() } |
811 | | }; |
812 | | } |
813 | | |
814 | | impl_traits!(U16, u16, 2, unsigned); |
815 | | impl_traits!(U32, u32, 4, unsigned); |
816 | | impl_traits!(U64, u64, 8, unsigned); |
817 | | impl_traits!(U128, u128, 16, unsigned); |
818 | | impl_traits!(I16, i16, 2, signed); |
819 | | impl_traits!(I32, i32, 4, signed); |
820 | | impl_traits!(I64, i64, 8, signed); |
821 | | impl_traits!(I128, i128, 16, signed); |
822 | | impl_traits!(F32, f32, 4, signed, @float); |
823 | | impl_traits!(F64, f64, 8, signed, @float); |
824 | | |
825 | | macro_rules! call_for_unsigned_types { |
826 | | ($fn:ident, $byteorder:ident) => { |
827 | | $fn::<U16<$byteorder>>(); |
828 | | $fn::<U32<$byteorder>>(); |
829 | | $fn::<U64<$byteorder>>(); |
830 | | $fn::<U128<$byteorder>>(); |
831 | | }; |
832 | | } |
833 | | |
834 | | macro_rules! call_for_signed_types { |
835 | | ($fn:ident, $byteorder:ident) => { |
836 | | $fn::<I16<$byteorder>>(); |
837 | | $fn::<I32<$byteorder>>(); |
838 | | $fn::<I64<$byteorder>>(); |
839 | | $fn::<I128<$byteorder>>(); |
840 | | }; |
841 | | } |
842 | | |
843 | | macro_rules! call_for_float_types { |
844 | | ($fn:ident, $byteorder:ident) => { |
845 | | $fn::<F32<$byteorder>>(); |
846 | | $fn::<F64<$byteorder>>(); |
847 | | }; |
848 | | } |
849 | | |
850 | | macro_rules! call_for_all_types { |
851 | | ($fn:ident, $byteorder:ident) => { |
852 | | call_for_unsigned_types!($fn, $byteorder); |
853 | | call_for_signed_types!($fn, $byteorder); |
854 | | call_for_float_types!($fn, $byteorder); |
855 | | }; |
856 | | } |
857 | | |
858 | | #[cfg(target_endian = "big")] |
859 | | type NonNativeEndian = LittleEndian; |
860 | | #[cfg(target_endian = "little")] |
861 | | type NonNativeEndian = BigEndian; |
862 | | |
863 | | // We use a `u64` seed so that we can use `SeedableRng::seed_from_u64`. |
864 | | // `SmallRng`'s `SeedableRng::Seed` differs by platform, so if we wanted to |
865 | | // call `SeedableRng::from_seed`, which takes a `Seed`, we would need |
866 | | // conditional compilation by `target_pointer_width`. |
867 | | const RNG_SEED: u64 = 0x7A03CAE2F32B5B8F; |
868 | | |
869 | | const RAND_ITERS: usize = if cfg!(any(miri, kani)) { |
870 | | // The tests below which use this constant used to take a very long time |
871 | | // on Miri, which slows down local development and CI jobs. We're not |
872 | | // using Miri to check for the correctness of our code, but rather its |
873 | | // soundness, and at least in the context of these particular tests, a |
874 | | // single loop iteration is just as good for surfacing UB as multiple |
875 | | // iterations are. |
876 | | // |
877 | | // As of the writing of this comment, here's one set of measurements: |
878 | | // |
879 | | // $ # RAND_ITERS == 1 |
880 | | // $ cargo miri test -- -Z unstable-options --report-time endian |
881 | | // test byteorder::tests::test_native_endian ... ok <0.049s> |
882 | | // test byteorder::tests::test_non_native_endian ... ok <0.061s> |
883 | | // |
884 | | // $ # RAND_ITERS == 1024 |
885 | | // $ cargo miri test -- -Z unstable-options --report-time endian |
886 | | // test byteorder::tests::test_native_endian ... ok <25.716s> |
887 | | // test byteorder::tests::test_non_native_endian ... ok <38.127s> |
888 | | 1 |
889 | | } else { |
890 | | 1024 |
891 | | }; |
892 | | |
893 | | #[cfg_attr(test, test)] |
894 | | #[cfg_attr(kani, kani::proof)] |
895 | | fn test_zero() { |
896 | | fn test_zero<T: ByteOrderType>() { |
897 | | assert_eq!(T::ZERO.get(), T::Native::ZERO); |
898 | | } |
899 | | |
900 | | call_for_all_types!(test_zero, NativeEndian); |
901 | | call_for_all_types!(test_zero, NonNativeEndian); |
902 | | } |
903 | | |
904 | | #[cfg_attr(test, test)] |
905 | | #[cfg_attr(kani, kani::proof)] |
906 | | fn test_max_value() { |
907 | | fn test_max_value<T: ByteOrderTypeUnsigned>() { |
908 | | assert_eq!(T::MAX_VALUE.get(), T::Native::MAX_VALUE); |
909 | | } |
910 | | |
911 | | call_for_unsigned_types!(test_max_value, NativeEndian); |
912 | | call_for_unsigned_types!(test_max_value, NonNativeEndian); |
913 | | } |
914 | | |
915 | | #[cfg_attr(test, test)] |
916 | | #[cfg_attr(kani, kani::proof)] |
917 | | fn test_endian() { |
918 | | fn test<T: ByteOrderType>(invert: bool) { |
919 | | let mut r = SmallRng::seed_from_u64(RNG_SEED); |
920 | | for _ in 0..RAND_ITERS { |
921 | | let native = T::Native::rand(&mut r); |
922 | | let mut bytes = T::ByteArray::default(); |
923 | | bytes.as_bytes_mut().copy_from_slice(native.as_bytes()); |
924 | | if invert { |
925 | | bytes = bytes.invert(); |
926 | | } |
927 | | let mut from_native = T::new(native); |
928 | | let from_bytes = T::from_bytes(bytes); |
929 | | |
930 | | from_native.assert_eq_or_nan(from_bytes); |
931 | | from_native.get().assert_eq_or_nan(native); |
932 | | from_bytes.get().assert_eq_or_nan(native); |
933 | | |
934 | | assert_eq!(from_native.into_bytes(), bytes); |
935 | | assert_eq!(from_bytes.into_bytes(), bytes); |
936 | | |
937 | | let updated = T::Native::rand(&mut r); |
938 | | from_native.set(updated); |
939 | | from_native.get().assert_eq_or_nan(updated); |
940 | | } |
941 | | } |
942 | | |
943 | | fn test_native<T: ByteOrderType>() { |
944 | | test::<T>(false); |
945 | | } |
946 | | |
947 | | fn test_non_native<T: ByteOrderType>() { |
948 | | test::<T>(true); |
949 | | } |
950 | | |
951 | | call_for_all_types!(test_native, NativeEndian); |
952 | | call_for_all_types!(test_non_native, NonNativeEndian); |
953 | | } |
954 | | |
955 | | #[test] |
956 | | fn test_ops_impls() { |
957 | | // Test implementations of traits in `core::ops`. Some of these are |
958 | | // fairly banal, but some are optimized to perform the operation without |
959 | | // swapping byte order (namely, bit-wise operations which are identical |
960 | | // regardless of byte order). These are important to test, and while |
961 | | // we're testing those anyway, it's trivial to test all of the impls. |
962 | | |
963 | | fn test<T, F, G, H>(op: F, op_native: G, op_native_checked: Option<H>) |
964 | | where |
965 | | T: ByteOrderType, |
966 | | F: Fn(T, T) -> T, |
967 | | G: Fn(T::Native, T::Native) -> T::Native, |
968 | | H: Fn(T::Native, T::Native) -> Option<T::Native>, |
969 | | { |
970 | | let mut r = SmallRng::seed_from_u64(RNG_SEED); |
971 | | for _ in 0..RAND_ITERS { |
972 | | let n0 = T::Native::rand(&mut r); |
973 | | let n1 = T::Native::rand(&mut r); |
974 | | let t0 = T::new(n0); |
975 | | let t1 = T::new(n1); |
976 | | |
977 | | // If this operation would overflow/underflow, skip it rather |
978 | | // than attempt to catch and recover from panics. |
979 | | if matches!(&op_native_checked, Some(checked) if checked(n0, n1).is_none()) { |
980 | | continue; |
981 | | } |
982 | | |
983 | | let n_res = op_native(n0, n1); |
984 | | let t_res = op(t0, t1); |
985 | | |
986 | | // For `f32` and `f64`, NaN values are not considered equal to |
987 | | // themselves. We store `Option<f32>`/`Option<f64>` and store |
988 | | // NaN as `None` so they can still be compared. |
989 | | let n_res = (!T::Native::is_nan(n_res)).then(|| n_res); |
990 | | let t_res = (!T::Native::is_nan(t_res.get())).then(|| t_res.get()); |
991 | | assert_eq!(n_res, t_res); |
992 | | } |
993 | | } |
994 | | |
995 | | macro_rules! test { |
996 | | (@binary $trait:ident, $method:ident $([$checked_method:ident])?, $($call_for_macros:ident),*) => {{ |
997 | | test!( |
998 | | @inner $trait, |
999 | | core::ops::$trait::$method, |
1000 | | core::ops::$trait::$method, |
1001 | | { |
1002 | | #[allow(unused_mut, unused_assignments)] |
1003 | | let mut op_native_checked = None::<fn(T::Native, T::Native) -> Option<T::Native>>; |
1004 | | $( |
1005 | | op_native_checked = Some(T::Native::$checked_method); |
1006 | | )? |
1007 | | op_native_checked |
1008 | | }, |
1009 | | $($call_for_macros),* |
1010 | | ); |
1011 | | }}; |
1012 | | (@unary $trait:ident, $method:ident $([$checked_method:ident])?, $($call_for_macros:ident),*) => {{ |
1013 | | test!( |
1014 | | @inner $trait, |
1015 | | |slf, _rhs| core::ops::$trait::$method(slf), |
1016 | | |slf, _rhs| core::ops::$trait::$method(slf), |
1017 | | { |
1018 | | #[allow(unused_mut, unused_assignments)] |
1019 | | let mut op_native_checked = None::<fn(T::Native, T::Native) -> Option<T::Native>>; |
1020 | | $( |
1021 | | op_native_checked = Some(|slf, _rhs| T::Native::$checked_method(slf)); |
1022 | | )? |
1023 | | op_native_checked |
1024 | | }, |
1025 | | $($call_for_macros),* |
1026 | | ); |
1027 | | }}; |
1028 | | (@inner $trait:ident, $op:expr, $op_native:expr, $op_native_checked:expr, $($call_for_macros:ident),*) => {{ |
1029 | | fn t<T: ByteOrderType + core::ops::$trait<Output = T>>() |
1030 | | where |
1031 | | T::Native: core::ops::$trait<Output = T::Native>, |
1032 | | { |
1033 | | test::<T, _, _, _>( |
1034 | | $op, |
1035 | | $op_native, |
1036 | | $op_native_checked, |
1037 | | ); |
1038 | | } |
1039 | | |
1040 | | $( |
1041 | | $call_for_macros!(t, NativeEndian); |
1042 | | $call_for_macros!(t, NonNativeEndian); |
1043 | | )* |
1044 | | }}; |
1045 | | } |
1046 | | |
1047 | | test!(@binary Add, add[checked_add], call_for_all_types); |
1048 | | test!(@binary Div, div[checked_div], call_for_all_types); |
1049 | | test!(@binary Mul, mul[checked_mul], call_for_all_types); |
1050 | | test!(@binary Rem, rem[checked_rem], call_for_all_types); |
1051 | | test!(@binary Sub, sub[checked_sub], call_for_all_types); |
1052 | | |
1053 | | test!(@binary BitAnd, bitand, call_for_unsigned_types, call_for_signed_types); |
1054 | | test!(@binary BitOr, bitor, call_for_unsigned_types, call_for_signed_types); |
1055 | | test!(@binary BitXor, bitxor, call_for_unsigned_types, call_for_signed_types); |
1056 | | test!(@binary Shl, shl[checked_shl], call_for_unsigned_types, call_for_signed_types); |
1057 | | test!(@binary Shr, shr[checked_shr], call_for_unsigned_types, call_for_signed_types); |
1058 | | |
1059 | | test!(@unary Not, not, call_for_signed_types, call_for_unsigned_types); |
1060 | | test!(@unary Neg, neg, call_for_signed_types, call_for_float_types); |
1061 | | } |
1062 | | |
1063 | | #[test] |
1064 | | fn test_debug_impl() { |
1065 | | // Ensure that Debug applies format options to the inner value. |
1066 | | let val = U16::<LE>::new(10); |
1067 | | assert_eq!(format!("{:?}", val), "U16(10)"); |
1068 | | assert_eq!(format!("{:03?}", val), "U16(010)"); |
1069 | | assert_eq!(format!("{:x?}", val), "U16(a)"); |
1070 | | } |
1071 | | } |