zkp_u256/traits/
binary.rs1#![allow(clippy::module_name_repetitions)]
3use num_traits::PrimInt;
4use std::ops::{
5 BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, ShlAssign, Shr,
6 ShrAssign,
7};
8
9pub trait Binary:
12 Sized
13 + Not<Output = Self>
14 + BitAnd<Output = Self>
15 + BitOr<Output = Self>
16 + BitXor<Output = Self>
17 + Shl<usize, Output = Self>
18 + Shr<usize, Output = Self>
19{
20 fn num_bits() -> usize;
21
22 fn bit(&self, i: usize) -> bool;
26
27 fn count_ones(&self) -> usize;
28 fn count_zeros(&self) -> usize;
29 fn leading_zeros(&self) -> usize;
30 fn trailing_zeros(&self) -> usize;
31
32 fn rotate_left(&self, n: usize) -> Self;
33 fn rotate_right(&self, n: usize) -> Self;
34
35 fn bits(&self) -> usize {
37 Self::num_bits() - self.leading_zeros()
38 }
39
40 fn most_significant_bit(&self) -> Option<usize> {
42 (Self::num_bits() - 1).checked_sub(self.leading_zeros())
43 }
44}
45
46impl<T: PrimInt> Binary for T {
48 #[inline(always)]
49 fn num_bits() -> usize {
50 Self::zero().count_zeros() as usize
51 }
52
53 fn bit(&self, i: usize) -> bool {
54 (*self >> i) & Self::one() == Self::one()
55 }
56
57 fn count_ones(&self) -> usize {
58 <Self as PrimInt>::count_ones(*self) as usize
59 }
60
61 fn count_zeros(&self) -> usize {
62 <Self as PrimInt>::count_zeros(*self) as usize
63 }
64
65 fn leading_zeros(&self) -> usize {
66 <Self as PrimInt>::leading_zeros(*self) as usize
67 }
68
69 fn trailing_zeros(&self) -> usize {
70 <Self as PrimInt>::trailing_zeros(*self) as usize
71 }
72
73 fn rotate_left(&self, n: usize) -> Self {
74 #[allow(clippy::cast_possible_truncation)]
76 <Self as PrimInt>::rotate_left(*self, n as u32)
77 }
78
79 fn rotate_right(&self, n: usize) -> Self {
80 #[allow(clippy::cast_possible_truncation)]
82 <Self as PrimInt>::rotate_right(*self, n as u32)
83 }
84}
85
86pub trait BinaryOps<Rhs = Self, Output = Self>:
87 Not<Output = Output>
88 + BitAnd<Rhs, Output = Output>
89 + BitOr<Rhs, Output = Output>
90 + BitXor<Rhs, Output = Output>
91{
92}
93
94pub trait BinaryAssignOps<Rhs = Self>:
95 BitAndAssign<Rhs> + BitOrAssign<Rhs> + BitXorAssign<Rhs> + ShlAssign<usize> + ShrAssign<usize>
96{
97}
98
99impl<T, Rhs> BinaryAssignOps<Rhs> for T where
100 T: BitAndAssign<Rhs>
101 + BitOrAssign<Rhs>
102 + BitXorAssign<Rhs>
103 + ShlAssign<usize>
104 + ShrAssign<usize>
105{
106}
107
108#[allow(single_use_lifetimes)]
110pub trait BinaryAssignRef: for<'r> BinaryAssignOps<&'r Self> {}
111
112#[allow(single_use_lifetimes)]
114impl<T> BinaryAssignRef for T where T: for<'r> BinaryAssignOps<&'r T> {}