1use core::{
4 borrow::{
5 Borrow,
6 BorrowMut,
7 },
8 cmp,
9 convert::TryFrom,
10 fmt::{
11 self,
12 Debug,
13 Display,
14 Formatter,
15 },
16 hash::{
17 Hash,
18 Hasher,
19 },
20 marker::Unpin,
21};
22
23use tap::TryConv;
24
25use super::BitArray;
26use crate::{
27 index::BitIdx,
28 mem,
29 order::BitOrder,
30 slice::BitSlice,
31 store::BitStore,
32 view::BitViewSized,
33};
34
35#[cfg(not(tarpaulin_include))]
36impl<A, O> Borrow<BitSlice<A::Store, O>> for BitArray<A, O>
37where
38 A: BitViewSized,
39 O: BitOrder,
40{
41 #[inline]
42 fn borrow(&self) -> &BitSlice<A::Store, O> {
43 self.as_bitslice()
44 }
45}
46
47#[cfg(not(tarpaulin_include))]
48impl<A, O> BorrowMut<BitSlice<A::Store, O>> for BitArray<A, O>
49where
50 A: BitViewSized,
51 O: BitOrder,
52{
53 #[inline]
54 fn borrow_mut(&mut self) -> &mut BitSlice<A::Store, O> {
55 self.as_mut_bitslice()
56 }
57}
58
59impl<A, O> Clone for BitArray<A, O>
60where
61 A: BitViewSized,
62 O: BitOrder,
63{
64 #[inline]
65 fn clone(&self) -> Self {
66 let mut out = Self::ZERO;
67 for (dst, src) in
68 out.as_raw_mut_slice().iter_mut().zip(self.as_raw_slice())
69 {
70 dst.store_value(src.load_value());
71 }
72 out
73 }
74}
75
76impl<A, O> Eq for BitArray<A, O>
77where
78 A: BitViewSized,
79 O: BitOrder,
80{
81}
82
83#[cfg(not(tarpaulin_include))]
84impl<A, O> Ord for BitArray<A, O>
85where
86 A: BitViewSized,
87 O: BitOrder,
88{
89 #[inline]
90 fn cmp(&self, other: &Self) -> cmp::Ordering {
91 self.as_bitslice().cmp(other.as_bitslice())
92 }
93}
94
95#[cfg(not(tarpaulin_include))]
96impl<O1, A, O2, T> PartialEq<BitArray<A, O2>> for BitSlice<T, O1>
97where
98 O1: BitOrder,
99 O2: BitOrder,
100 A: BitViewSized,
101 T: BitStore,
102{
103 #[inline]
104 fn eq(&self, other: &BitArray<A, O2>) -> bool {
105 self == other.as_bitslice()
106 }
107}
108
109#[cfg(not(tarpaulin_include))]
110impl<A, O, Rhs> PartialEq<Rhs> for BitArray<A, O>
111where
112 A: BitViewSized,
113 O: BitOrder,
114 Rhs: ?Sized,
115 BitSlice<A::Store, O>: PartialEq<Rhs>,
116{
117 #[inline]
118 fn eq(&self, other: &Rhs) -> bool {
119 self.as_bitslice() == other
120 }
121}
122
123#[cfg(not(tarpaulin_include))]
124impl<A, T, O> PartialOrd<BitArray<A, O>> for BitSlice<T, O>
125where
126 A: BitViewSized,
127 T: BitStore,
128 O: BitOrder,
129{
130 #[inline]
131 fn partial_cmp(&self, other: &BitArray<A, O>) -> Option<cmp::Ordering> {
132 self.partial_cmp(other.as_bitslice())
133 }
134}
135
136#[cfg(not(tarpaulin_include))]
137impl<A, O, Rhs> PartialOrd<Rhs> for BitArray<A, O>
138where
139 A: BitViewSized,
140 O: BitOrder,
141 Rhs: ?Sized,
142 BitSlice<A::Store, O>: PartialOrd<Rhs>,
143{
144 #[inline]
145 fn partial_cmp(&self, other: &Rhs) -> Option<cmp::Ordering> {
146 self.as_bitslice().partial_cmp(other)
147 }
148}
149
150#[cfg(not(tarpaulin_include))]
151impl<A, O> AsRef<BitSlice<A::Store, O>> for BitArray<A, O>
152where
153 A: BitViewSized,
154 O: BitOrder,
155{
156 #[inline]
157 fn as_ref(&self) -> &BitSlice<A::Store, O> {
158 self.as_bitslice()
159 }
160}
161
162#[cfg(not(tarpaulin_include))]
163impl<A, O> AsMut<BitSlice<A::Store, O>> for BitArray<A, O>
164where
165 A: BitViewSized,
166 O: BitOrder,
167{
168 #[inline]
169 fn as_mut(&mut self) -> &mut BitSlice<A::Store, O> {
170 self.as_mut_bitslice()
171 }
172}
173
174#[cfg(not(tarpaulin_include))]
175impl<A, O> From<A> for BitArray<A, O>
176where
177 A: BitViewSized,
178 O: BitOrder,
179{
180 #[inline]
181 fn from(data: A) -> Self {
182 Self::new(data)
183 }
184}
185
186impl<A, O> TryFrom<&BitSlice<A::Store, O>> for BitArray<A, O>
187where
188 A: BitViewSized,
189 O: BitOrder,
190{
191 type Error = TryFromBitSliceError;
192
193 #[inline]
194 fn try_from(src: &BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
195 src.try_conv::<&Self>().map(|this| this.clone())
196 }
197}
198
199impl<A, O> TryFrom<&BitSlice<A::Store, O>> for &BitArray<A, O>
200where
201 A: BitViewSized,
202 O: BitOrder,
203{
204 type Error = TryFromBitSliceError;
205
206 #[inline]
207 fn try_from(src: &BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
208 TryFromBitSliceError::new::<A, O>(src).map(|()| unsafe {
209 &*src
210 .as_bitspan()
211 .address()
212 .to_const()
213 .cast::<BitArray<A, O>>()
214 })
215 }
216}
217
218impl<A, O> TryFrom<&mut BitSlice<A::Store, O>> for &mut BitArray<A, O>
219where
220 A: BitViewSized,
221 O: BitOrder,
222{
223 type Error = TryFromBitSliceError;
224
225 #[inline]
226 fn try_from(src: &mut BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
227 TryFromBitSliceError::new::<A, O>(src).map(|()| unsafe {
228 &mut *src
229 .as_mut_bitspan()
230 .address()
231 .to_mut()
232 .cast::<BitArray<A, O>>()
233 })
234 }
235}
236
237impl<A, O> Default for BitArray<A, O>
238where
239 A: BitViewSized,
240 O: BitOrder,
241{
242 #[inline]
243 fn default() -> Self {
244 Self::ZERO
245 }
246}
247
248impl<A, O> Debug for BitArray<A, O>
249where
250 A: BitViewSized,
251 O: BitOrder,
252{
253 #[inline]
254 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
255 self.as_bitspan().render(fmt, "Array", None)?;
256 fmt.write_str(" ")?;
257 Display::fmt(self, fmt)
258 }
259}
260
261easy_fmt! {
262 impl Binary
263 impl Display
264 impl LowerHex
265 impl Octal
266 impl UpperHex
267 for BitArray
268}
269
270#[cfg(not(tarpaulin_include))]
271impl<A, O> Hash for BitArray<A, O>
272where
273 A: BitViewSized,
274 O: BitOrder,
275{
276 #[inline]
277 fn hash<H>(&self, hasher: &mut H)
278 where H: Hasher {
279 self.as_bitslice().hash(hasher);
280 }
281}
282
283impl<A, O> Copy for BitArray<A, O>
284where
285 O: BitOrder,
286 A: BitViewSized + Copy,
287{
288}
289
290impl<A, O> Unpin for BitArray<A, O>
291where
292 A: BitViewSized,
293 O: BitOrder,
294{
295}
296
297#[repr(transparent)]
298#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
299#[doc = include_str!("../../doc/array/TryFromBitSliceError.md")]
300pub struct TryFromBitSliceError(InnerError);
301
302impl TryFromBitSliceError {
303 #[inline]
305 fn new<A, O>(bits: &BitSlice<A::Store, O>) -> Result<(), Self>
306 where
307 O: BitOrder,
308 A: BitViewSized,
309 {
310 InnerError::new::<A, O>(bits).map_err(Self)
311 }
312}
313
314impl Debug for TryFromBitSliceError {
315 #[inline]
316 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
317 fmt.write_str("TryFromBitSliceError::")?;
318 match self.0 {
319 InnerError::UnequalLen { actual, expected } => {
320 write!(fmt, "UnequalLen({} != {})", actual, expected)
321 },
322 InnerError::Misaligned => fmt.write_str("Misaligned"),
323 }
324 }
325}
326
327#[cfg(not(tarpaulin_include))]
328impl Display for TryFromBitSliceError {
329 #[inline]
330 fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
331 match self.0 {
332 InnerError::UnequalLen { actual, expected } => write!(
333 fmt,
334 "bit-slice with length {} cannot be viewed as bit-array with \
335 length {}",
336 actual, expected,
337 ),
338 InnerError::Misaligned => fmt.write_str(
339 "a bit-slice must begin at the front edge of a storage element \
340 in order to be viewed as a bit-array",
341 ),
342 }
343 }
344}
345
346#[cfg(feature = "std")]
347impl std::error::Error for TryFromBitSliceError {}
348
349#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
351enum InnerError {
352 UnequalLen {
354 actual: usize,
356 expected: usize,
358 },
359 Misaligned,
361}
362
363impl InnerError {
364 #[inline]
366 fn new<A, O>(bits: &BitSlice<A::Store, O>) -> Result<(), Self>
367 where
368 O: BitOrder,
369 A: BitViewSized,
370 {
371 let bitspan = bits.as_bitspan();
372 let actual = bitspan.len();
373 let expected = mem::bits_of::<A>();
374 if actual != expected {
375 return Err(Self::UnequalLen { actual, expected });
376 }
377 if bitspan.head() != BitIdx::<<A::Store as BitStore>::Mem>::MIN {
378 return Err(Self::Misaligned);
379 }
380 Ok(())
381 }
382}