bit_bounds/
lib.rs

1//!
2//! Helper traits for const generic bounds
3//!
4//! ```rust
5//! #![allow(incomplete_features)]
6//! #![feature(generic_const_exprs)]
7//!
8//! use bit_bounds::{IsPowerOf2, usize::*};
9//!
10//! struct Buffer<const N: usize> {
11//!   inner: [usize; N],
12//! }
13//!
14//! impl<const N: usize> Buffer<N>
15//! where
16//!   Int<N>: IsPowerOf2
17//! {
18//!   pub const fn new() -> Self {
19//!     Buffer { inner: [0; N] }
20//!   }
21//! }
22//!
23//! fn extract_index<const N: usize>(counter: usize) -> usize
24//! where
25//!   Int<N>: IsPowerOf2,
26//!   Int<N>: BitsAllClear<{ (u32::MAX as usize) << 32 }>,
27//! {
28//!   (counter >> 32) & (N - 1)
29//! }
30//! ```
31
32#![allow(incomplete_features)]
33#![feature(generic_const_exprs)]
34
35#![no_std]
36
37use const_assert::{Assert, IsTrue};
38
39pub trait IsPowerOf2 {}
40
41macro_rules! define_bit_bounds {
42  ($ty:ident) => {
43    pub mod $ty {
44      use super::*;
45      pub trait BitsAllSet<const M: $ty> {}
46      pub trait BitsAnySet<const M: $ty> {}
47      pub trait BitsAllClear<const M: $ty> {}
48      pub trait BitsAnyClear<const M: $ty> {}
49
50      pub struct Int<const N: $ty>;
51      impl<const N: $ty> IsPowerOf2 for Int<N> where Assert<{ N == N.next_power_of_two() }>: IsTrue {}
52      impl<const N: $ty, const M: $ty> BitsAllSet<M> for Int<N> where Assert<{ N & M == M }>: IsTrue {}
53      impl<const N: $ty, const M: $ty> BitsAnySet<M> for Int<N> where Assert<{ N & M != 0 }>: IsTrue {}
54      impl<const N: $ty, const M: $ty> BitsAllClear<M> for Int<N> where Assert<{ (N ^ M) & M == M }>: IsTrue {}
55      impl<const N: $ty, const M: $ty> BitsAnyClear<M> for Int<N> where Assert<{ N & M != M }>: IsTrue {}
56    }
57  };
58}
59
60define_bit_bounds!(u8);
61define_bit_bounds!(u16);
62define_bit_bounds!(u32);
63define_bit_bounds!(u64);
64define_bit_bounds!(u128);
65define_bit_bounds!(usize);