sync_ptr/
lib.rs

1//! # sync-ptr
2//! Sync & Send wrappers for raw pointer's in rust.
3//! To use add `use sync_ptr::*;` to your file,
4//! then you should be able to call `my_ptr.as_sync_const()` among others on any raw pointer
5//! to obtain a wrapped version of your raw pointer that is Sync/Send.
6//!
7#![no_std]
8#![deny(clippy::correctness)]
9#![warn(
10    clippy::perf,
11    clippy::complexity,
12    clippy::style,
13    clippy::nursery,
14    clippy::pedantic,
15    clippy::clone_on_ref_ptr,
16    clippy::decimal_literal_representation,
17    clippy::float_cmp_const,
18    clippy::missing_docs_in_private_items,
19    clippy::multiple_inherent_impl,
20    clippy::unwrap_used,
21    clippy::cargo_common_metadata,
22    clippy::used_underscore_binding
23)]
24#![allow(clippy::inline_always)]
25extern crate alloc;
26
27use core::fmt::{Formatter, Pointer};
28use core::ops::Deref;
29
30/// Implement common traits for type `SelfType` by forwarding implementation
31/// to underlying pointer.
32///
33/// Rust compiler cannot correctly auto-derive them because it's adding unnecessary
34/// constraint equivalent to:
35///
36/// ```ignore
37/// impl<T: Clone> Clone for SyncMutPtr<T> {...}
38/// ```
39///
40/// It's not consistent with how these traits are implemented in built-in primitive pointers:
41/// for example pointer can be cloned even if underlying type does not implement Clone, because
42/// we are cloning pointer, not value it points to.
43///
44/// To make implementation of traits in this library consistent with implementation of same
45/// traits on primitive pointers, we have to manually implement them.
46macro_rules! trait_impl {
47    ($SelfType:ident, $SelfName:literal) => {
48        impl<T> Clone for $SelfType<T> {
49            #[inline(always)]
50            fn clone(&self) -> Self {
51                *self
52            }
53        }
54
55        impl<T> Copy for $SelfType<T> {}
56        impl<T> Pointer for $SelfType<T> {
57            fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
58                core::fmt::Pointer::fmt(&self.0, f)
59            }
60        }
61
62        impl<T> Eq for $SelfType<T> {}
63        impl<T> PartialEq for $SelfType<T> {
64            fn eq(&self, other: &Self) -> bool {
65                PartialEq::eq(&self.0, &other.0)
66            }
67        }
68
69        impl<T> PartialOrd for $SelfType<T> {
70            fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
71                Some(self.cmp(other))
72            }
73        }
74
75        impl<T> Ord for $SelfType<T> {
76            fn cmp(&self, other: &Self) -> core::cmp::Ordering {
77                Ord::cmp(&self.0, &other.0)
78            }
79        }
80
81        impl<T> core::fmt::Debug for $SelfType<T> {
82            fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
83                use core::fmt::Write;
84                f.write_str($SelfName)?;
85                f.write_char('(')?;
86                core::fmt::Debug::fmt(&self.0, f)?;
87                f.write_char(')')
88            }
89        }
90
91        impl<T> core::hash::Hash for $SelfType<T> {
92            fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
93                core::hash::Hash::hash(&self.0, state);
94            }
95        }
96    };
97}
98
99///
100/// Wrapped mutable raw pointer that is Send+Sync
101///
102#[repr(transparent)]
103pub struct SyncMutPtr<T>(*mut T);
104
105unsafe impl<T> Sync for SyncMutPtr<T> {}
106unsafe impl<T> Send for SyncMutPtr<T> {}
107
108trait_impl!(SyncMutPtr, "SyncMutPtr");
109
110impl<T> SyncMutPtr<T> {
111    ///
112    /// Makes `ptr` Send+Sync
113    ///
114    /// # Safety
115    /// The `ptr` parameter must be able to handle being sent and used in other threads concurrently,
116    /// or special care must be taken when using the wrapped `ptr` to not use it
117    /// in any way in other threads.
118    ///
119    #[inline(always)]
120    #[must_use]
121    pub const unsafe fn new(ptr: *mut T) -> Self {
122        Self(ptr)
123    }
124
125    ///
126    /// Makes a Send+Sync null ptr.
127    ///
128    #[inline(always)]
129    #[must_use]
130    pub const fn null() -> Self {
131        Self(core::ptr::null_mut())
132    }
133
134    ///
135    /// Casts `ptr` to another data type while keeping it Send+Sync.
136    ///
137    #[inline(always)]
138    #[must_use]
139    pub const fn cast<Y>(&self) -> SyncMutPtr<Y> {
140        SyncMutPtr(self.0.cast())
141    }
142
143    ///
144    /// Returns inner `ptr` which is then no longer Send+Sync.
145    ///
146    #[inline(always)]
147    #[must_use]
148    pub const fn inner(&self) -> *mut T {
149        self.0
150    }
151
152    ///
153    /// Makes `ptr` immutable.
154    ///
155    #[inline(always)]
156    #[must_use]
157    pub const fn as_sync_const(&self) -> SyncConstPtr<T> {
158        SyncConstPtr(self.0)
159    }
160
161    ///
162    /// Makes `ptr` immutable and no longer Sync.
163    ///
164    #[inline(always)]
165    #[must_use]
166    pub const fn as_send_const(&self) -> SendConstPtr<T> {
167        SendConstPtr(self.0)
168    }
169
170    ///
171    /// This is equivalent to `.clone()` and does nothing.
172    ///
173    #[inline(always)]
174    #[must_use]
175    pub const fn as_sync_mut(&self) -> Self {
176        Self(self.0)
177    }
178
179    ///
180    /// Makes `ptr` no longer Sync.
181    ///
182    #[inline(always)]
183    #[must_use]
184    pub const fn as_send_mut(&self) -> SendMutPtr<T> {
185        SendMutPtr(self.0)
186    }
187}
188
189impl<T> Deref for SyncMutPtr<T> {
190    type Target = *mut T;
191
192    #[inline(always)]
193    fn deref(&self) -> &Self::Target {
194        &self.0
195    }
196}
197
198impl<T> From<SyncMutPtr<T>> for *mut T {
199    #[inline(always)]
200    fn from(val: SyncMutPtr<T>) -> Self {
201        val.inner()
202    }
203}
204
205impl<T> From<SyncMutPtr<T>> for *const T {
206    #[inline(always)]
207    fn from(val: SyncMutPtr<T>) -> Self {
208        val.inner()
209    }
210}
211
212///
213/// Wrapped const raw pointer that is Send+Sync
214///
215#[repr(transparent)]
216pub struct SyncConstPtr<T>(*const T);
217
218unsafe impl<T> Sync for SyncConstPtr<T> {}
219unsafe impl<T> Send for SyncConstPtr<T> {}
220
221trait_impl!(SyncConstPtr, "SyncConstPtr");
222
223impl<T> SyncConstPtr<T> {
224    ///
225    /// Makes `ptr` Send+Sync
226    ///
227    /// # Safety
228    /// The `ptr` parameter must be able to handle being sent and used in other threads concurrently,
229    /// or special care must be taken when using the wrapped `ptr` to not use it
230    /// in any way in other threads.
231    ///
232    #[inline(always)]
233    #[must_use]
234    pub const unsafe fn new(ptr: *const T) -> Self {
235        Self(ptr)
236    }
237
238    ///
239    /// Makes a Send+Sync null ptr.
240    ///
241    #[inline(always)]
242    #[must_use]
243    pub const fn null() -> Self {
244        Self(core::ptr::null())
245    }
246
247    ///
248    /// Casts `ptr` to another data type while keeping it Send+Sync.
249    ///
250    #[inline(always)]
251    #[must_use]
252    pub const fn cast<Y>(&self) -> SyncConstPtr<Y> {
253        SyncConstPtr(self.0.cast())
254    }
255
256    ///
257    /// Returns inner `ptr` which is then no longer Send+Sync.
258    ///
259    #[inline(always)]
260    #[must_use]
261    pub const fn inner(&self) -> *const T {
262        self.0
263    }
264
265    ///
266    /// This is equivalent to `.clone()` and does nothing.
267    ///
268    #[inline(always)]
269    #[must_use]
270    pub const fn as_sync_const(&self) -> Self {
271        Self(self.0)
272    }
273
274    ///
275    /// Makes this `ptr` no longer Sync.
276    ///
277    #[inline(always)]
278    #[must_use]
279    pub const fn as_send_const(&self) -> SendConstPtr<T> {
280        SendConstPtr(self.0)
281    }
282
283    ///
284    /// Makes this `ptr` mutable
285    ///
286    /// # Safety
287    /// Writing to immutable data is UB.
288    ///
289    #[inline(always)]
290    #[must_use]
291    pub const fn as_sync_mut(&self) -> SyncMutPtr<T> {
292        SyncMutPtr(self.0.cast_mut())
293    }
294
295    ///
296    /// Makes this `ptr` mutable and no longer Sync.
297    ///
298    /// # Safety
299    /// Writing to immutable data is UB.
300    ///
301    #[inline(always)]
302    #[must_use]
303    pub const fn as_send_mut(&self) -> SendMutPtr<T> {
304        SendMutPtr(self.0.cast_mut())
305    }
306}
307
308impl<T> Deref for SyncConstPtr<T> {
309    type Target = *const T;
310
311    #[inline(always)]
312    fn deref(&self) -> &Self::Target {
313        &self.0
314    }
315}
316
317impl<T> From<SyncConstPtr<T>> for *const T {
318    #[inline(always)]
319    fn from(val: SyncConstPtr<T>) -> Self {
320        val.inner()
321    }
322}
323
324///
325/// Wrapped mutable raw pointer that is Send but not Sync
326///
327#[repr(transparent)]
328pub struct SendMutPtr<T>(*mut T);
329
330unsafe impl<T> Send for SendMutPtr<T> {}
331
332trait_impl!(SendMutPtr, "SendMutPtr");
333
334impl<T> SendMutPtr<T> {
335    ///
336    /// Makes `ptr` Send
337    ///
338    /// # Safety
339    /// The `ptr` parameter must be able to handle being sent to other threads
340    /// or special care must be taken when using the wrapped `ptr` to not use it
341    /// in any way in other threads.
342    ///
343    #[inline(always)]
344    #[must_use]
345    pub const unsafe fn new(ptr: *mut T) -> Self {
346        Self(ptr)
347    }
348    ///
349    /// Makes a Send null ptr.
350    ///
351    #[inline(always)]
352    #[must_use]
353    pub const fn null() -> Self {
354        Self(core::ptr::null_mut())
355    }
356
357    ///
358    /// Casts `ptr` to another data type while keeping it Send.
359    ///
360    #[inline(always)]
361    #[must_use]
362    pub const fn cast<Y>(&self) -> SendMutPtr<Y> {
363        SendMutPtr(self.0.cast())
364    }
365
366    ///
367    /// Returns inner `ptr` which is then no longer Send.
368    ///
369    #[inline(always)]
370    #[must_use]
371    pub const fn inner(&self) -> *mut T {
372        self.0
373    }
374
375    ///
376    /// Makes this `ptr` Sync
377    ///
378    /// # Safety
379    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
380    /// or special care must be taken when using the wrapped `ptr` to not use it
381    /// in any way in other threads.
382    ///
383    #[inline(always)]
384    #[must_use]
385    pub const unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
386        SyncConstPtr(self.0)
387    }
388
389    ///
390    /// Makes this `ptr` const.
391    ///
392    #[inline(always)]
393    #[must_use]
394    pub const fn as_send_const(&self) -> SendConstPtr<T> {
395        SendConstPtr(self.0)
396    }
397
398    ///
399    /// Makes this `ptr` Sync
400    ///
401    /// # Safety
402    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
403    /// or special care must be taken when using the wrapped `ptr` to not use it
404    /// in any way in other threads.
405    ///
406    #[inline(always)]
407    #[must_use]
408    pub const unsafe fn as_sync_mut(&self) -> SyncMutPtr<T> {
409        SyncMutPtr(self.0)
410    }
411
412    ///
413    /// This is equivalent to `.clone()` and does nothing.
414    ///
415    #[inline(always)]
416    #[must_use]
417    pub const fn as_send_mut(&self) -> Self {
418        Self(self.0)
419    }
420}
421
422impl<T> Deref for SendMutPtr<T> {
423    type Target = *mut T;
424
425    #[inline(always)]
426    fn deref(&self) -> &Self::Target {
427        &self.0
428    }
429}
430
431impl<T> From<SendMutPtr<T>> for *mut T {
432    #[inline(always)]
433    fn from(val: SendMutPtr<T>) -> Self {
434        val.inner()
435    }
436}
437
438impl<T> From<SendMutPtr<T>> for *const T {
439    #[inline(always)]
440    fn from(val: SendMutPtr<T>) -> Self {
441        val.inner()
442    }
443}
444
445///
446/// Wrapped const raw pointer that is Send but not Sync
447///
448#[repr(transparent)]
449pub struct SendConstPtr<T>(*const T);
450
451unsafe impl<T> Send for SendConstPtr<T> {}
452
453trait_impl!(SendConstPtr, "SendConstPtr");
454
455impl<T> SendConstPtr<T> {
456    ///
457    /// Makes `ptr` Send
458    ///
459    /// # Safety
460    /// The `ptr` parameter must be able to handle being sent to other threads
461    /// or special care must be taken when using the wrapped `ptr` to not use it
462    /// in any way in other threads.
463    ///
464    #[inline(always)]
465    #[must_use]
466    pub const unsafe fn new(ptr: *const T) -> Self {
467        Self(ptr)
468    }
469
470    ///
471    /// Makes a Send null ptr.
472    ///
473    #[inline(always)]
474    #[must_use]
475    pub const fn null() -> Self {
476        Self(core::ptr::null())
477    }
478
479    ///
480    /// Casts `ptr` to another data type while keeping it Send.
481    ///
482    #[inline(always)]
483    #[must_use]
484    pub const fn cast<Y>(&self) -> SendConstPtr<Y> {
485        SendConstPtr(self.0.cast())
486    }
487
488    ///
489    /// Returns inner `ptr` which is then no longer Send.
490    ///
491    #[inline(always)]
492    #[must_use]
493    pub const fn inner(&self) -> *const T {
494        self.0
495    }
496
497    ///
498    /// Makes this `ptr` Sync
499    ///
500    /// # Safety
501    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
502    /// or special care must be taken when using the wrapped `ptr` to not use it
503    /// in any way in other threads.
504    ///
505    #[inline(always)]
506    #[must_use]
507    pub const unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
508        SyncConstPtr(self.0)
509    }
510
511    ///
512    /// This is equivalent to `.clone()` and does nothing.
513    ///
514    #[inline(always)]
515    #[must_use]
516    pub const fn as_send_const(&self) -> Self {
517        Self(self.0)
518    }
519
520    ///
521    /// Makes this `ptr` Sync
522    ///
523    /// # Safety
524    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
525    /// or special care must be taken when using the wrapped `ptr` to not use it
526    /// in any way in other threads.
527    ///
528    /// `ptr` is also marked as mutable. Writing to immutable data is usually UB.
529    ///
530    #[inline(always)]
531    #[must_use]
532    pub const unsafe fn as_sync_mut(&self) -> SyncMutPtr<T> {
533        SyncMutPtr(self.0.cast_mut())
534    }
535
536    ///
537    /// Makes this `ptr` mutable
538    ///
539    /// # Safety
540    /// Writing to immutable data is UB.
541    ///
542    #[inline(always)]
543    #[must_use]
544    pub const fn as_send_mut(&self) -> SendMutPtr<T> {
545        SendMutPtr(self.0.cast_mut())
546    }
547}
548
549impl<T> Deref for SendConstPtr<T> {
550    type Target = *const T;
551
552    #[inline(always)]
553    fn deref(&self) -> &Self::Target {
554        &self.0
555    }
556}
557
558impl<T> From<SendConstPtr<T>> for *const T {
559    #[inline(always)]
560    fn from(val: SendConstPtr<T>) -> *const T {
561        val.inner()
562    }
563}
564
565pub trait FromConstPtr<T>: Sized {
566    ///
567    /// Makes `self` immutable and Send+Sync
568    ///
569    /// # Safety
570    /// `self` must be able to handle being sent to and used concurrently by other threads,
571    /// or special care must be taken when using the wrapped `self` to not use it
572    /// in any way in other threads.
573    ///
574    unsafe fn as_sync_const(&self) -> SyncConstPtr<T>;
575
576    ///
577    /// Makes `self` immutable and Send
578    ///
579    /// # Safety
580    /// `self` must be able to handle being sent to other threads
581    /// or special care must be taken when using the wrapped `self` to not use it
582    /// in any way in other threads.
583    ///
584    unsafe fn as_send_const(&self) -> SendConstPtr<T>;
585}
586
587pub trait FromMutPtr<T>: FromConstPtr<T> {
588    ///
589    /// Makes `self` Send+Sync
590    ///
591    /// # Safety
592    /// `self` must be able to handle being sent to and used concurrently by other threads,
593    /// or special care must be taken when using the wrapped `self` to not use it
594    /// in any way in other threads.
595    ///
596    unsafe fn as_sync_mut(&self) -> SyncMutPtr<T>;
597
598    ///
599    /// Makes `self` Send
600    ///
601    /// # Safety
602    /// `self` must be able to handle being sent to other threads
603    /// or special care must be taken when using the wrapped `self` to not use it
604    /// in any way in other threads.
605    ///
606    unsafe fn as_send_mut(&self) -> SendMutPtr<T>;
607}
608
609impl<T> FromConstPtr<T> for *const T {
610    #[inline(always)]
611    unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
612        SyncConstPtr(self.cast())
613    }
614
615    #[inline(always)]
616    unsafe fn as_send_const(&self) -> SendConstPtr<T> {
617        SendConstPtr(self.cast())
618    }
619}
620
621impl<T> FromConstPtr<T> for *mut T {
622    #[inline(always)]
623    unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
624        SyncConstPtr(self.cast())
625    }
626
627    #[inline(always)]
628    unsafe fn as_send_const(&self) -> SendConstPtr<T> {
629        SendConstPtr(self.cast())
630    }
631}
632
633impl<T> FromMutPtr<T> for *mut T {
634    #[inline(always)]
635    unsafe fn as_sync_mut(&self) -> SyncMutPtr<T> {
636        SyncMutPtr(self.cast())
637    }
638
639    #[inline(always)]
640    unsafe fn as_send_mut(&self) -> SendMutPtr<T> {
641        SendMutPtr(self.cast())
642    }
643}