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