astd/macros.rs
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
/// A simple macro that ignores all of its contents and does nothing.
///
/// # Use
///
/// This macro exists to enable expansion of repeat or optional rule groups
/// that may not explicitly make use of that argument. For example, sometimes
/// the conditional inclusion of a token might want to generate something not
/// using that meta-variable -- but expansion requires at least one meta-variable
/// from the group to be specified to not be ambiguous. With this macro, you can
/// still "use" the meta-variable without actually actively using it.
///
/// # Example
///
/// ```
/// # use astd::phantom_fragment;
/// macro_rules! generate{
/// ($A:ident, $($B:ident)?) => {
/// $(
/// phantom_fragment!($B);
/// impl $A {
/// // When $B is present, define this function without using $B.
/// fn do_something(&self) { /* ... */ }
/// }
/// )?
/// }
/// }
/// ```
#[macro_export]
macro_rules! phantom_fragment {
($($_:tt)*) => {};
($_:block) => {};
($_:expr) => {};
($_:ident) => {};
($_:item) => {};
($_:lifetime) => {};
($_:literal) => {};
($_:meta) => {};
($_:pat) => {};
($_:pat_param) => {};
($_:path) => {};
($_:stmt) => {};
($_:ty) => {};
($_:vis) => {};
}
/// Defines the input types as being transparent wrappers around another type,
/// which enables conversions between reference types.
#[macro_export]
macro_rules! transparent {
($($Outter:ident.$Ex:tt => $Inner:ty$(,)?)+) => {
$(
unsafe impl $crate::convert::Transparent for $Outter {
type Wrapped = $Inner;
}
impl AsRef<$Inner> for $Outter {
fn as_ref(&self) -> &$Inner {
&self.$Ex
}
}
impl AsMut<$Inner> for $Outter {
fn as_mut(&mut self) -> &mut $Inner {
&mut self.$Ex
}
}
impl ::astd::convert::Take<$Inner> for $Outter {
unsafe fn take(self) -> $Inner {
self.$Ex
}
}
impl std::ops::Deref for $Outter {
type Target = $Inner;
fn deref(&self) -> &Self::Target {
&self.$Ex
}
}
impl std::ops::DerefMut for $Outter {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.$Ex
}
}
)+
};
}