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