macro_rules! impl_marker(
(@para_rec
[$tra1t:ty, ($($clause:tt)+), ($($type_constr:tt)*)]
(< $($params:tt)*)
) => {
impl< $($params)* $tra1t for $($type_constr)*< $($params)*
where $($clause)+
{}
};
(@para_rec
[$tra1t:ty, ($($clause:tt)+), ($($prev:tt)*)]
($cur:tt $($rest:tt)*)
) => {
impl_marker!(@para_rec
[$tra1t, ($($clause)+), ($($prev)* $cur)]
($($rest)*)
);
};
(@where_rec
[$tra1t:ty, ($($typ3:tt)+), ($($clause:tt)+)]
($(;)*)
) => {
impl_marker!(@para_rec
[$tra1t, ($($clause)+), ()]
($($typ3)+)
);
};
(@where_rec
[$tra1t:ty, ($($typ3:tt)+), ($($clause:tt)+)]
(; $($rest:tt)+)
) => {
impl_marker!(@para_rec
[$tra1t, ($($clause)+), ()]
($($typ3)+)
);
impl_marker!(@rec
[$tra1t, ()]
($($rest)+)
);
};
(@where_rec
[$tra1t:ty, ($($typ3:tt)+), ($($prev:tt)*)]
($cur:tt $($rest:tt)*)
) => {
impl_marker!(@where_rec
[$tra1t, ($($typ3)+), ($($prev)* $cur)]
($($rest)*)
);
};
(@rec
[$tra1t:ty, ($($typ3:tt)*)]
($(;)*)
) => {
impl $tra1t for $($typ3)* { }
};
(@rec
[$tra1t:ty, ($($typ3:tt)*)]
(; $($rest:tt)+)
) => {
impl $tra1t for $($typ3)* { }
impl_marker!(@rec
[$tra1t, ()]
($($rest)+)
);
};
(@rec
[$tra1t:ty, ($($prev:tt)+)]
(where $($rest:tt)+)
) => {
impl_marker!(@where_rec
[$tra1t, ($($prev)+), ()]
($($rest)+)
);
};
(@rec
[$tra1t:ty, ($($prev:tt)*)]
($cur:tt $($rest:tt)*)
) => {
impl_marker!(@rec
[$tra1t, ($($prev)* $cur)]
($($rest)*)
);
};
($tra1t:ty; $($rest:tt)+) => {
impl_marker!(@rec
[$tra1t, ()]
($($rest)+)
);
};
);
macro_rules! impl_ident {
($M:ty; $V:expr; $($T:ty),* $(,)*) => {
$(impl Identity<$M> for $T { #[inline] fn identity() -> $T {$V} })+
}
}
macro_rules! impl_approx_eq {
($V:expr; $($T:ty),* $(,)*) => {
$(impl ApproxEq for $T {
type Eps = $T;
#[inline]
fn default_epsilon() -> Self::Eps { $V }
#[inline]
fn approx_eq_eps(&self, b: &$T, epsilon: &$T) -> bool {
if self < b {
*b - *self <= *epsilon
} else {
*self - *b <= *epsilon
}
}
})+
}
}