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) => {
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                f.debug_tuple(stringify!($SelfType)).field(&self.0).finish()
84            }
85        }
86
87        impl<T> core::hash::Hash for $SelfType<T> {
88            fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
89                core::hash::Hash::hash(&self.0, state);
90            }
91        }
92    };
93}
94
95///
96/// Wrapped mutable raw pointer that is Send+Sync
97///
98#[repr(transparent)]
99pub struct SyncMutPtr<T>(*mut T);
100
101unsafe impl<T> Sync for SyncMutPtr<T> {}
102unsafe impl<T> Send for SyncMutPtr<T> {}
103
104trait_impl!(SyncMutPtr);
105
106impl<T> SyncMutPtr<T> {
107    ///
108    /// Makes `ptr` Send+Sync
109    ///
110    /// # Safety
111    /// The `ptr` parameter must be able to handle being sent and used in other threads concurrently,
112    /// or special care must be taken when using the wrapped `ptr` to not use it
113    /// in any way in other threads.
114    ///
115    #[inline(always)]
116    #[must_use]
117    pub const unsafe fn new(ptr: *mut T) -> Self {
118        Self(ptr)
119    }
120
121    ///
122    /// Makes a Send+Sync null ptr.
123    ///
124    #[inline(always)]
125    #[must_use]
126    pub const fn null() -> Self {
127        Self(core::ptr::null_mut())
128    }
129
130    ///
131    /// Casts `ptr` to another data type while keeping it Send+Sync.
132    ///
133    #[inline(always)]
134    #[must_use]
135    pub const fn cast<Y>(&self) -> SyncMutPtr<Y> {
136        SyncMutPtr(self.0.cast())
137    }
138
139    ///
140    /// Returns inner `ptr` which is then no longer Send+Sync.
141    ///
142    #[inline(always)]
143    #[must_use]
144    pub const fn inner(&self) -> *mut T {
145        self.0
146    }
147
148    ///
149    /// Makes `ptr` immutable.
150    ///
151    #[inline(always)]
152    #[must_use]
153    pub const fn as_sync_const(&self) -> SyncConstPtr<T> {
154        SyncConstPtr(self.0)
155    }
156
157    ///
158    /// Makes `ptr` immutable and no longer Sync.
159    ///
160    #[inline(always)]
161    #[must_use]
162    pub const fn as_send_const(&self) -> SendConstPtr<T> {
163        SendConstPtr(self.0)
164    }
165
166    ///
167    /// This is equivalent to `.clone()` and does nothing.
168    ///
169    #[inline(always)]
170    #[must_use]
171    pub const fn as_sync_mut(&self) -> Self {
172        Self(self.0)
173    }
174
175    ///
176    /// Makes `ptr` no longer Sync.
177    ///
178    #[inline(always)]
179    #[must_use]
180    pub const fn as_send_mut(&self) -> SendMutPtr<T> {
181        SendMutPtr(self.0)
182    }
183}
184
185impl<T> Deref for SyncMutPtr<T> {
186    type Target = *mut T;
187
188    #[inline(always)]
189    fn deref(&self) -> &Self::Target {
190        &self.0
191    }
192}
193
194impl<T> From<SyncMutPtr<T>> for *mut T {
195    #[inline(always)]
196    fn from(val: SyncMutPtr<T>) -> Self {
197        val.inner()
198    }
199}
200
201impl<T> From<SyncMutPtr<T>> for *const T {
202    #[inline(always)]
203    fn from(val: SyncMutPtr<T>) -> Self {
204        val.inner()
205    }
206}
207
208///
209/// Wrapped const raw pointer that is Send+Sync
210///
211#[repr(transparent)]
212pub struct SyncConstPtr<T>(*const T);
213
214unsafe impl<T> Sync for SyncConstPtr<T> {}
215unsafe impl<T> Send for SyncConstPtr<T> {}
216
217trait_impl!(SyncConstPtr);
218
219impl<T> SyncConstPtr<T> {
220    ///
221    /// Makes `ptr` Send+Sync
222    ///
223    /// # Safety
224    /// The `ptr` parameter must be able to handle being sent and used in other threads concurrently,
225    /// or special care must be taken when using the wrapped `ptr` to not use it
226    /// in any way in other threads.
227    ///
228    #[inline(always)]
229    #[must_use]
230    pub const unsafe fn new(ptr: *const T) -> Self {
231        Self(ptr)
232    }
233
234    ///
235    /// Makes a Send+Sync null ptr.
236    ///
237    #[inline(always)]
238    #[must_use]
239    pub const fn null() -> Self {
240        Self(core::ptr::null())
241    }
242
243    ///
244    /// Casts `ptr` to another data type while keeping it Send+Sync.
245    ///
246    #[inline(always)]
247    #[must_use]
248    pub const fn cast<Y>(&self) -> SyncConstPtr<Y> {
249        SyncConstPtr(self.0.cast())
250    }
251
252    ///
253    /// Returns inner `ptr` which is then no longer Send+Sync.
254    ///
255    #[inline(always)]
256    #[must_use]
257    pub const fn inner(&self) -> *const T {
258        self.0
259    }
260
261    ///
262    /// This is equivalent to `.clone()` and does nothing.
263    ///
264    #[inline(always)]
265    #[must_use]
266    pub const fn as_sync_const(&self) -> Self {
267        Self(self.0)
268    }
269
270    ///
271    /// Makes this `ptr` no longer Sync.
272    ///
273    #[inline(always)]
274    #[must_use]
275    pub const fn as_send_const(&self) -> SendConstPtr<T> {
276        SendConstPtr(self.0)
277    }
278
279    ///
280    /// Makes this `ptr` mutable
281    ///
282    /// # Safety
283    /// Writing to immutable data is UB.
284    ///
285    #[inline(always)]
286    #[must_use]
287    pub const fn as_sync_mut(&self) -> SyncMutPtr<T> {
288        SyncMutPtr(self.0.cast_mut())
289    }
290
291    ///
292    /// Makes this `ptr` mutable and no longer Sync.
293    ///
294    /// # Safety
295    /// Writing to immutable data is UB.
296    ///
297    #[inline(always)]
298    #[must_use]
299    pub const fn as_send_mut(&self) -> SendMutPtr<T> {
300        SendMutPtr(self.0.cast_mut())
301    }
302}
303
304impl<T> Deref for SyncConstPtr<T> {
305    type Target = *const T;
306
307    #[inline(always)]
308    fn deref(&self) -> &Self::Target {
309        &self.0
310    }
311}
312
313impl<T> From<SyncConstPtr<T>> for *const T {
314    #[inline(always)]
315    fn from(val: SyncConstPtr<T>) -> Self {
316        val.inner()
317    }
318}
319
320///
321/// Wrapped mutable raw pointer that is Send but not Sync
322///
323#[repr(transparent)]
324pub struct SendMutPtr<T>(*mut T);
325
326unsafe impl<T> Send for SendMutPtr<T> {}
327
328trait_impl!(SendMutPtr);
329
330impl<T> SendMutPtr<T> {
331    ///
332    /// Makes `ptr` Send
333    ///
334    /// # Safety
335    /// The `ptr` parameter must be able to handle being sent to other threads
336    /// or special care must be taken when using the wrapped `ptr` to not use it
337    /// in any way in other threads.
338    ///
339    #[inline(always)]
340    #[must_use]
341    pub const unsafe fn new(ptr: *mut T) -> Self {
342        Self(ptr)
343    }
344    ///
345    /// Makes a Send null ptr.
346    ///
347    #[inline(always)]
348    #[must_use]
349    pub const fn null() -> Self {
350        Self(core::ptr::null_mut())
351    }
352
353    ///
354    /// Casts `ptr` to another data type while keeping it Send.
355    ///
356    #[inline(always)]
357    #[must_use]
358    pub const fn cast<Y>(&self) -> SendMutPtr<Y> {
359        SendMutPtr(self.0.cast())
360    }
361
362    ///
363    /// Returns inner `ptr` which is then no longer Send.
364    ///
365    #[inline(always)]
366    #[must_use]
367    pub const fn inner(&self) -> *mut T {
368        self.0
369    }
370
371    ///
372    /// Makes this `ptr` Sync
373    ///
374    /// # Safety
375    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
376    /// or special care must be taken when using the wrapped `ptr` to not use it
377    /// in any way in other threads.
378    ///
379    #[inline(always)]
380    #[must_use]
381    pub const unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
382        SyncConstPtr(self.0)
383    }
384
385    ///
386    /// Makes this `ptr` const.
387    ///
388    #[inline(always)]
389    #[must_use]
390    pub const fn as_send_const(&self) -> SendConstPtr<T> {
391        SendConstPtr(self.0)
392    }
393
394    ///
395    /// Makes this `ptr` Sync
396    ///
397    /// # Safety
398    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
399    /// or special care must be taken when using the wrapped `ptr` to not use it
400    /// in any way in other threads.
401    ///
402    #[inline(always)]
403    #[must_use]
404    pub const unsafe fn as_sync_mut(&self) -> SyncMutPtr<T> {
405        SyncMutPtr(self.0)
406    }
407
408    ///
409    /// This is equivalent to `.clone()` and does nothing.
410    ///
411    #[inline(always)]
412    #[must_use]
413    pub const fn as_send_mut(&self) -> Self {
414        Self(self.0)
415    }
416}
417
418impl<T> Deref for SendMutPtr<T> {
419    type Target = *mut T;
420
421    #[inline(always)]
422    fn deref(&self) -> &Self::Target {
423        &self.0
424    }
425}
426
427impl<T> From<SendMutPtr<T>> for *mut T {
428    #[inline(always)]
429    fn from(val: SendMutPtr<T>) -> Self {
430        val.inner()
431    }
432}
433
434impl<T> From<SendMutPtr<T>> for *const T {
435    #[inline(always)]
436    fn from(val: SendMutPtr<T>) -> Self {
437        val.inner()
438    }
439}
440
441///
442/// Wrapped const raw pointer that is Send but not Sync
443///
444#[repr(transparent)]
445pub struct SendConstPtr<T>(*const T);
446
447unsafe impl<T> Send for SendConstPtr<T> {}
448
449trait_impl!(SendConstPtr);
450
451impl<T> SendConstPtr<T> {
452    ///
453    /// Makes `ptr` Send
454    ///
455    /// # Safety
456    /// The `ptr` parameter must be able to handle being sent to other threads
457    /// or special care must be taken when using the wrapped `ptr` to not use it
458    /// in any way in other threads.
459    ///
460    #[inline(always)]
461    #[must_use]
462    pub const unsafe fn new(ptr: *const T) -> Self {
463        Self(ptr)
464    }
465
466    ///
467    /// Makes a Send null ptr.
468    ///
469    #[inline(always)]
470    #[must_use]
471    pub const fn null() -> Self {
472        Self(core::ptr::null())
473    }
474
475    ///
476    /// Casts `ptr` to another data type while keeping it Send.
477    ///
478    #[inline(always)]
479    #[must_use]
480    pub const fn cast<Y>(&self) -> SendConstPtr<Y> {
481        SendConstPtr(self.0.cast())
482    }
483
484    ///
485    /// Returns inner `ptr` which is then no longer Send.
486    ///
487    #[inline(always)]
488    #[must_use]
489    pub const fn inner(&self) -> *const T {
490        self.0
491    }
492
493    ///
494    /// Makes this `ptr` Sync
495    ///
496    /// # Safety
497    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
498    /// or special care must be taken when using the wrapped `ptr` to not use it
499    /// in any way in other threads.
500    ///
501    #[inline(always)]
502    #[must_use]
503    pub const unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
504        SyncConstPtr(self.0)
505    }
506
507    ///
508    /// This is equivalent to `.clone()` and does nothing.
509    ///
510    #[inline(always)]
511    #[must_use]
512    pub const fn as_send_const(&self) -> Self {
513        Self(self.0)
514    }
515
516    ///
517    /// Makes this `ptr` Sync
518    ///
519    /// # Safety
520    /// This `ptr` must be able to handle being accessed by multiple threads at the same time,
521    /// or special care must be taken when using the wrapped `ptr` to not use it
522    /// in any way in other threads.
523    ///
524    /// `ptr` is also marked as mutable. Writing to immutable data is usually UB.
525    ///
526    #[inline(always)]
527    #[must_use]
528    pub const unsafe fn as_sync_mut(&self) -> SyncMutPtr<T> {
529        SyncMutPtr(self.0.cast_mut())
530    }
531
532    ///
533    /// Makes this `ptr` mutable
534    ///
535    /// # Safety
536    /// Writing to immutable data is UB.
537    ///
538    #[inline(always)]
539    #[must_use]
540    pub const fn as_send_mut(&self) -> SendMutPtr<T> {
541        SendMutPtr(self.0.cast_mut())
542    }
543}
544
545impl<T> Deref for SendConstPtr<T> {
546    type Target = *const T;
547
548    #[inline(always)]
549    fn deref(&self) -> &Self::Target {
550        &self.0
551    }
552}
553
554impl<T> From<SendConstPtr<T>> for *const T {
555    #[inline(always)]
556    fn from(val: SendConstPtr<T>) -> *const T {
557        val.inner()
558    }
559}
560
561pub trait FromConstPtr<T>: Sized {
562    ///
563    /// Makes `self` immutable and Send+Sync
564    ///
565    /// # Safety
566    /// `self` must be able to handle being sent to and used concurrently by other threads,
567    /// or special care must be taken when using the wrapped `self` to not use it
568    /// in any way in other threads.
569    ///
570    unsafe fn as_sync_const(&self) -> SyncConstPtr<T>;
571
572    ///
573    /// Makes `self` immutable and Send
574    ///
575    /// # Safety
576    /// `self` must be able to handle being sent to other threads
577    /// or special care must be taken when using the wrapped `self` to not use it
578    /// in any way in other threads.
579    ///
580    unsafe fn as_send_const(&self) -> SendConstPtr<T>;
581}
582
583pub trait FromMutPtr<T>: FromConstPtr<T> {
584    ///
585    /// Makes `self` Send+Sync
586    ///
587    /// # Safety
588    /// `self` must be able to handle being sent to and used concurrently by other threads,
589    /// or special care must be taken when using the wrapped `self` to not use it
590    /// in any way in other threads.
591    ///
592    unsafe fn as_sync_mut(&self) -> SyncMutPtr<T>;
593
594    ///
595    /// Makes `self` Send
596    ///
597    /// # Safety
598    /// `self` must be able to handle being sent to other threads
599    /// or special care must be taken when using the wrapped `self` to not use it
600    /// in any way in other threads.
601    ///
602    unsafe fn as_send_mut(&self) -> SendMutPtr<T>;
603}
604
605impl<T> FromConstPtr<T> for *const T {
606    #[inline(always)]
607    unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
608        SyncConstPtr(self.cast())
609    }
610
611    #[inline(always)]
612    unsafe fn as_send_const(&self) -> SendConstPtr<T> {
613        SendConstPtr(self.cast())
614    }
615}
616
617impl<T> FromConstPtr<T> for *mut T {
618    #[inline(always)]
619    unsafe fn as_sync_const(&self) -> SyncConstPtr<T> {
620        SyncConstPtr(self.cast())
621    }
622
623    #[inline(always)]
624    unsafe fn as_send_const(&self) -> SendConstPtr<T> {
625        SendConstPtr(self.cast())
626    }
627}
628
629impl<T> FromMutPtr<T> for *mut T {
630    #[inline(always)]
631    unsafe fn as_sync_mut(&self) -> SyncMutPtr<T> {
632        SyncMutPtr(self.cast())
633    }
634
635    #[inline(always)]
636    unsafe fn as_send_mut(&self) -> SendMutPtr<T> {
637        SendMutPtr(self.cast())
638    }
639}