bitvec/
ptr.rs

1#![doc = include_str!("../doc/ptr.md")]
2
3use core::hash::{
4	Hash,
5	Hasher,
6};
7
8use wyz::bidi::BidiIterator;
9
10use crate::{
11	devel as dvl,
12	order::BitOrder,
13	slice::BitSlice,
14	store::BitStore,
15};
16
17mod addr;
18mod proxy;
19mod range;
20mod single;
21mod span;
22mod tests;
23
24pub use wyz::comu::{
25	Const,
26	Mut,
27	Mutability,
28};
29
30pub(crate) use self::{
31	addr::AddressExt,
32	span::BitSpan,
33};
34pub use self::{
35	addr::{
36		check_alignment,
37		MisalignError,
38	},
39	proxy::BitRef,
40	range::BitPtrRange,
41	single::{
42		BitPtr,
43		BitPtrError,
44	},
45	span::BitSpanError,
46};
47
48#[inline]
49#[doc = include_str!("../doc/ptr/copy.md")]
50pub unsafe fn copy<T1, T2, O1, O2>(
51	src: BitPtr<Const, T1, O1>,
52	dst: BitPtr<Mut, T2, O2>,
53	count: usize,
54) where
55	O1: BitOrder,
56	O2: BitOrder,
57	T1: BitStore,
58	T2: BitStore,
59{
60	//  Overlap is only defined if the orderings are identical.
61	if dvl::match_order::<O1, O2>() {
62		let (addr, head) = dst.raw_parts();
63		let dst = BitPtr::<Mut, T2, O1>::new_unchecked(addr, head);
64		let src_pair = src.range(count);
65
66		let rev = src_pair.contains(&dst);
67		for (from, to) in src_pair.zip(dst.range(count)).bidi(rev) {
68			to.write(from.read());
69		}
70	}
71	else {
72		copy_nonoverlapping(src, dst, count);
73	}
74}
75
76#[inline]
77#[doc = include_str!("../doc/ptr/copy_nonoverlapping.md")]
78pub unsafe fn copy_nonoverlapping<T1, T2, O1, O2>(
79	src: BitPtr<Const, T1, O1>,
80	dst: BitPtr<Mut, T2, O2>,
81	count: usize,
82) where
83	O1: BitOrder,
84	O2: BitOrder,
85	T1: BitStore,
86	T2: BitStore,
87{
88	for (from, to) in src.range(count).zip(dst.range(count)) {
89		to.write(from.read());
90	}
91}
92
93#[inline]
94#[doc = include_str!("../doc/ptr/drop_in_place.md")]
95#[deprecated = "this has no effect, and should not be called"]
96pub unsafe fn drop_in_place<T, O>(_: BitPtr<Mut, T, O>)
97where
98	T: BitStore,
99	O: BitOrder,
100{
101}
102
103#[doc = include_str!("../doc/ptr/eq.md")]
104#[inline]
105pub fn eq<T1, T2, O>(
106	this: BitPtr<Const, T1, O>,
107	that: BitPtr<Const, T2, O>,
108) -> bool
109where
110	T1: BitStore,
111	T2: BitStore,
112	O: BitOrder,
113{
114	this == that
115}
116
117#[inline]
118#[cfg(not(tarpaulin_include))]
119#[doc = include_str!("../doc/ptr/hash.md")]
120pub fn hash<T, O, S>(ptr: BitPtr<Const, T, O>, into: &mut S)
121where
122	T: BitStore,
123	O: BitOrder,
124	S: Hasher,
125{
126	ptr.hash(into);
127}
128
129#[inline]
130#[cfg(not(tarpaulin_include))]
131#[doc = include_str!("../doc/ptr/null.md")]
132pub fn null<T, O>() -> BitPtr<Const, T, O>
133where
134	T: BitStore,
135	O: BitOrder,
136{
137	BitPtr::DANGLING
138}
139
140#[inline]
141#[cfg(not(tarpaulin_include))]
142#[doc = include_str!("../doc/ptr/null_mut.md")]
143pub fn null_mut<T, O>() -> BitPtr<Mut, T, O>
144where
145	T: BitStore,
146	O: BitOrder,
147{
148	BitPtr::DANGLING
149}
150
151#[inline]
152#[cfg(not(tarpaulin_include))]
153#[doc = include_str!("../doc/ptr/read.md")]
154pub unsafe fn read<T, O>(src: BitPtr<Const, T, O>) -> bool
155where
156	T: BitStore,
157	O: BitOrder,
158{
159	src.read()
160}
161
162#[inline]
163#[allow(deprecated)]
164#[cfg(not(tarpaulin_include))]
165#[doc = include_str!("../doc/ptr/read_unaligned.md")]
166#[deprecated = "`BitPtr` does not have unaligned addresses"]
167pub unsafe fn read_unaligned<T, O>(src: BitPtr<Const, T, O>) -> bool
168where
169	T: BitStore,
170	O: BitOrder,
171{
172	src.read_unaligned()
173}
174
175#[inline]
176#[cfg(not(tarpaulin_include))]
177#[doc = include_str!("../doc/ptr/read_volatile.md")]
178pub unsafe fn read_volatile<T, O>(src: BitPtr<Const, T, O>) -> bool
179where
180	T: BitStore,
181	O: BitOrder,
182{
183	src.read_volatile()
184}
185
186#[inline]
187#[cfg(not(tarpaulin_include))]
188#[doc = include_str!("../doc/ptr/replace.md")]
189pub unsafe fn replace<T, O>(dst: BitPtr<Mut, T, O>, src: bool) -> bool
190where
191	T: BitStore,
192	O: BitOrder,
193{
194	dst.replace(src)
195}
196
197#[inline]
198#[cfg(not(tarpaulin_include))]
199#[doc = include_str!("../doc/ptr/slice_from_raw_parts.md")]
200pub fn slice_from_raw_parts<T, O>(
201	ptr: BitPtr<Const, T, O>,
202	len: usize,
203) -> *const BitSlice<T, O>
204where
205	T: BitStore,
206	O: BitOrder,
207{
208	bitslice_from_raw_parts(ptr, len)
209}
210
211#[inline]
212#[cfg(not(tarpaulin_include))]
213#[doc = include_str!("../doc/ptr/slice_from_raw_parts_mut.md")]
214pub fn slice_from_raw_parts_mut<T, O>(
215	ptr: BitPtr<Mut, T, O>,
216	len: usize,
217) -> *mut BitSlice<T, O>
218where
219	T: BitStore,
220	O: BitOrder,
221{
222	bitslice_from_raw_parts_mut(ptr, len)
223}
224
225#[inline]
226#[doc = include_str!("../doc/ptr/swap.md")]
227pub unsafe fn swap<T1, T2, O1, O2>(
228	one: BitPtr<Mut, T1, O1>,
229	two: BitPtr<Mut, T2, O2>,
230) where
231	T1: BitStore,
232	T2: BitStore,
233	O1: BitOrder,
234	O2: BitOrder,
235{
236	one.write(two.replace(one.read()));
237}
238
239#[inline]
240#[doc = include_str!("../doc/ptr/swap_nonoverlapping.md")]
241pub unsafe fn swap_nonoverlapping<T1, T2, O1, O2>(
242	mut one: BitPtr<Mut, T1, O1>,
243	mut two: BitPtr<Mut, T2, O2>,
244	count: usize,
245) where
246	O1: BitOrder,
247	O2: BitOrder,
248	T1: BitStore,
249	T2: BitStore,
250{
251	//  Note: compare codegen with `one.range(count).zip(two.range(count))`.
252	for _ in 0 .. count {
253		swap(one, two);
254		one = one.add(1);
255		two = two.add(1);
256	}
257}
258
259#[inline]
260#[cfg(not(tarpaulin_include))]
261#[doc = include_str!("../doc/ptr/write.md")]
262pub unsafe fn write<T, O>(dst: BitPtr<Mut, T, O>, value: bool)
263where
264	T: BitStore,
265	O: BitOrder,
266{
267	dst.write(value);
268}
269
270#[inline]
271#[cfg(not(tarpaulin_include))]
272#[deprecated = "use `write_bits()` instead"]
273#[doc = include_str!("../doc/ptr/write_bytes.md")]
274pub unsafe fn write_bytes<T, O>(
275	dst: BitPtr<Mut, T, O>,
276	value: bool,
277	count: usize,
278) where
279	T: BitStore,
280	O: BitOrder,
281{
282	write_bits(dst, value, count)
283}
284
285#[inline]
286#[allow(deprecated)]
287#[cfg(not(tarpaulin_include))]
288#[doc = include_str!("../doc/ptr/write_unaligned.md")]
289#[deprecated = "`BitPtr` does not have unaligned addresses"]
290pub unsafe fn write_unaligned<T, O>(dst: BitPtr<Mut, T, O>, value: bool)
291where
292	T: BitStore,
293	O: BitOrder,
294{
295	dst.write_unaligned(value);
296}
297
298#[inline]
299#[cfg(not(tarpaulin_include))]
300#[doc = include_str!("../doc/ptr/write_volatile.md")]
301pub unsafe fn write_volatile<T, O>(dst: BitPtr<Mut, T, O>, value: bool)
302where
303	T: BitStore,
304	O: BitOrder,
305{
306	dst.write_volatile(value);
307}
308
309//  Renamed variants.
310
311#[inline]
312#[cfg(not(tarpaulin_include))]
313#[doc = include_str!("../doc/ptr/bitslice_from_raw_parts.md")]
314pub fn bitslice_from_raw_parts<T, O>(
315	ptr: BitPtr<Const, T, O>,
316	len: usize,
317) -> *const BitSlice<T, O>
318where
319	T: BitStore,
320	O: BitOrder,
321{
322	ptr.span(len).unwrap().into_bitslice_ptr()
323}
324
325#[inline]
326#[cfg(not(tarpaulin_include))]
327#[doc = include_str!("../doc/ptr/bitslice_from_raw_parts_mut.md")]
328pub fn bitslice_from_raw_parts_mut<T, O>(
329	ptr: BitPtr<Mut, T, O>,
330	len: usize,
331) -> *mut BitSlice<T, O>
332where
333	T: BitStore,
334	O: BitOrder,
335{
336	ptr.span(len).unwrap().into_bitslice_ptr_mut()
337}
338
339#[inline]
340#[doc = include_str!("../doc/ptr/write_bits.md")]
341pub unsafe fn write_bits<T, O>(dst: BitPtr<Mut, T, O>, value: bool, count: usize)
342where
343	T: BitStore,
344	O: BitOrder,
345{
346	for bit in dst.range(count) {
347		bit.write(value);
348	}
349}