/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bitvec-1.0.1/src/ptr/proxy.rs
Line | Count | Source |
1 | | #![doc = include_str!("../../doc/ptr/proxy.md")] |
2 | | |
3 | | use core::{ |
4 | | cell::UnsafeCell, |
5 | | cmp, |
6 | | fmt::{ |
7 | | self, |
8 | | Debug, |
9 | | Display, |
10 | | Formatter, |
11 | | Pointer, |
12 | | }, |
13 | | hash::{ |
14 | | Hash, |
15 | | Hasher, |
16 | | }, |
17 | | marker::PhantomData, |
18 | | mem, |
19 | | ops::{ |
20 | | Deref, |
21 | | DerefMut, |
22 | | Not, |
23 | | }, |
24 | | }; |
25 | | |
26 | | use wyz::comu::{ |
27 | | Const, |
28 | | Mut, |
29 | | Mutability, |
30 | | }; |
31 | | |
32 | | use super::BitPtr; |
33 | | use crate::{ |
34 | | order::{ |
35 | | BitOrder, |
36 | | Lsb0, |
37 | | }, |
38 | | store::BitStore, |
39 | | }; |
40 | | |
41 | | #[doc = include_str!("../../doc/ptr/BitRef.md")] |
42 | | // Restore alignment and sizing properties, as `BitPtr` lacks them. |
43 | | #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] |
44 | | #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] |
45 | | #[cfg_attr( |
46 | | not(any(target_pointer_width = "32", target_pointer_width = "64")), |
47 | | repr(C) |
48 | | )] |
49 | | pub struct BitRef<'a, M = Const, T = usize, O = Lsb0> |
50 | | where |
51 | | M: Mutability, |
52 | | T: BitStore, |
53 | | O: BitOrder, |
54 | | { |
55 | | /// The proxied bit-address. |
56 | | bitptr: BitPtr<M, T, O>, |
57 | | /// A local cache of the proxied bit that can be referenced. |
58 | | data: bool, |
59 | | /// Attach the lifetime and reflect the possibility of mutation. |
60 | | _ref: PhantomData<&'a UnsafeCell<bool>>, |
61 | | } |
62 | | |
63 | | impl<M, T, O> BitRef<'_, M, T, O> |
64 | | where |
65 | | M: Mutability, |
66 | | T: BitStore, |
67 | | O: BitOrder, |
68 | | { |
69 | | /// Converts a bit-pointer into a proxy bit-reference. |
70 | | /// |
71 | | /// This reads through the pointer in order to cache the current bit value |
72 | | /// in the proxy. |
73 | | /// |
74 | | /// ## Original |
75 | | /// |
76 | | /// The syntax `unsafe { &* ptr }`. |
77 | | /// |
78 | | /// ## Safety |
79 | | /// |
80 | | /// This is equivalent to (and is!) dereferencing a raw pointer. The pointer |
81 | | /// must be well-constructed, refer to a live memory location in the program |
82 | | /// context, and not be aliased beyond its typing indicators. |
83 | | #[inline] |
84 | 34.0k | pub unsafe fn from_bitptr(bitptr: BitPtr<M, T, O>) -> Self { |
85 | 34.0k | let data = bitptr.read(); |
86 | 34.0k | Self { |
87 | 34.0k | bitptr, |
88 | 34.0k | data, |
89 | 34.0k | _ref: PhantomData, |
90 | 34.0k | } |
91 | 34.0k | } <bitvec::ptr::proxy::BitRef<wyz::comu::Const, u8, bitvec::order::Msb0>>::from_bitptr Line | Count | Source | 84 | 34.0k | pub unsafe fn from_bitptr(bitptr: BitPtr<M, T, O>) -> Self { | 85 | 34.0k | let data = bitptr.read(); | 86 | 34.0k | Self { | 87 | 34.0k | bitptr, | 88 | 34.0k | data, | 89 | 34.0k | _ref: PhantomData, | 90 | 34.0k | } | 91 | 34.0k | } |
Unexecuted instantiation: <bitvec::ptr::proxy::BitRef<_, _, _>>::from_bitptr |
92 | | |
93 | | /// Decays the bit-reference to an ordinary bit-pointer. |
94 | | /// |
95 | | /// ## Original |
96 | | /// |
97 | | /// The syntax `&val as *T`. |
98 | | #[inline] |
99 | | #[cfg(not(tarpaulin_include))] |
100 | 0 | pub fn into_bitptr(self) -> BitPtr<M, T, O> { |
101 | 0 | self.bitptr |
102 | 0 | } |
103 | | |
104 | | /// Removes a layer of `::Alias` marking from a bit-reference. |
105 | | /// |
106 | | /// ## Safety |
107 | | /// |
108 | | /// The caller must ensure that no element-level aliasing *by `bitvec`* |
109 | | /// occurs in the scope for which the produced de-aliased proxy is alive. |
110 | | #[cfg(not(tarpaulin_include))] |
111 | 0 | pub(crate) unsafe fn remove_alias(this: BitRef<M, T::Alias, O>) -> Self { |
112 | 0 | Self { |
113 | 0 | bitptr: this.bitptr.cast::<T>(), |
114 | 0 | data: this.data, |
115 | 0 | _ref: PhantomData, |
116 | 0 | } |
117 | 0 | } |
118 | | } |
119 | | |
120 | | impl<T, O> BitRef<'_, Mut, T, O> |
121 | | where |
122 | | T: BitStore, |
123 | | O: BitOrder, |
124 | | { |
125 | | /// Moves `src` into the referenced bit, returning the previous value. |
126 | | /// |
127 | | /// ## Original |
128 | | /// |
129 | | /// [`mem::replace`](core::mem::replace) |
130 | | #[inline] |
131 | 0 | pub fn replace(&mut self, src: bool) -> bool { |
132 | 0 | mem::replace(&mut self.data, src) |
133 | 0 | } |
134 | | |
135 | | /// Swaps the bit values of two proxies. |
136 | | /// |
137 | | /// ## Original |
138 | | /// |
139 | | /// [`mem::swap`](core::mem::swap) |
140 | | #[inline] |
141 | 0 | pub fn swap<T2, O2>(&mut self, other: &mut BitRef<Mut, T2, O2>) |
142 | 0 | where |
143 | 0 | T2: BitStore, |
144 | 0 | O2: BitOrder, |
145 | | { |
146 | 0 | mem::swap(&mut self.data, &mut other.data) |
147 | 0 | } |
148 | | |
149 | | /// Commits a bit into the proxied location. |
150 | | /// |
151 | | /// This function writes `value` directly into the proxied location, |
152 | | /// bypassing the cache and destroying the proxy. This eliminates the second |
153 | | /// write done in the destructor, and allows code to be slightly faster. |
154 | | #[inline] |
155 | 0 | pub fn commit(self, value: bool) { |
156 | 0 | unsafe { |
157 | 0 | self.bitptr.write(value); |
158 | 0 | } |
159 | 0 | mem::forget(self); |
160 | 0 | } |
161 | | |
162 | | /// Writes `value` into the proxy. |
163 | | /// |
164 | | /// This does not write into the proxied location; that is deferred until |
165 | | /// the proxy destructor runs. |
166 | | #[inline] |
167 | 0 | pub fn set(&mut self, value: bool) { |
168 | 0 | self.data = value; |
169 | 0 | } |
170 | | } |
171 | | |
172 | | #[cfg(not(tarpaulin_include))] |
173 | | impl<T, O> Clone for BitRef<'_, Const, T, O> |
174 | | where |
175 | | T: BitStore, |
176 | | O: BitOrder, |
177 | | { |
178 | | #[inline] |
179 | 0 | fn clone(&self) -> Self { |
180 | 0 | Self { ..*self } |
181 | 0 | } |
182 | | } |
183 | | |
184 | | impl<M, T, O> Eq for BitRef<'_, M, T, O> |
185 | | where |
186 | | M: Mutability, |
187 | | T: BitStore, |
188 | | O: BitOrder, |
189 | | { |
190 | | } |
191 | | |
192 | | #[cfg(not(tarpaulin_include))] |
193 | | impl<M, T, O> Ord for BitRef<'_, M, T, O> |
194 | | where |
195 | | M: Mutability, |
196 | | T: BitStore, |
197 | | O: BitOrder, |
198 | | { |
199 | | #[inline] |
200 | 0 | fn cmp(&self, other: &Self) -> cmp::Ordering { |
201 | 0 | self.data.cmp(&other.data) |
202 | 0 | } |
203 | | } |
204 | | |
205 | | #[cfg(not(tarpaulin_include))] |
206 | | impl<M1, M2, O1, O2, T1, T2> PartialEq<BitRef<'_, M2, T2, O2>> |
207 | | for BitRef<'_, M1, T1, O1> |
208 | | where |
209 | | M1: Mutability, |
210 | | M2: Mutability, |
211 | | T1: BitStore, |
212 | | T2: BitStore, |
213 | | O1: BitOrder, |
214 | | O2: BitOrder, |
215 | | { |
216 | | #[inline(always)] |
217 | 0 | fn eq(&self, other: &BitRef<'_, M2, T2, O2>) -> bool { |
218 | 0 | self.data == other.data |
219 | 0 | } |
220 | | } |
221 | | |
222 | | #[cfg(not(tarpaulin_include))] |
223 | | impl<M, T, O> PartialEq<bool> for BitRef<'_, M, T, O> |
224 | | where |
225 | | M: Mutability, |
226 | | T: BitStore, |
227 | | O: BitOrder, |
228 | | { |
229 | | #[inline(always)] |
230 | 0 | fn eq(&self, other: &bool) -> bool { |
231 | 0 | self.data == *other |
232 | 0 | } |
233 | | } |
234 | | |
235 | | #[cfg(not(tarpaulin_include))] |
236 | | impl<M, T, O> PartialEq<BitRef<'_, M, T, O>> for bool |
237 | | where |
238 | | M: Mutability, |
239 | | T: BitStore, |
240 | | O: BitOrder, |
241 | | { |
242 | | #[inline] |
243 | 0 | fn eq(&self, other: &BitRef<'_, M, T, O>) -> bool { |
244 | 0 | other == self |
245 | 0 | } |
246 | | } |
247 | | |
248 | | #[cfg(not(tarpaulin_include))] |
249 | | impl<M, T, O> PartialEq<&bool> for BitRef<'_, M, T, O> |
250 | | where |
251 | | M: Mutability, |
252 | | T: BitStore, |
253 | | O: BitOrder, |
254 | | { |
255 | | #[inline(always)] |
256 | 0 | fn eq(&self, other: &&bool) -> bool { |
257 | 0 | self.data == **other |
258 | 0 | } |
259 | | } |
260 | | |
261 | | #[cfg(not(tarpaulin_include))] |
262 | | impl<M, T, O> PartialEq<BitRef<'_, M, T, O>> for &bool |
263 | | where |
264 | | M: Mutability, |
265 | | T: BitStore, |
266 | | O: BitOrder, |
267 | | { |
268 | | #[inline] |
269 | 0 | fn eq(&self, other: &BitRef<'_, M, T, O>) -> bool { |
270 | 0 | other == *self |
271 | 0 | } |
272 | | } |
273 | | |
274 | | #[cfg(not(tarpaulin_include))] |
275 | | impl<M1, M2, O1, O2, T1, T2> PartialOrd<BitRef<'_, M2, T2, O2>> |
276 | | for BitRef<'_, M1, T1, O1> |
277 | | where |
278 | | M1: Mutability, |
279 | | M2: Mutability, |
280 | | T1: BitStore, |
281 | | T2: BitStore, |
282 | | O1: BitOrder, |
283 | | O2: BitOrder, |
284 | | { |
285 | | #[inline] |
286 | 0 | fn partial_cmp( |
287 | 0 | &self, |
288 | 0 | other: &BitRef<'_, M2, T2, O2>, |
289 | 0 | ) -> Option<cmp::Ordering> { |
290 | 0 | self.data.partial_cmp(&other.data) |
291 | 0 | } |
292 | | } |
293 | | |
294 | | #[cfg(not(tarpaulin_include))] |
295 | | impl<M, T, O> PartialOrd<bool> for BitRef<'_, M, T, O> |
296 | | where |
297 | | M: Mutability, |
298 | | T: BitStore, |
299 | | O: BitOrder, |
300 | | { |
301 | | #[inline] |
302 | 0 | fn partial_cmp(&self, other: &bool) -> Option<cmp::Ordering> { |
303 | 0 | self.data.partial_cmp(other) |
304 | 0 | } |
305 | | } |
306 | | |
307 | | #[cfg(not(tarpaulin_include))] |
308 | | impl<M, T, O> PartialOrd<&bool> for BitRef<'_, M, T, O> |
309 | | where |
310 | | M: Mutability, |
311 | | T: BitStore, |
312 | | O: BitOrder, |
313 | | { |
314 | | #[inline] |
315 | 0 | fn partial_cmp(&self, other: &&bool) -> Option<cmp::Ordering> { |
316 | 0 | self.data.partial_cmp(*other) |
317 | 0 | } |
318 | | } |
319 | | |
320 | | #[cfg(not(tarpaulin_include))] |
321 | | impl<M, T, O> AsRef<bool> for BitRef<'_, M, T, O> |
322 | | where |
323 | | M: Mutability, |
324 | | T: BitStore, |
325 | | O: BitOrder, |
326 | | { |
327 | | #[inline] |
328 | 0 | fn as_ref(&self) -> &bool { |
329 | 0 | &self.data |
330 | 0 | } |
331 | | } |
332 | | |
333 | | #[cfg(not(tarpaulin_include))] |
334 | | impl<T, O> AsMut<bool> for BitRef<'_, Mut, T, O> |
335 | | where |
336 | | T: BitStore, |
337 | | O: BitOrder, |
338 | | { |
339 | | #[inline] |
340 | 0 | fn as_mut(&mut self) -> &mut bool { |
341 | 0 | &mut self.data |
342 | 0 | } |
343 | | } |
344 | | |
345 | | impl<M, T, O> Debug for BitRef<'_, M, T, O> |
346 | | where |
347 | | M: Mutability, |
348 | | T: BitStore, |
349 | | O: BitOrder, |
350 | | { |
351 | | #[inline] |
352 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
353 | 0 | unsafe { self.bitptr.span_unchecked(1) } |
354 | 0 | .render(fmt, "Ref", &[("bit", &self.data as &dyn Debug)]) |
355 | 0 | } |
356 | | } |
357 | | |
358 | | #[cfg(not(tarpaulin_include))] |
359 | | impl<M, T, O> Display for BitRef<'_, M, T, O> |
360 | | where |
361 | | M: Mutability, |
362 | | T: BitStore, |
363 | | O: BitOrder, |
364 | | { |
365 | | #[inline] |
366 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
367 | 0 | Display::fmt(&self.data, fmt) |
368 | 0 | } |
369 | | } |
370 | | |
371 | | #[cfg(not(tarpaulin_include))] |
372 | | impl<M, T, O> Pointer for BitRef<'_, M, T, O> |
373 | | where |
374 | | M: Mutability, |
375 | | T: BitStore, |
376 | | O: BitOrder, |
377 | | { |
378 | | #[inline] |
379 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
380 | 0 | Pointer::fmt(&self.bitptr, fmt) |
381 | 0 | } |
382 | | } |
383 | | |
384 | | #[cfg(not(tarpaulin_include))] |
385 | | impl<M, T, O> Hash for BitRef<'_, M, T, O> |
386 | | where |
387 | | M: Mutability, |
388 | | T: BitStore, |
389 | | O: BitOrder, |
390 | | { |
391 | | #[inline] |
392 | 0 | fn hash<H>(&self, state: &mut H) |
393 | 0 | where H: Hasher { |
394 | 0 | self.bitptr.hash(state); |
395 | 0 | } |
396 | | } |
397 | | |
398 | | // #[allow(clippy::non_send_fields_in_send_ty)] // I know what I’m doing |
399 | | unsafe impl<M, T, O> Send for BitRef<'_, M, T, O> |
400 | | where |
401 | | M: Mutability, |
402 | | T: BitStore + Sync, |
403 | | O: BitOrder, |
404 | | { |
405 | | } |
406 | | |
407 | | unsafe impl<M, T, O> Sync for BitRef<'_, M, T, O> |
408 | | where |
409 | | M: Mutability, |
410 | | T: BitStore + Sync, |
411 | | O: BitOrder, |
412 | | { |
413 | | } |
414 | | |
415 | | // This cannot be implemented until `Drop` is specialized to only |
416 | | // `<Mut, T, O>`. |
417 | | // impl<T, O> Copy for BitRef<'_, Const, T, O> |
418 | | // where O: BitOrder, T: BitStore {} |
419 | | |
420 | | impl<M, T, O> Deref for BitRef<'_, M, T, O> |
421 | | where |
422 | | M: Mutability, |
423 | | T: BitStore, |
424 | | O: BitOrder, |
425 | | { |
426 | | type Target = bool; |
427 | | |
428 | | #[inline] |
429 | 34.0k | fn deref(&self) -> &Self::Target { |
430 | 34.0k | &self.data |
431 | 34.0k | } <bitvec::ptr::proxy::BitRef<wyz::comu::Const, u8, bitvec::order::Msb0> as core::ops::deref::Deref>::deref Line | Count | Source | 429 | 34.0k | fn deref(&self) -> &Self::Target { | 430 | 34.0k | &self.data | 431 | 34.0k | } |
Unexecuted instantiation: <bitvec::ptr::proxy::BitRef<_, _, _> as core::ops::deref::Deref>::deref |
432 | | } |
433 | | |
434 | | impl<T, O> DerefMut for BitRef<'_, Mut, T, O> |
435 | | where |
436 | | T: BitStore, |
437 | | O: BitOrder, |
438 | | { |
439 | | #[inline] |
440 | 0 | fn deref_mut(&mut self) -> &mut Self::Target { |
441 | 0 | &mut self.data |
442 | 0 | } |
443 | | } |
444 | | |
445 | | impl<M, T, O> Drop for BitRef<'_, M, T, O> |
446 | | where |
447 | | M: Mutability, |
448 | | T: BitStore, |
449 | | O: BitOrder, |
450 | | { |
451 | | #[inline] |
452 | 34.0k | fn drop(&mut self) { |
453 | | // `Drop` cannot specialize on type parameters, but only mutable |
454 | | // proxies can commit to memory. |
455 | 34.0k | if M::CONTAINS_MUTABILITY { |
456 | 0 | unsafe { |
457 | 0 | self.bitptr.to_mut().write(self.data); |
458 | 0 | } |
459 | 34.0k | } |
460 | 34.0k | } <bitvec::ptr::proxy::BitRef<wyz::comu::Const, u8, bitvec::order::Msb0> as core::ops::drop::Drop>::drop Line | Count | Source | 452 | 34.0k | fn drop(&mut self) { | 453 | | // `Drop` cannot specialize on type parameters, but only mutable | 454 | | // proxies can commit to memory. | 455 | 34.0k | if M::CONTAINS_MUTABILITY { | 456 | 0 | unsafe { | 457 | 0 | self.bitptr.to_mut().write(self.data); | 458 | 0 | } | 459 | 34.0k | } | 460 | 34.0k | } |
Unexecuted instantiation: <bitvec::ptr::proxy::BitRef<_, _, _> as core::ops::drop::Drop>::drop |
461 | | } |
462 | | |
463 | | impl<M, T, O> Not for BitRef<'_, M, T, O> |
464 | | where |
465 | | M: Mutability, |
466 | | T: BitStore, |
467 | | O: BitOrder, |
468 | | { |
469 | | type Output = bool; |
470 | | |
471 | | #[inline] |
472 | 0 | fn not(self) -> Self::Output { |
473 | 0 | !self.data |
474 | 0 | } |
475 | | } |