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;