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