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}
756
757/// Function Pointer wrappers module, to allow for easy toggling using the feature flag.
758#[cfg(feature = "fnptr")]
759#[allow(clippy::incompatible_msrv)] //Documented in readme that this needs at least rust v1.85.0
760mod fnptr {
761    use core::fmt::{Debug, Pointer};
762    use core::hash::Hash;
763
764    /// Common function pointer wrapper implementation.
765    macro_rules! impl_pointer {
766        ($SelfType:ident) => {
767            impl<
768                    T: Pointer
769                        + Copy
770                        + Clone
771                        + Sized
772                        + Eq
773                        + PartialEq
774                        + PartialOrd
775                        + Ord
776                        + Hash
777                        + Debug,
778                > Default for $SelfType<T>
779            {
780                fn default() -> Self {
781                    Self(None)
782                }
783            }
784
785            impl<
786                    T: Pointer
787                        + Copy
788                        + Clone
789                        + Sized
790                        + Eq
791                        + PartialEq
792                        + PartialOrd
793                        + Ord
794                        + Hash
795                        + Debug,
796                > core::fmt::Pointer for $SelfType<T>
797            {
798                fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
799                    if let Some(r) = self.0.as_ref() {
800                        Pointer::fmt(r, f)
801                    } else {
802                        Pointer::fmt(&core::ptr::null::<()>(), f)
803                    }
804                }
805            }
806            impl<
807                    T: Pointer
808                        + Copy
809                        + Clone
810                        + Sized
811                        + Eq
812                        + PartialEq
813                        + PartialOrd
814                        + Ord
815                        + Hash
816                        + Debug,
817                > core::ops::Deref for $SelfType<T>
818            {
819                type Target = T;
820
821                #[inline(always)]
822                fn deref(&self) -> &Self::Target {
823                    self.0
824                        .as_ref()
825                        .expect("sync_ptr deref attempt to deref null function pointer")
826                }
827            }
828
829            impl<
830                    T: Pointer
831                        + Copy
832                        + Clone
833                        + Sized
834                        + Eq
835                        + PartialEq
836                        + PartialOrd
837                        + Ord
838                        + Hash
839                        + Debug,
840                > core::ops::DerefMut for $SelfType<T>
841            {
842                #[inline(always)]
843                fn deref_mut(&mut self) -> &mut Self::Target {
844                    self.0
845                        .as_mut()
846                        .expect("sync_ptr: deref_mut attempt to deref null function pointer")
847                }
848            }
849
850            impl<
851                    T: Pointer
852                        + Copy
853                        + Clone
854                        + Sized
855                        + Eq
856                        + PartialEq
857                        + PartialOrd
858                        + Ord
859                        + Hash
860                        + Debug,
861                > From<$SelfType<T>> for usize
862            {
863                #[inline(always)]
864                fn from(value: $SelfType<T>) -> Self {
865                    value.as_address()
866                }
867            }
868
869            impl<
870                    T: Pointer
871                        + Copy
872                        + Clone
873                        + Sized
874                        + Eq
875                        + PartialEq
876                        + PartialOrd
877                        + Ord
878                        + Hash
879                        + Debug,
880                > From<$SelfType<T>> for *const core::ffi::c_void
881            {
882                #[inline(always)]
883                fn from(value: $SelfType<T>) -> Self {
884                    value.as_raw_ptr()
885                }
886            }
887
888            impl<
889                    T: Pointer
890                        + Copy
891                        + Clone
892                        + Sized
893                        + Eq
894                        + PartialEq
895                        + PartialOrd
896                        + Ord
897                        + Hash
898                        + Debug,
899                > $SelfType<T>
900            {
901                /// Constructs a null function pointer
902                #[inline(always)]
903                pub const fn null() -> Self {
904                    Self(None)
905                }
906
907                /// Returns the inner representation of the wrapper
908                /// If the option is None then this wrapper was a null pointer.
909                #[inline(always)]
910                pub const fn inner(&self) -> Option<T> {
911                    self.0
912                }
913
914                /// Unwraps the wrapper returning the raw function pointer
915                /// # Panics
916                /// If the wrapper represents a null pointer
917                #[inline(always)]
918                pub const fn unwrap(&self) -> T {
919                    self.0.unwrap()
920                }
921
922                /// Returns the address of the function pointer.
923                /// This is equivalent to doing `raw_fn_ptr as usize` with the exception
924                /// that this function will return 0usize for a null pointer.
925                #[inline(always)]
926                pub const fn as_address(&self) -> usize {
927                    if let Some(r) = self.0.as_ref() {
928                        unsafe { core::mem::transmute_copy::<_, usize>(r) }
929                    } else {
930                        0
931                    }
932                }
933
934                /// Returns the raw pointer representation of the function pointer.
935                /// This is equivalent to doing `raw_fn_ptr as *const c_void` with the exception
936                /// that this function will return null for a null pointer.
937                #[inline(always)]
938                pub const fn as_raw_ptr(&self) -> *const core::ffi::c_void {
939                    if let Some(r) = self.0.as_ref() {
940                        unsafe { core::mem::transmute_copy::<_, *const core::ffi::c_void>(r) }
941                    } else {
942                        core::ptr::null()
943                    }
944                }
945
946                /// Returns true if this wrapper represents a null function pointer.
947                #[inline(always)]
948                pub const fn is_null(&self) -> bool {
949                    self.0.is_none()
950                }
951            }
952        };
953    }
954
955    ///
956    /// This macro creates a Function Pointer that is Send+Sync and guaranteed to have the same representation
957    /// in memory as a raw function pointer would. (Meaning its size is usize)
958    ///
959    /// # Example
960    /// ```rust
961    ///
962    /// use std::ffi::c_void;
963    /// use sync_ptr::sync_fn_ptr;
964    /// use sync_ptr::SyncFnPtr;
965    ///
966    /// extern "C" fn test_function() -> u64 {
967    ///     123456u64
968    /// }
969    ///
970    /// fn some_other_function() {
971    ///     let test_fn_ptr = sync_fn_ptr!(extern "C" fn() -> u64, test_function);
972    ///     //Type of test_fn_ptr is SendFnPtr<extern "C" fn() -> u64>
973    ///     std::thread::spawn(move || {
974    ///         assert_eq!(test_fn_ptr(), test_function());
975    ///     }).join().unwrap();
976    /// }
977    /// ```
978    ///
979    #[macro_export]
980    macro_rules! sync_fn_ptr {
981        ($sig:ty, $var:expr) => {{
982            let x = $var as $sig;
983            _ = move || {
984                //Workaround to ensure T is core::marker::FnPtr, which is unfortunately unstable.
985                _ = core::ptr::fn_addr_eq(x, x);
986            };
987
988            //The compiler should optimize this out, as this should always hold true.
989            assert!(core::mem::size_of::<SyncFnPtr::<$sig>>() == core::mem::size_of::<$sig>());
990
991            //Safety: SyncFnPtr has repr(transparent)
992            let n: SyncFnPtr<$sig> = unsafe { core::mem::transmute(Some(x)) };
993
994            n
995        }};
996    }
997
998    ///
999    /// This macro creates a Function Pointer that is Send+Sync and guaranteed to have the same representation
1000    /// in memory as a raw function pointer would. (Meaning its size is usize)
1001    ///
1002    /// # Null
1003    /// This will not cause undefined behavior if a null pointer is used to create the function pointer.
1004    /// Unlike ordinary rust function pointers this type supports null pointers.
1005    /// Attempting to call a null function pointer will panic.
1006    ///
1007    /// # Safety
1008    /// This macro has to be placed in an unsafe block, because it accepts an arbitrary pointer as well as usize.
1009    /// The pointer/usize is interpreted as an address to a function. Should the pointer/usize not in fact be the address
1010    /// of a function with the given signature then this macro causes undefined behavior immediately.
1011    ///
1012    /// The safe version of this macro is `sync_fn_ptr!` which only accepts a rust function type.
1013    ///
1014    /// # Example
1015    /// ```rust
1016    ///
1017    /// use std::ffi::c_void;
1018    /// use sync_ptr::sync_fn_ptr_from_addr;
1019    /// use sync_ptr::SyncFnPtr;
1020    ///
1021    /// extern "C" fn test_function() -> u64 {
1022    ///     123456u64
1023    /// }
1024    ///
1025    /// fn some_function() {
1026    ///     //usually you would get this address from ffi/dlsym/GetProcAddress.
1027    ///     let some_address = test_function as *const c_void;
1028    ///     let test_fn_ptr = unsafe { sync_fn_ptr_from_addr!(extern "C" fn() -> u64, some_address) };
1029    ///     //Type of test_fn_ptr is SyncFnPtr<extern "C" fn() -> u64>
1030    ///     std::thread::spawn(move || {
1031    ///         assert_eq!(test_fn_ptr(), test_function());
1032    ///     }).join().unwrap();
1033    /// }
1034    /// ```
1035    ///
1036    #[macro_export]
1037    macro_rules! sync_fn_ptr_from_addr {
1038    ($sig:ty, $var:expr) => {
1039        {
1040            //The compiler should optimize this out, as this should always hold true.
1041            assert!(core::mem::size_of::<SyncFnPtr::<$sig>>() == core::mem::size_of::<$sig>());
1042
1043            let ptr = $var as *const core::ffi::c_void;
1044            if ptr.is_null() {
1045                SyncFnPtr::<$sig>::default()
1046            } else {
1047                //Safety: Only safe if var is a function pointer.
1048                let x : $sig = core::mem::transmute($var as *const core::ffi::c_void);
1049
1050                _ = move || {
1051                    //Workaround to ensure T is core::marker::FnPtr, which is unfortunately unstable.
1052                    _= core::ptr::fn_addr_eq(x, x);
1053                };
1054
1055                //Safety: SyncFnPtr has repr(transparent)
1056                core::mem::transmute(Some(x))
1057            }
1058        }
1059
1060    };
1061}
1062
1063    #[repr(transparent)]
1064    #[derive(Copy, Clone, Ord, PartialOrd, Hash, Debug, Eq, PartialEq)]
1065    pub struct SyncFnPtr<
1066        T: Pointer + Copy + Clone + Sized + Eq + PartialEq + PartialOrd + Ord + Hash + Debug,
1067    >(Option<T>);
1068    unsafe impl<T: Pointer + Copy + Clone + Sized + Eq + PartialEq + PartialOrd + Ord + Hash + Debug>
1069        Sync for SyncFnPtr<T>
1070    {
1071    }
1072    unsafe impl<T: Pointer + Copy + Clone + Sized + Eq + PartialEq + PartialOrd + Ord + Hash + Debug>
1073        Send for SyncFnPtr<T>
1074    {
1075    }
1076
1077    impl_pointer!(SyncFnPtr);
1078
1079    ///
1080    /// This macro creates a Function Pointer that is Send and guaranteed to have the same representation
1081    /// in memory as a raw function pointer would. (Meaning its size is usize)
1082    ///
1083    /// # Example
1084    /// ```rust
1085    ///
1086    /// use std::ffi::c_void;
1087    /// use sync_ptr::send_fn_ptr;
1088    /// use sync_ptr::SendFnPtr;
1089    ///
1090    /// extern "C" fn test_function() -> u64 {
1091    ///     123456u64
1092    /// }
1093    ///
1094    /// fn some_function() {
1095    ///     let test_fn_ptr = send_fn_ptr!(extern "C" fn() -> u64, test_function);
1096    ///     //Type of test_fn_ptr is SendFnPtr<extern "C" fn() -> u64>
1097    ///     std::thread::spawn(move || {
1098    ///         assert_eq!(test_fn_ptr(), test_function());
1099    ///     }).join().unwrap();
1100    /// }
1101    /// ```
1102    ///
1103    #[macro_export]
1104    macro_rules! send_fn_ptr {
1105        ($sig:ty, $var:expr) => {{
1106            let x = $var as $sig;
1107            _ = move || {
1108                //Workaround to ensure T is core::marker::FnPtr, which is unfortunately unstable.
1109                _ = core::ptr::fn_addr_eq(x, x);
1110            };
1111
1112            //The compiler should optimize this out, as this should always hold true.
1113            assert!(core::mem::size_of::<SendFnPtr::<$sig>>() == core::mem::size_of::<$sig>());
1114
1115            //Safety: SyncFnPtr has repr(transparent)
1116            let n: SendFnPtr<$sig> = unsafe { core::mem::transmute(Some(x)) };
1117
1118            n
1119        }};
1120    }
1121
1122    ///
1123    /// This macro creates a Function Pointer that is Send and guaranteed to have the same representation
1124    /// in memory as a raw function pointer would. (Meaning its size is usize)
1125    ///
1126    /// # Null
1127    /// This will not cause undefined behavior if a null pointer is used to create the function pointer.
1128    /// Unlike ordinary rust function pointers this type supports null pointers.
1129    /// Attempting to call a null function pointer will panic.
1130    ///
1131    /// # Safety
1132    /// This macro has to be placed in an unsafe block, because it accepts an arbitrary pointer as well as usize.
1133    /// The pointer/usize is interpreted as an address to a function. Should the pointer/usize not in fact be the address
1134    /// of a function with the given signature then this macro causes undefined behavior immediately.
1135    ///
1136    /// The safe version of this macro is `sync_fn_ptr!` which only accepts a rust function type.
1137    ///
1138    /// # Example
1139    /// ```rust
1140    ///
1141    /// use std::ffi::c_void;
1142    /// use sync_ptr::send_fn_ptr_from_addr;
1143    /// use sync_ptr::SendFnPtr;
1144    ///
1145    /// extern "C" fn test_function() -> u64 {
1146    ///     123456u64
1147    /// }
1148    ///
1149    /// fn some_function() {
1150    ///     //usually you would get this address from ffi/dlsym/GetProcAddress.
1151    ///     let some_address = test_function as *const c_void;
1152    ///     let test_fn_ptr = unsafe { send_fn_ptr_from_addr!(extern "C" fn() -> u64, some_address) };
1153    ///     //Type of test_fn_ptr is SendFnPtr<extern "C" fn() -> u64>
1154    ///     std::thread::spawn(move || {
1155    ///         assert_eq!(test_fn_ptr(), test_function());
1156    ///     }).join().unwrap();
1157    /// }
1158    /// ```
1159    #[macro_export]
1160    macro_rules! send_fn_ptr_from_addr {
1161    ($sig:ty, $var:expr) => {
1162        {
1163            //The compiler should optimize this out, as this should always hold true.
1164            assert!(core::mem::size_of::<SendFnPtr::<$sig>>() == core::mem::size_of::<$sig>());
1165
1166            let ptr = $var as *const core::ffi::c_void;
1167            if ptr.is_null() {
1168                SendFnPtr::<$sig>::default()
1169            } else {
1170                //Safety: Only safe if var is a function pointer.
1171                let x : $sig = core::mem::transmute($var as *const core::ffi::c_void);
1172
1173                _ = move || {
1174                    //Workaround to ensure T is core::marker::FnPtr, which is unfortunately unstable.
1175                    _= core::ptr::fn_addr_eq(x, x);
1176                };
1177
1178                //Safety: SendFnPtr has repr(transparent)
1179                core::mem::transmute(Some(x))
1180            }
1181        }
1182
1183    };
1184}
1185
1186    #[repr(transparent)]
1187    #[derive(Copy, Clone, Ord, PartialOrd, Hash, Debug, Eq, PartialEq)]
1188    pub struct SendFnPtr<
1189        T: Pointer + Copy + Clone + Sized + Eq + PartialEq + PartialOrd + Ord + Hash + Debug,
1190    >(Option<T>);
1191    unsafe impl<T: Pointer + Copy + Clone + Sized + Eq + PartialEq + PartialOrd + Ord + Hash + Debug>
1192        Send for SendFnPtr<T>
1193    {
1194    }
1195
1196    impl_pointer!(SendFnPtr);
1197}
1198
1199#[cfg(feature = "fnptr")]
1200pub use fnptr::*;
1201
1202#[cfg(doctest)]
1203#[cfg(feature = "fnptr")]
1204#[doc = include_str!("../README.md")]
1205struct ReadmeDocTests;