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}