#![macro_use]
macro_rules! impl_operator {
(<$S:ident: $Constraint:ident> $Op:ident for $Lhs:ty {
fn $op:ident($x:ident) -> $Output:ty { $body:expr }
}) => {
impl<$S: $Constraint> $Op for $Lhs {
type Output = $Output;
#[inline]
fn $op(self) -> $Output {
let $x = self; $body
}
}
impl<'a, $S: $Constraint> $Op for &'a $Lhs {
type Output = $Output;
#[inline]
fn $op(self) -> $Output {
let $x = self; $body
}
}
};
(<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ident> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
};
(<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, $S: $Constraint> $Op<&'a $Rhs> for $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, 'b, $S: $Constraint> $Op<&'a $Rhs> for &'b $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
};
($Op:ident<$Rhs:ident<$S:ident>> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl $Op<$Rhs<$S>> for $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: $Rhs<$S>) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a> $Op<&'a $Rhs<$S>> for $Lhs {
type Output = $Output;
#[inline]
fn $op(self, other: &'a $Rhs<$S>) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
};
}
macro_rules! impl_assignment_operator {
(<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident(&mut $lhs:ident, $rhs:ident) $body:block
}) => {
impl<$S: $Constraint + $Op<$S>> $Op<$Rhs> for $Lhs {
#[inline]
fn $op(&mut $lhs, $rhs: $Rhs) $body
}
};
}
macro_rules! fold_array {
(&$method:ident, { $x:expr }) => { *$x };
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };
(&$method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method(&$y).$method(&$z).$method(&$w) };
($method:ident, { $x:expr }) => { $x };
($method:ident, { $x:expr, $y:expr }) => { $x.$method($y) };
($method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method($y).$method($z) };
($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method($y).$method($z).$method($w) };
}
macro_rules! impl_fixed_array_conversions {
($ArrayN:ident <$S:ident> { $($field:ident : $index:expr),+ }, $n:expr) => {
impl<$S> Into<[$S; $n]> for $ArrayN<$S> {
#[inline]
fn into(self) -> [$S; $n] {
match self { $ArrayN { $($field),+ } => [$($field),+] }
}
}
impl<$S> AsRef<[$S; $n]> for $ArrayN<$S> {
#[inline]
fn as_ref(&self) -> &[$S; $n] {
unsafe { mem::transmute(self) }
}
}
impl<$S> AsMut<[$S; $n]> for $ArrayN<$S> {
#[inline]
fn as_mut(&mut self) -> &mut [$S; $n] {
unsafe { mem::transmute(self) }
}
}
impl<$S: Clone> From<[$S; $n]> for $ArrayN<$S> {
#[inline]
fn from(v: [$S; $n]) -> $ArrayN<$S> {
$ArrayN { $($field: v[$index].clone()),+ }
}
}
impl<'a, $S> From<&'a [$S; $n]> for &'a $ArrayN<$S> {
#[inline]
fn from(v: &'a [$S; $n]) -> &'a $ArrayN<$S> {
unsafe { mem::transmute(v) }
}
}
impl<'a, $S> From<&'a mut [$S; $n]> for &'a mut $ArrayN<$S> {
#[inline]
fn from(v: &'a mut [$S; $n]) -> &'a mut $ArrayN<$S> {
unsafe { mem::transmute(v) }
}
}
}
}
macro_rules! impl_tuple_conversions {
($ArrayN:ident <$S:ident> { $($field:ident),+ }, $Tuple:ty) => {
impl<$S> Into<$Tuple> for $ArrayN<$S> {
#[inline]
fn into(self) -> $Tuple {
match self { $ArrayN { $($field),+ } => ($($field),+,) }
}
}
impl<$S> AsRef<$Tuple> for $ArrayN<$S> {
#[inline]
fn as_ref(&self) -> &$Tuple {
unsafe { mem::transmute(self) }
}
}
impl<$S> AsMut<$Tuple> for $ArrayN<$S> {
#[inline]
fn as_mut(&mut self) -> &mut $Tuple {
unsafe { mem::transmute(self) }
}
}
impl<$S> From<$Tuple> for $ArrayN<$S> {
#[inline]
fn from(v: $Tuple) -> $ArrayN<$S> {
match v { ($($field),+,) => $ArrayN { $($field: $field),+ } }
}
}
impl<'a, $S> From<&'a $Tuple> for &'a $ArrayN<$S> {
#[inline]
fn from(v: &'a $Tuple) -> &'a $ArrayN<$S> {
unsafe { mem::transmute(v) }
}
}
impl<'a, $S> From<&'a mut $Tuple> for &'a mut $ArrayN<$S> {
#[inline]
fn from(v: &'a mut $Tuple) -> &'a mut $ArrayN<$S> {
unsafe { mem::transmute(v) }
}
}
}
}
macro_rules! impl_index_operators {
($VectorN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
impl<$S> Index<$I> for $VectorN<$S> {
type Output = $Output;
#[inline]
fn index<'a>(&'a self, i: $I) -> &'a $Output {
let v: &[$S; $n] = self.as_ref(); &v[i]
}
}
impl<$S> IndexMut<$I> for $VectorN<$S> {
#[inline]
fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
let v: &mut [$S; $n] = self.as_mut(); &mut v[i]
}
}
}
}
#[cfg(feature = "simd")]
macro_rules! impl_operator_default {
(<$S:ident: $Constraint:ident> $Op:ident for $Lhs:ty {
fn $op:ident($x:ident) -> $Output:ty { $body:expr }
}) => {
impl<$S: $Constraint> $Op for $Lhs {
type Output = $Output;
#[inline]
default fn $op(self) -> $Output {
let $x = self; $body
}
}
impl<'a, $S: $Constraint> $Op for &'a $Lhs {
type Output = $Output;
#[inline]
default fn $op(self) -> $Output {
let $x = self; $body
}
}
};
(<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ident> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
};
(<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, $S: $Constraint> $Op<&'a $Rhs> for $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a, 'b, $S: $Constraint> $Op<&'a $Rhs> for &'b $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
};
($Op:ident<$Rhs:ident<$S:ident>> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl $Op<$Rhs<$S>> for $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: $Rhs<$S>) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
impl<'a> $Op<&'a $Rhs<$S>> for $Lhs {
type Output = $Output;
#[inline]
default fn $op(self, other: &'a $Rhs<$S>) -> $Output {
let ($lhs, $rhs) = (self, other); $body
}
}
};
}
#[cfg(feature = "simd")]
macro_rules! impl_assignment_operator_default {
(<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident(&mut $lhs:ident, $rhs:ident) $body:block
}) => {
impl<$S: $Constraint + $Op<$S>> $Op<$Rhs> for $Lhs {
#[inline]
default fn $op(&mut $lhs, $rhs: $Rhs) $body
}
};
}
#[cfg(feature = "simd")]
macro_rules! impl_operator_simd {
([$Simd:ident]; $Op:ident for $Lhs:ty {
fn $op:ident($x:ident) -> $Output:ty { $body:expr }
}) => {
impl $Op for $Lhs {
#[inline]
fn $op(self) -> $Output {
let $x: $Simd = self.into(); $body
}
}
};
(@rs [$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl $Op<$Rhs> for $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), $Simd::splat(other)); $body
}
}
impl<'a> $Op<$Rhs> for &'a $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), $Simd::splat(other)); $body
}
}
};
([$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ty {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl $Op<$Rhs> for $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), other.into()); $body
}
}
impl<'a> $Op<&'a $Rhs> for $Lhs {
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), (*other).into()); $body
}
}
impl<'a> $Op<$Rhs> for &'a $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), other.into()); $body
}
}
impl<'a, 'b> $Op<&'a $Rhs> for &'b $Lhs {
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), (*other).into()); $body
}
}
};
(@ls [$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ident {
fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
}) => {
impl $Op<$Rhs> for $Lhs {
#[inline]
fn $op(self, other: $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), other.into()); $body
}
}
impl<'a> $Op<&'a $Rhs> for $Lhs {
#[inline]
fn $op(self, other: &'a $Rhs) -> $Output {
let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), (*other).into()); $body
}
}
};
}
#[cfg(feature = "mint")]
macro_rules! impl_mint_conversions {
($ArrayN:ident { $($field:ident),+ }, $Mint:ident) => {
impl<S: Clone> Into<mint::$Mint<S>> for $ArrayN<S> {
#[inline]
fn into(self) -> mint::$Mint<S> {
mint::$Mint::from([$(self.$field),+])
}
}
impl<S> From<mint::$Mint<S>> for $ArrayN<S> {
#[inline]
fn from(v: mint::$Mint<S>) -> Self {
$ArrayN { $( $field: v.$field, )+ }
}
}
}
}
include!(concat!(env!("OUT_DIR"), "/swizzle_operator_macro.rs"));