glam_det 2.0.0

A simple and fast 3D math library for games and graphics.
Documentation
// Copyright (C) 2020-2025 glam-det authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

macro_rules! impl_type_cast_methods {
    ($ty1:ident, $ty2:ident, $fn_name1:ident, $fn_name2:ident) => {
        impl $ty1 {
            #[inline]
            pub(crate) fn $fn_name1(self) -> $ty2 {
                unsafe { ConstUnionHack128bit { $ty1: self }.$ty2 }
            }
        }
        impl $ty2 {
            #[allow(unused)]
            #[inline]
            pub(crate) fn $fn_name2(self) -> $ty1 {
                unsafe { ConstUnionHack128bit { $ty2: self }.$ty1 }
            }
        }
    };
}

macro_rules! impl_wide_partial_eq {
    ($t: ty) => {
        impl PartialEq for $t {
            #[inline]
            fn eq(&self, rhs: &Self) -> bool {
                self.0 == rhs.0
            }
        }
    };
}

#[cfg(not(feature = "scalar-math"))]
macro_rules! impl_wide_bit_ops {
    ($t: ident) => {
        impl_op_ex!(! |a: &$t| -> $t { $t(!a.0) });
        impl_op_ex!(^ |a: &$t, b: &$t| -> $t { $t(a.0 ^ b.0) });
        impl_op_ex!(| |a: &$t, b: &$t| -> $t { $t(a.0 | b.0) });
        impl_op_ex!(& |a: &$t, b: &$t| -> $t { $t(a.0 & b.0) });
    };
}

#[cfg(not(feature = "scalar-math"))]
macro_rules! impl_wide_interge_shift_ops {
    ($src_ty:ident, $( $shift_ty:ident ),*) => {
        $(
            impl_op_ex!(<< |a: &$src_ty, b: &$shift_ty| -> $src_ty { $src_ty(a.0 << *b) });
            impl_op_ex!(>> |a: &$src_ty, b: &$shift_ty| -> $src_ty { $src_ty(a.0 >> *b) });
            impl IntegerShiftOps<$shift_ty> for $src_ty {}
        )*
    };
}

#[cfg(feature = "scalar-math")]
macro_rules! impl_wide_bit_ops {
    ($t: ident) => {
        impl_op_ex!(! |a: &$t| -> $t { $t(a.0.map(|x| !x)) });
        impl_op_ex!(^ |a: &$t, b: &$t| -> $t { $t::zip_map(*a, *b, |x, y| x ^ y) });
        impl_op_ex!(| |a: &$t, b: &$t| -> $t { $t::zip_map(*a, *b, |x, y| x | y) });
        impl_op_ex!(& |a: &$t, b: &$t| -> $t { $t::zip_map(*a, *b, |x, y| x & y) });
    };
}

#[cfg(feature = "scalar-math")]
macro_rules! impl_wide_interge_shift_ops {
    ($src_ty:ident, $( $shift_ty:ident ),*) => {
        $(
            impl_op_ex!(<< |a: &$src_ty, b: &$shift_ty| -> $src_ty { $src_ty(a.0.map(|x| x << *b)) });
            impl_op_ex!(>> |a: &$src_ty, b: &$shift_ty| -> $src_ty { $src_ty(a.0.map(|x| x >> *b)) });
            impl IntegerShiftOps<$shift_ty> for $src_ty {}
        )*
    };
}

macro_rules! impl_default {
    ($wide_ty: ident) => {
        impl Default for $wide_ty {
            fn default() -> Self {
                Self::ZERO
            }
        }
    };
}

#[cfg(feature = "scalar-math")]
macro_rules! add_into {
    ($e: expr) => {
        $e
    };
}

#[cfg(not(feature = "scalar-math"))]
macro_rules! add_into {
    ($e: expr) => {
        $e.into()
    };
}

#[cfg(feature = "scalar-math")]
macro_rules! as_array_mut {
    ($e: expr) => {
        &mut $e
    };
}

#[cfg(not(feature = "scalar-math"))]
macro_rules! as_array_mut {
    ($e: expr) => {
        $e.as_array_mut()
    };
}

#[cfg(feature = "scalar-math")]
macro_rules! as_array_ref {
    ($e: expr) => {
        &$e
    };
}

#[cfg(not(feature = "scalar-math"))]
macro_rules! as_array_ref {
    ($e: expr) => {
        $e.as_array_ref()
    };
}

macro_rules! impl_wide_scalar_ops {
    ($wide_ty: ty, $scalar_ty: ty) => {
        impl Add<$scalar_ty> for $wide_ty {
            type Output = $wide_ty;

            fn add(self, rhs: $scalar_ty) -> $wide_ty {
                self + <$wide_ty>::const_splat(rhs)
            }
        }

        impl Add<$wide_ty> for $scalar_ty {
            type Output = $wide_ty;

            fn add(self, rhs: $wide_ty) -> $wide_ty {
                <$wide_ty>::const_splat(self) + rhs
            }
        }

        impl Sub<$scalar_ty> for $wide_ty {
            type Output = $wide_ty;

            fn sub(self, rhs: $scalar_ty) -> $wide_ty {
                self - <$wide_ty>::const_splat(rhs)
            }
        }

        impl Sub<$wide_ty> for $scalar_ty {
            type Output = $wide_ty;

            fn sub(self, rhs: $wide_ty) -> $wide_ty {
                <$wide_ty>::const_splat(self) - rhs
            }
        }

        impl Mul<$scalar_ty> for $wide_ty {
            type Output = $wide_ty;

            fn mul(self, rhs: $scalar_ty) -> $wide_ty {
                self * <$wide_ty>::const_splat(rhs)
            }
        }

        impl Mul<$wide_ty> for $scalar_ty {
            type Output = $wide_ty;

            fn mul(self, rhs: $wide_ty) -> $wide_ty {
                <$wide_ty>::const_splat(self) * rhs
            }
        }

        impl Div<$scalar_ty> for $wide_ty {
            type Output = $wide_ty;

            fn div(self, rhs: $scalar_ty) -> $wide_ty {
                self / <$wide_ty>::const_splat(rhs)
            }
        }

        impl Div<$wide_ty> for $scalar_ty {
            type Output = $wide_ty;

            fn div(self, rhs: $wide_ty) -> $wide_ty {
                <$wide_ty>::const_splat(self) / rhs
            }
        }

        impl Rem<$scalar_ty> for $wide_ty {
            type Output = $wide_ty;

            fn rem(self, rhs: $scalar_ty) -> $wide_ty {
                self % <$wide_ty>::const_splat(rhs)
            }
        }

        impl Rem<$wide_ty> for $scalar_ty {
            type Output = $wide_ty;

            fn rem(self, rhs: $wide_ty) -> $wide_ty {
                <$wide_ty>::const_splat(self) % rhs
            }
        }
    };
}

pub(super) use add_into;
pub(super) use as_array_mut;
pub(super) use as_array_ref;
pub(super) use impl_default;
pub(super) use impl_type_cast_methods;
pub(super) use impl_wide_bit_ops;
pub(super) use impl_wide_interge_shift_ops;
pub(super) use impl_wide_partial_eq;
pub(super) use impl_wide_scalar_ops;