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