tartan_bitfield/lib.rs
1//! This crate can be used to define structures with accessors for particular bits or
2//! bit ranges. Useful for dealing with registers and protocols.
3//!
4//! # Features
5//!
6//! * **Performance**: Generated code is nearly identical to hand-rolled bit twiddling.
7//! * **Safety**: Absolutely no unsafe code in the implementation or usage.
8//! * **Portability**:
9//! * `#![no_std]`-compatible out of the box.
10//! * Unlike bit fields in C, the layout is predictable. See the section about
11//! endianness below.
12//! * Unlike Rust's `#[repr(packed, C)]`, each field has explicit bit ranges, rather
13//! than relying on the ordering and size of other fields within the struct. While
14//! specifying bit numbers may seem tedious, it can eliminate surprises, and it
15//! usually corresponds directly to the way registers and protocols are defined in
16//! datasheets.
17//! * **Convenience**:
18//! * Single-bit flags and multi-bit fields can be defined in the same structure.
19//! * Bit ranges can be accessed as non-primitive, non-integer types (including other
20//! bitfield structs) using appropriate [`Into`] and [`From`] implementations.
21//! * The structs implement all the traits you would expect. See the documentation
22//! for [`bitfield`]. A [`bitfield_without_debug`] macro is also available if you
23//! want to provide your own debugging output.
24//! * Accessors can be defined in a trait, which is useful for registers where where
25//! some fields are common, but others are only defined in certain states. See
26//! [`bitfield_accessors`].
27//!
28//! # Example
29//!
30//! ```
31//! # use tartan_bitfield::bitfield;
32//! bitfield! {
33//! // The structure will be a wrapper for a u32 value.
34//! pub struct Example(u32) {
35//! // Accessors for field `a` will refer to the first four least significant
36//! // bits of the wrapped value, bits 0, 1, 2, and 3.
37//! //
38//! // Note that like normal Rust ranges:
39//! // * `[0..4]` does not include bit 4
40//! // * `[0..=4]` includes bit 4
41//! //
42//! // The accessors will be public, and will take/return the four bits as a `u8`.
43//! [0..4] pub a: u8,
44//!
45//! // No accessors cover bits `4..6`. This is legal and can be used for reserved
46//! // bits. However, these bits will still affect equality for the struct as a
47//! // whole.
48//!
49//! // Accessors for field `b` will refer to the twelve bits starting at bit 6,
50//! // but they will not be public. They will take/return the 12 bits as a `u16`.
51//! [6..=17] b: u16,
52//!
53//! // Note that this bit range overlaps with `b`. This is allowed.
54//! [16..20] pub c: u8,
55//!
56//! // Accessors for field `d` will take/return a boolean and refer to a single
57//! // bit. Note that the `bool` is implied and not specified after the name.
58//! [25] pub d,
59//!
60//! // This will cover the 6 most significant bits of the wrapped value, but
61//! // the getters will take/return a `SubFields` struct instead of `u8`. This is
62//! // useful for nested bitfields, but the `A as B` syntax works for any `B`
63//! // which implements `Into<A>` and `From<A>`.
64//! [26..32] pub e: u8 as SubFields,
65//! }
66//! }
67//!
68//! bitfield! {
69//! // All accessors on this field use booleans and refer to single bits
70//! pub struct SubFields(u8) {
71//! [0] pub zero,
72//! [1] pub one,
73//! [2] pub two,
74//! [3] pub three,
75//! [4] pub four,
76//! [5] pub five,
77//! }
78//! }
79//!
80//!
81//! // The struct can be initialized with a u32 value
82//! let x = Example(0xfa84_9e1b);
83//! assert_eq!(x.a(), 0xb_u8);
84//! assert_eq!(x.b(), 0x278_u16); // Private, but still can be used within the module
85//! assert_eq!(x.c(), 0x4_u8);
86//! assert_eq!(x.d(), true);
87//! assert_eq!(x.e(), SubFields(0x3e_u8));
88//! assert_eq!(x.e().zero(), false);
89//! assert_eq!(x.e().five(), true);
90//!
91//! // It can also be converted Into and From its underlying representation
92//! let n: u32 = x.into();
93//! let y: Example = n.into();
94//! assert_eq!(n, 0xfa84_9e1b);
95//! assert_eq!(x, y);
96//!
97//! // Setters are all prefixed with `set_`. They have the same visibility as the getters.
98//! let mut z = Example::default();
99//! z.set_a(0xb);
100//! z.set_b(0x278);
101//! z.set_c(0x4);
102//! z.set_d(true);
103//! z.set_e(SubFields(0x3e));
104//! assert_eq!(z, Example(0xfa04_9e0b));
105//!
106//! // Reserved ranges influence equality, and they are all zero on `z`.
107//! assert_ne!(z, x);
108//!
109//! // Alternatively, you can use the `with_` methods, which return a new value instead
110//! // of mutating in place.
111//! let mut w = x
112//! .with_a(0x6)
113//! .with_b(0x9f3)
114//! .with_c(0xd)
115//! .with_d(false)
116//! .with_e(SubFields(0x2b));
117//! assert_eq!(w, Example(0xac8d_7cd6));
118//! assert_eq!(x, Example(0xfa84_9e1b));
119//! ```
120//!
121//! For lots more examples, see the [Tartan OS](https://github.com/cimbul/tartan-os)
122//! project that this crate was spun off from.
123//!
124//! # Endiannness and Bit Numbering
125//!
126//! Each bitfield wraps an underlying integer type. In the example above, `Example(u32)`
127//! wraps a `u32`. Bit numbers within the macro refer to the bits of the logical _value_,
128//! starting from the least significant bit = 0. They are not dependent on the order of
129//! the bytes of the `u32` representation in memory, a.k.a. endianness.
130//!
131//! The endianness of the underlying value is platform dependent. This is no different
132//! than any other integer value, and the context determines whether you need to worry
133//! about it.
134//! * If the underlying representation is a `u8`, then byte order is irrelevant.
135//! * If you are reading from a register, it's likely you want native byte order and
136//! don't need to do anything special.
137//! * If you are working with a network or bus protocol, it's likely you are serializing
138//! or deserializing from a byte array. To convert using a specific endianness
139//! regardless of platform, use the normal methods: for example, the builtins
140//! [`u32::from_be_bytes`] and [`u64::to_le_bytes`], or a crate like
141//! [byteorder](https://docs.rs/byteorder/latest/byteorder/).
142//!
143//! # Alternatives
144//!
145//! I have been using this in my personal OS project for a while, and it meets my needs
146//! better than other options. But you may be interested in a few other crates:
147//! * [bitfield](https://github.com/dzamlo/rust-bitfield): Similar approach for
148//! accessors and bit ranges, but a less obvious syntax.
149//! * [bitflags](https://docs.rs/bitflags/latest/bitflags/): Works well for single-bit
150//! flags that can be viewed as a collection.
151//! * [bitvec](https://docs.rs/bitvec/latest/bitvec/): Another collection type to view
152//! memory as a sequence of bits. Less focused on defining domain-specific structs.
153//! * [modular-bitfield](https://docs.rs/modular-bitfield/latest/modular_bitfield/):
154//! Field ordering and widths determine bit ranges. Structs can only be converted to
155//! byte arrays, and only in little-endian order, regardless of platform endianness.
156//! This can be undesirable when working with registers.
157//! * [packed_struct](https://docs.rs/packed_struct/0.10.0/packed_struct/): Lots of
158//! options, including bit numbering and endianness conversions. Structs are held
159//! in unpacked form in memory, and only converted to packed form for serialization.
160//! Depending on your access patterns, this may be better or worse (or it may not
161//! matter at all).
162//! * For an analogue to `pack_struct`'s `PrimitiveEnum`, see the
163//! [`tartan-c-enum`](https://github.com/cimbul/tartan-c-enum) crate.
164
165#![no_std]
166#![warn(missing_docs)]
167#![warn(clippy::pedantic)]
168#![allow(clippy::doc_markdown)]
169#![allow(clippy::inline_always)]
170#![allow(clippy::must_use_candidate)]
171#![allow(clippy::similar_names)]
172#![allow(clippy::upper_case_acronyms)]
173
174use core::convert::From;
175use core::default::Default;
176use core::ops;
177
178// Must be re-exported so that crates that use these macros will be able to resolve it
179#[doc(hidden)]
180pub use paste::paste;
181
182/// Marker trait implemented by types defined with the [`bitfield`] macro.
183///
184/// This mainly exists to allow type inference in the [`bitfield_accessors`] macro, but it
185/// also aids documentation and may be useful in user code.
186pub trait Bitfield<T>
187where
188 Self: core::fmt::Debug + Default + Copy + Eq + From<T> + Into<T>,
189{
190 /// Construct a new bitfield type from its underlying representation
191 #[inline(always)]
192 fn new(value: T) -> Self {
193 value.into()
194 }
195
196 /// Unwrap the bitfield into its underlying representation
197 #[inline(always)]
198 fn value(self) -> T {
199 self.into()
200 }
201}
202
203/// Define a structure that wraps a number with accessors for certain bit ranges.
204///
205/// See the crate documentation for an example.
206///
207/// The structure will implement these traits, where `T` is the underlying type defined
208/// in parentheses immediately after the struct name.
209/// * [`Bitfield<T>`](Bitfield)
210/// * [`Debug`]
211/// * [`Default`]
212/// * [`Copy`]
213/// * [`Eq`]
214/// * [`Into<T>`](Into)
215/// * [`From<T>`](From)
216#[macro_export]
217macro_rules! bitfield {
218 [
219 $( #[$meta:meta] )*
220 $vis:vis struct $struct:ident($underlying_type:ty) {
221 $($body:tt)*
222 }
223 ] => {
224 $crate::bitfield_without_debug! {
225 $(#[$meta])*
226 $vis struct $struct($underlying_type) {
227 $($body)*
228 }
229 }
230
231 impl ::core::fmt::Debug for $struct {
232 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
233 let mut struct_out = f.debug_struct(stringify!($struct));
234 struct_out.field("<value>", &self.0);
235 self.fmt_fields(&mut struct_out);
236 struct_out.finish()
237 }
238 }
239 }
240}
241
242/// Same as the [`bitfield`] macro without a [`Debug`] implementation provided.
243///
244/// Since Debug is required by the [`Bitfield`] trait, the caller must provide their own
245/// implementation.
246#[macro_export]
247macro_rules! bitfield_without_debug {
248 [
249 $( #[$meta:meta] )*
250 $vis:vis struct $struct:ident($underlying_type:ty) {
251 $($body:tt)*
252 }
253 ] => {
254 $( #[$meta] )*
255 #[repr(transparent)]
256 #[derive(Default, Clone, Copy, PartialEq, Eq)]
257 $vis struct $struct($underlying_type);
258
259 impl $struct {
260 $crate::bitfield_accessors! { $($body)* }
261 }
262
263 impl $crate::Bitfield<$underlying_type> for $struct {}
264
265 impl ::core::convert::From<$underlying_type> for $struct {
266 #[inline(always)]
267 fn from(val: $underlying_type) -> Self { Self(val) }
268 }
269
270 impl ::core::convert::From<$struct> for $underlying_type {
271 #[inline(always)]
272 fn from(val: $struct) -> Self { val.0 }
273 }
274 };
275}
276
277/// Define getters and setters for certain bit ranges. The containing type must
278/// implement the [`Bitfield`] trait.
279///
280/// This is most commonly invoked by the [`bitfield`] macro, but it can be used on its own
281/// to define common accessors as part of a trait, as in the example below:
282///
283/// ```
284/// # use tartan_bitfield::{Bitfield, bitfield, bitfield_accessors};
285/// #
286/// trait CommonFields: Bitfield<u32> {
287/// bitfield_accessors! {
288/// // Since these are part of a trait, the `pub` keyword must be omitted.
289/// [ 0.. 6] a: u8,
290/// [14] b,
291/// [18..32] c: u16,
292/// }
293/// }
294///
295/// bitfield! {
296/// struct SomeFields(u32) {
297/// [ 7] pub x,
298/// [16] pub y,
299/// }
300/// }
301///
302/// bitfield! {
303/// struct OtherFields(u32) {
304/// [10] pub z,
305/// [12] pub q,
306/// }
307/// }
308///
309/// impl CommonFields for SomeFields {}
310/// impl CommonFields for OtherFields {}
311///
312/// let f = SomeFields(0xabcd_1234);
313/// assert_eq!(f.a(), 0x34); // has accessors from CommonFields
314/// assert_eq!(f.y(), true); // has accessors from SomeFields
315/// //assert_eq!(f.z(), false); // COMPILE ERROR: no accessors from OtherFields
316///
317/// let g = OtherFields(0xabcd_1234);
318/// assert_eq!(g.a(), 0x34); // has accessors from CommonFields
319/// //assert_eq!(g.y(), true); // COMPILE ERROR: no accessors from SomeFields
320/// assert_eq!(g.z(), false); // has accessors from OtherFields
321/// ```
322#[macro_export]
323macro_rules! bitfield_accessors {
324 [
325 $(
326 $( #[$meta:meta] )*
327 [ $( $range:tt )* ]
328 $vis:vis $field:ident
329 $( : $underlying_type:ty $( as $interface_type:ty )? )?
330 ),*
331 $(,)?
332 ] => {
333 $(
334 $crate::bitfield_accessors! {
335 @field getter
336 $( #[$meta] )*
337 [ $( $range )* ]
338 $vis $field
339 $( : $underlying_type $( as $interface_type )? )?
340 }
341 )*
342
343 $(
344 $crate::bitfield_accessors! {
345 @field setter
346 $( #[$meta] )*
347 [ $( $range )* ]
348 $vis $field
349 $( : $underlying_type $( as $interface_type )? )?
350 }
351 )*
352
353 /// Print this object's bitfield values. Helper method for `Debug`
354 /// implementations.
355 fn fmt_fields(&self, f: &mut ::core::fmt::DebugStruct) {
356 $(
357 $(#[$meta])*
358 f.field(stringify!($field), &self.$field());
359 )*
360 }
361 };
362
363 // Special case for single-bit boolean fields
364 [
365 @field getter
366 $( #[$meta:meta] )*
367 [ $bit:literal ]
368 $vis:vis $field:ident
369 ] => {
370 $crate::paste! {
371 $( #[$meta] )*
372 $vis fn $field(&self) -> bool {
373 $crate::get_bit(<Self as $crate::Bitfield<_>>::value(*self), $bit)
374 }
375 }
376 };
377
378 // Special case for single-bit boolean fields
379 [
380 @field setter
381 $( #[$meta:meta] )*
382 [ $bit:literal ]
383 $vis:vis $field:ident
384 ] => {
385 $crate::paste! {
386 $( #[$meta] )*
387 #[inline(always)]
388 $vis fn [< set_ $field >](&mut self, value: bool) {
389 *self = self.[< with_ $field >](value);
390 }
391
392 $( #[$meta] )*
393 $vis fn [< with_ $field >](&mut self, value: bool) -> Self {
394 let packed = <Self as $crate::Bitfield<_>>::value(*self);
395 <Self as $crate::Bitfield<_>>::new(
396 $crate::set_bit(packed, $bit, value))
397 }
398 }
399 };
400
401 // A field type and both range bounds are required in all other cases.
402 // When no explicit interface type is given, use the underlying type.
403 [
404 @field $accessor_type:tt
405 $( #[$meta:meta] )*
406 [ $lsb:literal .. $msb:literal ]
407 $vis:vis $field:ident
408 : $field_type:ty
409 ] => {
410 $crate::bitfield_accessors! {
411 @field $accessor_type
412 $( #[$meta] )*
413 [$lsb..$msb] $vis $field: $field_type as $field_type
414 }
415 };
416
417 [
418 @field $accessor_type:tt
419 $( #[$meta:meta] )*
420 [ $lsb:literal ..= $msb:literal ]
421 $vis:vis $field:ident
422 : $field_type:ty
423 ] => {
424 $crate::bitfield_accessors! {
425 @field $accessor_type
426 $( #[$meta] )*
427 [$lsb..=$msb] $vis $field: $field_type as $field_type
428 }
429 };
430
431 [
432 @field getter
433 $( #[$meta:meta] )*
434 [ $lsb:literal .. $msb:literal ]
435 $vis:vis $field:ident
436 : $underlying_type:ty as $interface_type:ty
437 ] => {
438 $crate::paste! {
439 $( #[$meta] )*
440 $vis fn $field(&self) -> $interface_type {
441 use $crate::TruncateInto;
442 let packed = <Self as $crate::Bitfield<_>>::value(*self);
443 let underlying: $underlying_type =
444 $crate::get_bits(packed, $lsb, $msb).truncate_into();
445 underlying.into()
446 }
447 }
448 };
449
450 [
451 @field getter
452 $( #[$meta:meta] )*
453 [ $lsb:literal ..= $msb:literal ]
454 $vis:vis $field:ident
455 : $underlying_type:ty as $interface_type:ty
456 ] => {
457 $crate::paste! {
458 $( #[$meta] )*
459 $vis fn $field(&self) -> $interface_type {
460 use $crate::TruncateInto;
461 let packed = <Self as $crate::Bitfield<_>>::value(*self);
462 let underlying: $underlying_type =
463 $crate::get_bits(packed, $lsb, $msb + 1).truncate_into();
464 underlying.into()
465 }
466 }
467 };
468
469 [
470 @field setter
471 $( #[$meta:meta] )*
472 [ $lsb:literal .. $msb:literal ]
473 $vis:vis $field:ident
474 : $underlying_type:ty as $interface_type:ty
475 ] => {
476 $crate::paste! {
477 $( #[$meta] )*
478 #[inline(always)]
479 $vis fn [< set_ $field >](&mut self, value: $interface_type) {
480 *self = self.[< with_ $field >](value);
481 }
482
483 $( #[$meta] )*
484 $vis fn [< with_ $field >](&self, value: $interface_type) -> Self {
485 let underlying: $underlying_type = value.into();
486 let packed = <Self as $crate::Bitfield<_>>::value(*self);
487 <Self as $crate::Bitfield<_>>::new(
488 $crate::set_bits(packed, $lsb, $msb, underlying.into()))
489 }
490 }
491 };
492
493 [
494 @field setter
495 $( #[$meta:meta] )*
496 [ $lsb:literal ..= $msb:literal ]
497 $vis:vis $field:ident
498 : $underlying_type:ty as $interface_type:ty
499 ] => {
500 $crate::paste! {
501 $( #[$meta] )*
502 #[inline(always)]
503 $vis fn [< set_ $field >](&mut self, value: $interface_type) {
504 *self = self.[< with_ $field >](value);
505 }
506
507 $( #[$meta] )*
508 $vis fn [< with_ $field >](&self, value: $interface_type) -> Self {
509 let underlying: $underlying_type = value.into();
510 let packed = <Self as $crate::Bitfield<_>>::value(*self);
511 <Self as $crate::Bitfield<_>>::new(
512 $crate::set_bits(packed, $lsb, $msb + 1, underlying.into()))
513 }
514 }
515 };
516}
517
518/// Get a boolean reflecting a single bit of the value.
519///
520/// `bit_num` starts as zero for the least significant bit.
521///
522/// ```
523/// # use tartan_bitfield::get_bit;
524/// assert_eq!(get_bit(0b0000_0100_u8, 2), true);
525/// assert_eq!(get_bit(0b0000_0100_u8, 3), false);
526/// ```
527#[must_use]
528pub fn get_bit<T>(val: T, bit_num: u8) -> bool
529where
530 T: Default
531 + PartialEq
532 + From<bool>
533 + ops::BitAnd<T, Output = T>
534 + ops::Shl<u8, Output = T>,
535{
536 let position_mask = T::from(true) << bit_num;
537 (val & position_mask) != T::default()
538}
539
540/// Create a copy of the value with a single bit modified.
541///
542/// `bit_num` starts as zero for the least significant bit.
543///
544/// ```
545/// # use tartan_bitfield::set_bit;
546/// assert_eq!(set_bit(0b0000_0000_u8, 5, true), 0b0010_0000);
547/// assert_eq!(set_bit(0b1111_1111_u8, 0, false), 0b1111_1110);
548/// ```
549#[must_use]
550pub fn set_bit<T>(val: T, bit_num: u8, bit_val: bool) -> T
551where
552 T: From<bool>
553 + ops::BitAnd<Output = T>
554 + ops::BitOr<Output = T>
555 + ops::Shl<u8, Output = T>
556 + ops::Not<Output = T>,
557{
558 let value_mask = T::from(bit_val) << bit_num;
559 let position_mask = T::from(true) << bit_num;
560 val & position_mask.not() | value_mask
561}
562
563/// Extract a range of bits from the value, shifted so the first bit of the subset is the
564/// least significant bit of the result.
565///
566/// Bits are numbered starting with zero for the least significant bit. The range of bits
567/// in the result is `lsb..msb`, **exclusive** of `msb`.
568///
569/// ```
570/// # use tartan_bitfield::get_bits;
571/// assert_eq!(get_bits(0b1100_1110_u8, 3, 7), 0b1001);
572/// assert_eq!(get_bits(0b1010_0101_u8, 6, 8), 0b10);
573/// ```
574#[must_use]
575pub fn get_bits<T>(packed_val: T, lsb: u8, msb: u8) -> T
576where
577 T: Default
578 + OverflowingShl
579 + OverflowingShr
580 + ops::Not<Output = T>
581 + ops::BitAnd<T, Output = T>,
582{
583 let field_width = msb - lsb;
584 // e.g., 0b0000_0111 for U with a width 3 bits from its MSB to LSB
585 let field_width_mask = T::default().not().saturating_shl(field_width.into()).not();
586 packed_val.saturating_shr(lsb.into()) & field_width_mask
587}
588
589/// Create a copy of the value with a subset of bits updated based on the passed value.
590///
591/// Bits are numbered starting with zero for the least significant bit. The range of
592/// updated bits is `lsb..msb`, **exclusive** of `msb`. `field_val` is shifted left `lsb`
593/// bits before being combined with `packed_val`.
594///
595/// ```
596/// # use tartan_bitfield::set_bits;
597/// assert_eq!(set_bits(0b0000_0000_u8, 6, 8, 0b11), 0b1100_0000);
598/// assert_eq!(set_bits(0b1111_1111_u8, 1, 5, 0b0000), 0b1110_0001);
599/// assert_eq!(set_bits(0b1010_0110_u8, 2, 6, 0b1110), 0b1011_1010);
600/// ```
601#[must_use]
602pub fn set_bits<T>(packed_val: T, lsb: u8, msb: u8, field_val: T) -> T
603where
604 T: Default
605 + Copy
606 + OverflowingShl
607 + ops::Shl<u8, Output = T>
608 + ops::Not<Output = T>
609 + ops::BitAnd<T, Output = T>
610 + ops::BitOr<T, Output = T>,
611{
612 // e.g., 0b1110_0000 for MSB = 5 (exclusive)
613 let msb_mask = T::default().not().saturating_shl(msb.into());
614 // e.g., 0b0000_0011 for LSB = 2
615 let lsb_mask = T::default().not().saturating_shl(lsb.into()).not();
616 // e.g., 0b1110_0011 for MSB = 5, LSB = 2
617 let position_mask = msb_mask | lsb_mask;
618 let value_mask = field_val.saturating_shl(lsb.into()) & position_mask.not();
619 packed_val & position_mask | value_mask
620}
621
622/// A type whose values can be truncated into another type. This is more explicit than
623/// `x as T`.
624pub trait TruncateInto<T> {
625 /// Truncate the value to fit in the destination type
626 fn truncate_into(self) -> T;
627}
628
629macro_rules! truncate_into_impl {
630 ($source:ty, $dest:ty) => {
631 impl TruncateInto<$dest> for $source {
632 #[inline(always)]
633 #[allow(clippy::cast_possible_truncation)]
634 fn truncate_into(self) -> $dest {
635 self as $dest
636 }
637 }
638 };
639}
640
641truncate_into_impl!(u128, u128);
642truncate_into_impl!(u128, u64);
643truncate_into_impl!(u128, u32);
644truncate_into_impl!(u128, u16);
645truncate_into_impl!(u128, u8);
646
647truncate_into_impl!(u64, u64);
648truncate_into_impl!(u64, u32);
649truncate_into_impl!(u64, u16);
650truncate_into_impl!(u64, u8);
651
652truncate_into_impl!(u32, u32);
653truncate_into_impl!(u32, u16);
654truncate_into_impl!(u32, u8);
655
656truncate_into_impl!(u16, u16);
657truncate_into_impl!(u16, u8);
658
659truncate_into_impl!(u8, u8);
660
661truncate_into_impl!(usize, usize);
662#[cfg(target_pointer_width = "64")]
663truncate_into_impl!(usize, u64);
664#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
665truncate_into_impl!(usize, u32);
666#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
667truncate_into_impl!(usize, u16);
668#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
669truncate_into_impl!(usize, u8);
670
671/// A type with an overflowing left shift operation. Also adds a saturating version.
672///
673/// All basic numeric types have this operation, but there is no corresponding trait in
674/// [`core::ops`].
675pub trait OverflowingShl
676where
677 Self: Sized + Default,
678{
679 /// Shift the value left by `n mod m` bits, where `m` is the number of bits in the
680 /// type. Return the shifted value along with a boolean indicating whether the shift
681 /// count was wrapped.
682 ///
683 /// Since this behavior is counterintuitive and practically useless, see
684 /// [`saturating_shl`](Self::saturating_shl) for an alternative that behaves the way
685 /// you probably expect.
686 fn overflowing_shl(self, n: u32) -> (Self, bool);
687
688 /// Shift the value left by `n` bits. If `n` is greater than or equal to the number
689 /// of bits in this type, the result will be zero.
690 #[inline(always)]
691 #[must_use]
692 fn saturating_shl(self, n: u32) -> Self {
693 match self.overflowing_shl(n) {
694 (_, true) => Self::default(),
695 (x, _) => x,
696 }
697 }
698}
699
700macro_rules! overflowing_shl_impl {
701 ($type:ty) => {
702 impl OverflowingShl for $type {
703 #[inline(always)]
704 fn overflowing_shl(self, n: u32) -> (Self, bool) {
705 self.overflowing_shl(n)
706 }
707 }
708 };
709}
710
711overflowing_shl_impl!(u8);
712overflowing_shl_impl!(u16);
713overflowing_shl_impl!(u32);
714overflowing_shl_impl!(u64);
715overflowing_shl_impl!(u128);
716overflowing_shl_impl!(usize);
717
718/// A type with an overflowing right shift operation. Also adds a saturating version.
719///
720/// All basic numeric types have this operation, but there is no corresponding trait in
721/// [`core::ops`].
722pub trait OverflowingShr
723where
724 Self: Sized + Default,
725{
726 /// Shift the value right by `n mod m` bits, where `m` is the number of bits in the
727 /// type. Return the shifted value along with a boolean indicating whether the shift
728 /// count was wrapped.
729 ///
730 /// Since this behavior is counterintuitive and practically useless, see
731 /// [`saturating_shr`](Self::saturating_shr) for an alternative that behaves the way
732 /// you probably expect.
733 fn overflowing_shr(self, n: u32) -> (Self, bool);
734
735 /// Shift the value right by `n` bits. If `n` is greater than or equal to the number
736 /// of bits in this type, the result will be zero.
737 #[inline(always)]
738 #[must_use]
739 fn saturating_shr(self, n: u32) -> Self {
740 match self.overflowing_shr(n) {
741 (_, true) => Self::default(),
742 (x, _) => x,
743 }
744 }
745}
746
747macro_rules! overflowing_shr_impl {
748 ($type:ty) => {
749 impl OverflowingShr for $type {
750 #[inline(always)]
751 fn overflowing_shr(self, n: u32) -> (Self, bool) {
752 self.overflowing_shr(n)
753 }
754 }
755 };
756}
757
758overflowing_shr_impl!(u8);
759overflowing_shr_impl!(u16);
760overflowing_shr_impl!(u32);
761overflowing_shr_impl!(u64);
762overflowing_shr_impl!(u128);
763overflowing_shr_impl!(usize);