packed_flags/
bitsize.rs

1use std::{ops::{
2    BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Index, Not, Shl, ShlAssign,
3    Shr, ShrAssign, Sub,}, fmt::{UpperHex, LowerHex, Octal, Binary}};
4
5use crate::{flag_iter, Blong, FlagLs, B128, B32, B64, FlagLsError};
6
7#[derive(PartialEq, Eq, Default, Clone, Copy, Debug, Hash)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9/// A list of flags/bitfield up to the size of a pointer
10/// 
11/// This is only really useful if you need to deal with `usize`s for some other reason
12pub struct Bsize {
13    inner: usize,
14    len: usize,
15}
16impl Bsize {
17    fn lower_mask(point: usize) -> usize {
18        if point > Self::MAX_LENGTH {
19            panic!(
20                "Cannot create mask more than {} bits for Bsize",
21                Self::MAX_LENGTH
22            )
23        } else {
24            (1 << point) - 1
25        }
26    }
27    const fn inner(&self) -> usize {
28        self.inner
29    }
30    /// Converts the bitfield into its integer representation, a usize, consuming it
31    /// # Examples
32    /// The most common use case would be doing bitwise operations with a non-FlagLs item
33    /// Here we bitwisexor the inner state with an arbitrary usze number and then rebuild the flaglist into a result
34    /// ```
35    /// use packed_flags::Bsize;
36    /// use packed_flags::FlagLs;
37    /// use std::ops::BitXor;
38    /// 
39    /// let bitflags= Bsize::from_iter(vec![false,true,false,true,false,true,false,true]);
40    /// let other: usize = 3198; //presumably this other value would come from some external source
41    /// let updated = bitflags.as_inner().bitxor(&other);
42    /// let res = Bsize::initialize(updated,8);
43    ///
44    /// ```
45    #[must_use]
46    pub const fn as_inner(self) -> usize {
47        self.inner
48    }
49    fn uper_mask(point: usize) -> usize {
50        if point > Self::MAX_LENGTH {
51            panic!("Cannot mask above the end of the list");
52        } else {
53            usize::MAX - (1 << point) + 1
54        }
55    }
56    /// Create a new blank empty list of flags
57    #[must_use]
58    pub fn new() -> Self {
59        Self::default()
60    }
61    #[must_use]
62    /// Create a new `Bsize` from a `usize` and a length
63    /// 
64    /// Will truncate len to `MAX_LENGTH` and will truncate inner to len bits
65    /// # Examples
66    /// See [`as_inner`][Bsize::as_inner]
67    pub fn initialize(inner: usize, len: usize) -> Self {
68        let len =len.min(Self::MAX_LENGTH);
69        let mut out=Self { inner, len};
70        out.set_len(len);
71        out
72    }
73}
74impl Index<usize> for Bsize {
75    type Output = bool;
76    fn index(&self, index: usize) -> &Self::Output {
77        assert!(index < self.len, "Cannot access out of bounds index");
78        if (self.inner >> index) & 1 == 1 {
79            &true
80        } else {
81            &false
82        }
83    }
84}
85impl FlagLs for Bsize {
86    const MAX_LENGTH: usize = usize::BITS as usize;
87
88    fn len(&self) -> usize {
89        self.len
90    }
91
92    fn set_len(&mut self, new_len: usize) {
93        assert!(new_len <= Self::MAX_LENGTH, "Cannot set length to a length larger than {} for Bsize", Self::MAX_LENGTH);
94        self.len = new_len;
95        self.inner &= (1 << new_len) - 1;
96    }
97
98    fn insert(&mut self, index: usize, flag: bool) {
99        if index > self.len {
100            panic!("Cannot insert out of bounds");
101        } else if self.len == Self::MAX_LENGTH {
102            panic!("cannot insert to full list of flags")
103        } else {
104            let uper = self.inner & Self::uper_mask(index);
105            let lower = self.inner & Self::lower_mask(index);
106            self.inner = (uper << 1) + (usize::from(flag) << index) + lower;
107            self.len += 1;
108        }
109    }
110
111    fn remove(&mut self, index: usize) -> bool {
112        if index >= self.len {
113            panic!("Cannot remove out of bounds");
114        } else {
115            let uper = self.inner & Self::uper_mask(index + 1);
116            let lower = self.inner & Self::lower_mask(index);
117            let out = (self.inner >> index) & 1;
118            self.inner = (uper >> 1) + lower;
119            self.len -= 1;
120            out == 1
121        }
122    }
123
124    fn clear(&mut self) {
125        self.inner = 0;
126        self.len = 0;
127    }
128
129    fn get(&self, index: usize) -> Option<bool> {
130        if index<self.len{
131            Some((self.inner >> index) & 1 == 1)   
132        } else {
133            None
134        }
135    }
136
137    fn set(&mut self, index: usize, flag: bool) {
138        if index < self.len() {
139            let uper = self.inner & Self::uper_mask(index + 1);
140            let lower = self.inner & Self::lower_mask(index);
141            self.inner = uper + ((usize::from(flag)) << index) + lower;
142        } else {
143            panic!("Cannot set out of bounds")
144        }
145    }
146
147    fn iter(&self) -> flag_iter::Iter<Self> {
148        flag_iter::Iter::new(self)
149    }
150}
151impl BitAnd<Self> for Bsize {
152    type Output = Self;
153
154    fn bitand(self, rhs: Self) -> Self::Output {
155        Self{inner: self.inner() & rhs.inner(),len:self.len().max(rhs.len())}
156    }
157}
158impl BitAndAssign<Self> for Bsize {
159    fn bitand_assign(&mut self, rhs: Self) {
160        self.inner &= rhs.inner();
161        self.len = self.len.max(rhs.len());
162    }
163}
164impl BitOr<Self> for Bsize {
165    type Output = Self;
166    fn bitor(self, rhs: Self) -> Self::Output {
167        Self{inner: self.inner() | rhs.inner(),len:self.len().max(rhs.len())}
168    }
169}
170impl BitOrAssign<Self> for Bsize {
171    fn bitor_assign(&mut self, rhs: Self) {
172        self.inner |= rhs.inner();
173        self.len = self.len.max(rhs.len());
174    }
175}
176impl BitXor<Self> for Bsize {
177    type Output = Self;
178    fn bitxor(self, rhs: Self) -> Self::Output {
179        Self{inner:self.inner().bitxor(rhs.inner()),len:self.len().max(rhs.len())}
180    }
181}
182impl BitXorAssign<Self> for Bsize {
183    fn bitxor_assign(&mut self, rhs: Self) {
184        self.inner.bitxor_assign(rhs.inner());
185        self.len = self.len.max(rhs.len());
186    }
187}
188impl Shl<usize> for Bsize {
189    type Output = Self;
190    fn shl(self, rhs: usize) -> Self::Output {
191        Self{inner:self.inner<<rhs, len:(self.len + rhs).min(Self::MAX_LENGTH)}
192    }
193}
194#[allow(clippy::suspicious_op_assign_impl)]
195impl ShlAssign<usize> for Bsize {
196    fn shl_assign(&mut self, rhs: usize) {
197        self.inner.shl_assign(rhs);
198        self.len = (self.len + rhs).min(Self::MAX_LENGTH);
199    }
200}
201impl Shr<usize> for Bsize {
202    type Output = Self;
203    fn shr(self, rhs: usize) -> Self::Output {
204        let new_len = if self.len > rhs { self.len - rhs } else { 0 };
205        Self{inner:self.inner>>rhs,len:new_len}
206    }
207}
208impl ShrAssign<usize> for Bsize {
209    fn shr_assign(&mut self, rhs: usize) {
210        self.inner.shr_assign(rhs);
211        self.len = if self.len > rhs { self.len - rhs } else { 0 };
212    }
213}
214impl Not for Bsize {
215    type Output = Self;
216    fn not(self) -> Self::Output {
217        Self{inner: (!self.inner) & Self::lower_mask(self.len),len:self.len}
218    }
219}
220impl Sub<Self> for Bsize {
221    type Output = Self;
222    ///note subtraction is set difference
223    fn sub(self, rhs: Self) -> Self::Output {
224        Self{inner:self.inner&(!rhs.inner),len:self.len}
225    }
226}
227impl TryFrom<B32> for Bsize{
228    type Error = FlagLsError;
229    fn try_from(value: B32) -> Result<Self, Self::Error> {
230        let len = value.len();
231        match len.cmp(&Self::MAX_LENGTH){
232            std::cmp::Ordering::Greater=> Err(FlagLsError::MaximumLengthExceeded { mx_len: Self::MAX_LENGTH, attempt_len: len }),
233            _=>Ok(Self { inner: value.as_inner().try_into().expect("Infalible"), len })
234        }
235    }
236}
237impl TryFrom<B64> for Bsize{
238    type Error = FlagLsError;
239    fn try_from(value: B64) -> Result<Self, Self::Error> {
240        let len = value.len();
241        match len.cmp(&Self::MAX_LENGTH){
242            std::cmp::Ordering::Greater=> Err(FlagLsError::MaximumLengthExceeded { mx_len: Self::MAX_LENGTH, attempt_len: len }),
243            _=>Ok(Self { inner: value.as_inner().try_into().expect("Infalible"), len })
244        }
245    }
246}
247impl TryFrom<B128> for Bsize{
248    type Error = FlagLsError;
249    fn try_from(value: B128) -> Result<Self, Self::Error> {
250        let len = value.len();
251        match len.cmp(&Self::MAX_LENGTH){
252            std::cmp::Ordering::Greater=> Err(FlagLsError::MaximumLengthExceeded { mx_len: Self::MAX_LENGTH, attempt_len: len }),
253            _=>Ok(Self { inner: value.as_inner().try_into().expect("Unreachable"), len })
254        }
255    }
256}
257impl TryFrom<Blong> for Bsize{
258    type Error = FlagLsError;
259    fn try_from(value: Blong) -> Result<Self, Self::Error> {
260        let len = value.len();
261        match len.cmp(&Self::MAX_LENGTH){
262            std::cmp::Ordering::Greater=> Err(FlagLsError::MaximumLengthExceeded { mx_len: Self::MAX_LENGTH, attempt_len: len }),
263            _=>Ok(Self { inner: *value.as_inner().first().unwrap_or(&0), len })
264        }
265    }
266}
267impl UpperHex for Bsize{
268    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
269        write!(f,"{:X}",self.inner)
270    }
271}
272impl LowerHex for Bsize{
273    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274        write!(f,"{:x}",self.inner)
275    }
276}
277impl Octal for Bsize{
278    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
279        write!(f,"{:o}",self.inner)
280    }
281}
282impl Binary for Bsize{
283    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
284        write!(f,"{:b}",self.inner)
285    }
286}