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 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 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#[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}