bitvec/
view.rs

1#![doc = include_str!("../doc/view.md")]
2
3use core::slice;
4
5use crate::{
6	array::BitArray,
7	order::BitOrder,
8	ptr::BitSpanError,
9	slice::BitSlice,
10	store::BitStore,
11};
12
13#[doc = include_str!("../doc/view/BitView.md")]
14pub trait BitView {
15	/// The underlying element type.
16	type Store: BitStore;
17
18	/// Views a memory region as an immutable bit-slice.
19	fn view_bits<O>(&self) -> &BitSlice<Self::Store, O>
20	where O: BitOrder;
21
22	/// Attempts to view a memory region as an immutable bit-slice.
23	///
24	/// This may return an error if `self` is too long to view as a bit-slice.
25	fn try_view_bits<O>(
26		&self,
27	) -> Result<&BitSlice<Self::Store, O>, BitSpanError<Self::Store>>
28	where O: BitOrder;
29
30	/// Views a memory region as a mutable bit-slice.
31	fn view_bits_mut<O>(&mut self) -> &mut BitSlice<Self::Store, O>
32	where O: BitOrder;
33
34	/// Attempts to view a memory region as a mutable bit-slice.
35	///
36	/// This may return an error if `self` is too long to view as a bit-slice.
37	fn try_view_bits_mut<O>(
38		&mut self,
39	) -> Result<&mut BitSlice<Self::Store, O>, BitSpanError<Self::Store>>
40	where O: BitOrder;
41}
42
43#[cfg(not(tarpaulin_include))]
44impl<T> BitView for T
45where T: BitStore
46{
47	type Store = Self;
48
49	fn view_bits<O>(&self) -> &BitSlice<T, O>
50	where O: BitOrder {
51		BitSlice::from_element(self)
52	}
53
54	fn try_view_bits<O>(&self) -> Result<&BitSlice<T, O>, BitSpanError<T>>
55	where O: BitOrder {
56		Ok(BitSlice::from_element(self))
57	}
58
59	fn view_bits_mut<O>(&mut self) -> &mut BitSlice<T, O>
60	where O: BitOrder {
61		BitSlice::from_element_mut(self)
62	}
63
64	fn try_view_bits_mut<O>(
65		&mut self,
66	) -> Result<&mut BitSlice<T, O>, BitSpanError<T>>
67	where O: BitOrder {
68		Ok(BitSlice::from_element_mut(self))
69	}
70}
71
72/// Note that overly-large slices may cause the conversions to fail.
73#[cfg(not(tarpaulin_include))]
74impl<T> BitView for [T]
75where T: BitStore
76{
77	type Store = T;
78
79	#[inline]
80	fn view_bits<O>(&self) -> &BitSlice<T, O>
81	where O: BitOrder {
82		BitSlice::from_slice(self)
83	}
84
85	#[inline]
86	fn try_view_bits<O>(&self) -> Result<&BitSlice<T, O>, BitSpanError<T>>
87	where O: BitOrder {
88		BitSlice::try_from_slice(self)
89	}
90
91	#[inline]
92	fn view_bits_mut<O>(&mut self) -> &mut BitSlice<T, O>
93	where O: BitOrder {
94		BitSlice::from_slice_mut(self)
95	}
96
97	#[inline]
98	fn try_view_bits_mut<O>(
99		&mut self,
100	) -> Result<&mut BitSlice<T, O>, BitSpanError<T>>
101	where O: BitOrder {
102		BitSlice::try_from_slice_mut(self)
103	}
104}
105
106/// Note that overly-large arrays may cause the conversions to fail.
107#[cfg(not(tarpaulin_include))]
108impl<T, const N: usize> BitView for [T; N]
109where T: BitStore
110{
111	type Store = T;
112
113	#[inline]
114	fn view_bits<O>(&self) -> &BitSlice<T, O>
115	where O: BitOrder {
116		BitSlice::from_slice(self)
117	}
118
119	#[inline]
120	fn try_view_bits<O>(&self) -> Result<&BitSlice<T, O>, BitSpanError<T>>
121	where O: BitOrder {
122		BitSlice::try_from_slice(self)
123	}
124
125	#[inline]
126	fn view_bits_mut<O>(&mut self) -> &mut BitSlice<T, O>
127	where O: BitOrder {
128		BitSlice::from_slice_mut(self)
129	}
130
131	#[inline]
132	fn try_view_bits_mut<O>(
133		&mut self,
134	) -> Result<&mut BitSlice<T, O>, BitSpanError<T>>
135	where O: BitOrder {
136		BitSlice::try_from_slice_mut(self)
137	}
138}
139
140/// Helper trait for scalars and arrays, but not slices.
141pub trait BitViewSized: BitView + Sized {
142	/// The zero constant.
143	const ZERO: Self;
144
145	/// Wraps `self` in a `BitArray`.
146	#[inline]
147	fn into_bitarray<O>(self) -> BitArray<Self, O>
148	where O: BitOrder {
149		BitArray::new(self)
150	}
151
152	/// Views the type as a slice of its elements.
153	fn as_raw_slice(&self) -> &[Self::Store];
154
155	/// Views the type as a mutable slice of its elements.
156	fn as_raw_mut_slice(&mut self) -> &mut [Self::Store];
157}
158
159impl<T> BitViewSized for T
160where T: BitStore
161{
162	const ZERO: Self = <T as BitStore>::ZERO;
163
164	#[inline]
165	fn as_raw_slice(&self) -> &[Self::Store] {
166		slice::from_ref(self)
167	}
168
169	#[inline]
170	fn as_raw_mut_slice(&mut self) -> &mut [Self::Store] {
171		slice::from_mut(self)
172	}
173}
174
175impl<T, const N: usize> BitViewSized for [T; N]
176where T: BitStore
177{
178	const ZERO: Self = [T::ZERO; N];
179
180	#[inline]
181	fn as_raw_slice(&self) -> &[Self::Store] {
182		&self[..]
183	}
184
185	#[inline]
186	fn as_raw_mut_slice(&mut self) -> &mut [Self::Store] {
187		&mut self[..]
188	}
189}
190
191#[doc = include_str!("../doc/view/AsBits.md")]
192pub trait AsBits<T>
193where T: BitStore
194{
195	/// Views `self` as an immutable bit-slice region with the `O` ordering.
196	fn as_bits<O>(&self) -> &BitSlice<T, O>
197	where O: BitOrder;
198
199	/// Attempts to view `self` as an immutable bit-slice region with the `O`
200	/// ordering.
201	///
202	/// This may return an error if `self` is too long to view as a bit-slice.
203	fn try_as_bits<O>(&self) -> Result<&BitSlice<T, O>, BitSpanError<T>>
204	where O: BitOrder;
205}
206
207#[doc = include_str!("../doc/view/AsMutBits.md")]
208pub trait AsMutBits<T>
209where T: BitStore
210{
211	/// Views `self` as a mutable bit-slice region with the `O` ordering.
212	fn as_mut_bits<O>(&mut self) -> &mut BitSlice<T, O>
213	where O: BitOrder;
214
215	/// Attempts to view `self` as a mutable bit-slice region with the `O`
216	/// ordering.
217	///
218	/// This may return an error if `self` is too long to view as a bit-slice.
219	fn try_as_mut_bits<O>(
220		&mut self,
221	) -> Result<&mut BitSlice<T, O>, BitSpanError<T>>
222	where O: BitOrder;
223}
224
225#[cfg(not(tarpaulin_include))]
226impl<A, T> AsBits<T> for A
227where
228	A: AsRef<[T]>,
229	T: BitStore,
230{
231	#[inline]
232	fn as_bits<O>(&self) -> &BitSlice<T, O>
233	where O: BitOrder {
234		self.as_ref().view_bits::<O>()
235	}
236
237	#[inline]
238	fn try_as_bits<O>(&self) -> Result<&BitSlice<T, O>, BitSpanError<T>>
239	where O: BitOrder {
240		self.as_ref().try_view_bits::<O>()
241	}
242}
243
244#[cfg(not(tarpaulin_include))]
245impl<A, T> AsMutBits<T> for A
246where
247	A: AsMut<[T]>,
248	T: BitStore,
249{
250	#[inline]
251	fn as_mut_bits<O>(&mut self) -> &mut BitSlice<T, O>
252	where O: BitOrder {
253		self.as_mut().view_bits_mut::<O>()
254	}
255
256	#[inline]
257	fn try_as_mut_bits<O>(
258		&mut self,
259	) -> Result<&mut BitSlice<T, O>, BitSpanError<T>>
260	where O: BitOrder {
261		self.as_mut().try_view_bits_mut::<O>()
262	}
263}
264
265#[cfg(test)]
266mod tests {
267	use static_assertions::*;
268
269	use super::*;
270	use crate::prelude::*;
271
272	#[test]
273	fn implementations() {
274		let mut byte = 0u8;
275		let mut bytes = [0u8; 2];
276		assert!(byte.view_bits::<LocalBits>().not_any());
277		assert!(byte.view_bits_mut::<LocalBits>().not_any());
278		assert!(bytes.view_bits::<LocalBits>().not_any());
279		assert!(bytes.view_bits_mut::<LocalBits>().not_any());
280		assert!(bytes[..].view_bits::<LocalBits>().not_any());
281		assert!(bytes[..].view_bits_mut::<LocalBits>().not_any());
282
283		let mut blank: [u8; 0] = [];
284		assert!(blank.view_bits::<LocalBits>().is_empty());
285		assert!(blank.view_bits_mut::<LocalBits>().is_empty());
286
287		assert_eq!([0u32; 2].as_bits::<LocalBits>().len(), 64);
288		assert_eq!([0u32; 2].as_mut_bits::<LocalBits>().len(), 64);
289
290		assert_eq!(0usize.as_raw_slice().len(), 1);
291		assert_eq!(0usize.as_raw_mut_slice().len(), 1);
292		assert_eq!(0u32.into_bitarray::<LocalBits>().len(), 32);
293
294		assert_impl_all!(
295			[usize; 10]: AsBits<usize>,
296			AsMutBits<usize>,
297			BitViewSized,
298			BitView,
299		);
300	}
301}