core_extensions/macros/
transparent_newtype_macros.rs

1/// For implementing the [`TransparentNewtype`] trait,
2/// to cast between a field and `Self`.
3///
4/// # Example
5///
6/// ```rust
7/// use core_extensions::{TransparentNewtype, TransparentNewtypeExt, impl_transparent_newtype};
8///
9/// use std::cmp::{Ordering, Ord, PartialOrd};
10///
11/// #[repr(transparent)]
12/// #[derive(PartialEq, Eq)]
13/// struct Reverse<T: ?Sized>(T);
14///
15/// unsafe impl<T: ?Sized> TransparentNewtype for Reverse<T> {
16///     type Inner = T;
17///     
18///     // The argument must be `Self`
19///     // (it could also be Reverse<T> in here, it's just easier to always write Self)
20///     impl_transparent_newtype!{Self}
21/// }
22///
23/// /* PartialOrd an Ord impls for Reverse */
24///
25/// let mut list = vec![3, 13, 21, 5, 8, 34];
26///     
27/// <[Reverse<u64>]>::from_inner_mut(&mut list).sort();
28///
29/// assert_eq!(list, vec![34, 21, 13, 8, 5, 3]);
30/// #
31/// # impl<T> PartialOrd for Reverse<T> 
32/// # where
33/// #     T: ?Sized + PartialOrd
34/// # {
35/// #     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
36/// #         self.0.partial_cmp(&other.0)
37/// #             .map(Ordering::reverse)
38/// #     }
39/// # }
40/// # 
41/// # impl<T> Ord for Reverse<T> 
42/// # where
43/// #     T: ?Sized + Ord
44/// # {
45/// #     fn cmp(&self, other: &Self) -> Ordering {
46/// #         self.0.cmp(&other.0).reverse()
47/// #     }
48/// # }
49/// # 
50/// ```
51///
52/// [`TransparentNewtype`]: ./transparent_newtype/trait.TransparentNewtype.html
53#[cfg_attr(feature = "docsrs", doc(cfg(feature = "transparent_newtype")))]
54#[macro_export]
55macro_rules! impl_transparent_newtype {
56    ($S:ty) => (
57        #[inline(always)]
58        fn from_inner_raw(from: *const <$S as $crate::TransparentNewtype>::Inner) -> *const $S {
59            from as _
60        }
61
62        #[inline(always)]
63        fn from_inner_raw_mut(from: *mut <$S as $crate::TransparentNewtype>::Inner) -> *mut $S {
64            from as _
65        }
66
67        #[inline(always)]
68        fn as_inner_raw(this: *const $S) -> *const <$S as $crate::TransparentNewtype>::Inner {
69            this as _
70        }
71
72        #[inline(always)]
73        fn as_inner_raw_mut(this: *mut $S) -> *mut <$S as $crate::TransparentNewtype>::Inner {
74            this as _
75        }
76    )
77}
78
79
80/// For delegating the implementation of the [`TransparentNewtype`] trait to a field.
81///
82/// # Example
83///
84/// ```rust
85/// use core_extensions::{TransparentNewtype, TransparentNewtypeExt};
86///
87/// use std::num::Wrapping;
88///
89/// #[derive(Debug, PartialEq, Eq)]
90/// #[repr(transparent)]
91/// struct Foo<T>(Wrapping<T>);
92///
93/// unsafe impl<T> TransparentNewtype for Foo<T> {
94///     core_extensions::delegate_transparent_newtype_impl!{
95///         // This argument must be `Self`
96///         // (it could also be Foo<T> in here, it's just easier to always write Self)
97///         Self,
98///         // The type of the field that this delegates to
99///         Wrapping<T>
100///     }
101/// }
102/// 
103/// assert_eq!(Foo::<u8>::from_inner(3), Foo(Wrapping(3)));
104/// assert_eq!(Foo::<bool>::from_inner_ref(&true), &Foo(Wrapping(true)));
105/// assert_eq!(Foo::<&str>::from_inner_mut(&mut "hello"), &mut Foo(Wrapping("hello")));
106/// ```
107///
108/// [`TransparentNewtype`]: ./transparent_newtype/trait.TransparentNewtype.html 
109#[cfg_attr(feature = "docsrs", doc(cfg(feature = "transparent_newtype")))]
110#[macro_export]
111macro_rules! delegate_transparent_newtype_impl {
112    ($S:ty, $Field:ty) => (
113        type Inner = <$Field as $crate::TransparentNewtype>::Inner;
114
115        #[inline(always)]
116        fn from_inner_raw(from: *const <$S as $crate::TransparentNewtype>::Inner) -> *const $S {
117            <$Field as $crate::TransparentNewtype>::from_inner_raw(from)
118                as _
119        }
120
121        #[inline(always)]
122        fn from_inner_raw_mut(from: *mut <$S as $crate::TransparentNewtype>::Inner) -> *mut $S {
123            <$Field as $crate::TransparentNewtype>::from_inner_raw_mut(from)
124                as _
125        }
126
127        #[inline(always)]
128        fn as_inner_raw(this: *const $S) -> *const <$S as $crate::TransparentNewtype>::Inner {
129            <$Field as $crate::TransparentNewtype>::as_inner_raw(this as _)
130        }
131
132        #[inline(always)]
133        fn as_inner_raw_mut(this: *mut $S) -> *mut <$S as $crate::TransparentNewtype>::Inner {
134            <$Field as $crate::TransparentNewtype>::as_inner_raw_mut(this as _)
135        }
136    )
137}