move vector2 macro code
This commit is contained in:
parent
78f860c672
commit
f531e8d8ee
@ -1,291 +1,4 @@
|
|||||||
#[cfg(feature="fixed_wide_traits")]
|
#[cfg(feature="fixed_wide_traits")]
|
||||||
pub mod wide;
|
pub mod wide;
|
||||||
|
|
||||||
// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license)
|
pub mod vector;
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export(local_inner_macros)]
|
|
||||||
macro_rules! impl_vector {
|
|
||||||
( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => {
|
|
||||||
impl<T> $struct<T> {
|
|
||||||
/// Constructs a new vector with the specified values for each field.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_wide_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(0, 0);
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2.x, 0);
|
|
||||||
/// assert_eq!(vec2.y, 0);
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub const fn new( $($field: T), + ) -> Self {
|
|
||||||
Self {
|
|
||||||
$( $field ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes the vector and returns its values as an array.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_wide_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(0, 0);
|
|
||||||
/// let array = vec2.to_array();
|
|
||||||
///
|
|
||||||
/// assert_eq!(array, [0, 0]);
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn to_array(self) -> [T; $size] {
|
|
||||||
[ $(self.$field), + ]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes the vector and returns its values as a tuple.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_wide_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(0, 0);
|
|
||||||
/// let tuple = vec2.to_tuple();
|
|
||||||
///
|
|
||||||
/// assert_eq!(tuple, (0, 0));
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn to_tuple(self) -> ( $($generic), + ) {
|
|
||||||
( $(self.$field), + )
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes the vector and returns a new vector with the given function applied on each field.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_wide_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(1, 2)
|
|
||||||
/// .map(|i| i * 2);
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(2, 4));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn map<F, U>(self, f: F) -> $struct<U>
|
|
||||||
where
|
|
||||||
F: Fn(T) -> U
|
|
||||||
{
|
|
||||||
$struct {
|
|
||||||
$( $field: f(self.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy> $struct<T> {
|
|
||||||
/// Constructs a vector using the given `value` as the value for all of its fields.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_wide_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::from_value(0);
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(0, 0));
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub const fn from_value(value: T) -> Self {
|
|
||||||
Self {
|
|
||||||
$( $field: value ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<[T; $size]> for $struct<T> {
|
|
||||||
fn from(from: [T; $size]) -> Self {
|
|
||||||
let mut iterator = from.into_iter();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
// SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)`
|
|
||||||
$( $field: unsafe { iterator.next().unwrap_unchecked() } ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<($($generic), +)> for $struct<T> {
|
|
||||||
fn from(from: ($($generic), +)) -> Self {
|
|
||||||
let ( $($field), + ) = from;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
$( $field ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: core::fmt::Debug> core::fmt::Debug for $struct<T> {
|
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
||||||
let identifier = core::stringify!($struct);
|
|
||||||
|
|
||||||
f.debug_struct(identifier)
|
|
||||||
$( .field( core::stringify!($field), &self.$field ) ) +
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: PartialEq> PartialEq for $struct<T> {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
$( self.$field == other.$field ) && +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Eq> Eq for $struct<T> { }
|
|
||||||
|
|
||||||
impl<T: core::hash::Hash> core::hash::Hash for $struct<T> {
|
|
||||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
$( self.$field.hash(state); ) +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Clone> Clone for $struct<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
$( $field: self.$field.clone() ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy> Copy for $struct<T> { }
|
|
||||||
|
|
||||||
impl<T: Default> Default for $struct<T> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
$( $field: T::default() ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Ord> $struct<T> {
|
|
||||||
pub fn min(self, rhs: Self) -> $struct<T> {
|
|
||||||
$struct{
|
|
||||||
$( $field: self.$field.min(rhs.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn max(self, rhs: Self) -> $struct<T> {
|
|
||||||
$struct{
|
|
||||||
$( $field: self.$field.max(rhs.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn cmp(self, rhs: Self) -> $struct<core::cmp::Ordering> {
|
|
||||||
$struct{
|
|
||||||
$( $field: self.$field.cmp(&rhs.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn lt(self, rhs: Self) -> $struct<bool> {
|
|
||||||
$struct{
|
|
||||||
$( $field: self.$field.lt(&rhs.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn gt(self, rhs: Self) -> $struct<bool> {
|
|
||||||
$struct{
|
|
||||||
$( $field: self.$field.gt(&rhs.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn ge(self, rhs: Self) -> $struct<bool> {
|
|
||||||
$struct{
|
|
||||||
$( $field: self.$field.ge(&rhs.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn le(self, rhs: Self) -> $struct<bool> {
|
|
||||||
$struct{
|
|
||||||
$( $field: self.$field.le(&rhs.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl $struct<bool>{
|
|
||||||
pub fn all(&self)->bool{
|
|
||||||
const ALL:[bool;$size]=[true;$size];
|
|
||||||
core::matches!(self.to_array(),ALL)
|
|
||||||
}
|
|
||||||
pub fn any(&self)->bool{
|
|
||||||
$( self.$field )|| +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: core::ops::Neg<Output = T>> core::ops::Neg for $struct<T> {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
fn neg(self) -> Self::Output {
|
|
||||||
Self {
|
|
||||||
$( $field: -self.$field ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Impl arithmetic pperators
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, AddAssign, add_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, Add, add, Self );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, SubAssign, sub_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, Sub, sub, Self );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, MulAssign, mul_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, Mul, mul, Self );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, DivAssign, div_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, Div, div, Self );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, RemAssign, rem_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, Rem, rem, Self );
|
|
||||||
|
|
||||||
// Impl bitwise operators
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, BitAnd, bitand, Self );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, BitOr, bitor, Self );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign );
|
|
||||||
$crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self );
|
|
||||||
|
|
||||||
// Impl floating-point based methods
|
|
||||||
#[cfg(feature="fixed_wide_traits")]
|
|
||||||
$crate::impl_wide_operations!( $struct { $($field), + }, $size );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export(local_inner_macros)]
|
|
||||||
macro_rules! impl_operator {
|
|
||||||
( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => {
|
|
||||||
impl<T:core::ops::$trait<Output=T>> core::ops::$trait for $struct<T> {
|
|
||||||
type Output = $output;
|
|
||||||
|
|
||||||
fn $method(self, other: Self) -> Self::Output {
|
|
||||||
Self {
|
|
||||||
$( $field: self.$field.$method(other.$field) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T:core::ops::$trait<Output=T>+Copy> core::ops::$trait<T> for $struct<T>{
|
|
||||||
type Output = $output;
|
|
||||||
|
|
||||||
fn $method(self, other: T) -> Self::Output {
|
|
||||||
$struct {
|
|
||||||
$( $field: self.$field.$method(other) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => {
|
|
||||||
impl<T: core::ops::$trait> core::ops::$trait for $struct<T> {
|
|
||||||
fn $method(&mut self, other: Self) {
|
|
||||||
$( self.$field.$method(other.$field) ); +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: core::ops::$trait + Copy> core::ops::$trait<T> for $struct<T> {
|
|
||||||
fn $method(&mut self, other: T) {
|
|
||||||
$( self.$field.$method(other) ); +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
288
fixed_wide_vectors/src/macros/vector.rs
Normal file
288
fixed_wide_vectors/src/macros/vector.rs
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license)
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export(local_inner_macros)]
|
||||||
|
macro_rules! impl_vector {
|
||||||
|
( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => {
|
||||||
|
impl<T> $struct<T> {
|
||||||
|
/// Constructs a new vector with the specified values for each field.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use fixed_wide_vectors::Vector2;
|
||||||
|
///
|
||||||
|
/// let vec2 = Vector2::new(0, 0);
|
||||||
|
///
|
||||||
|
/// assert_eq!(vec2.x, 0);
|
||||||
|
/// assert_eq!(vec2.y, 0);
|
||||||
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
|
pub const fn new( $($field: T), + ) -> Self {
|
||||||
|
Self {
|
||||||
|
$( $field ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consumes the vector and returns its values as an array.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use fixed_wide_vectors::Vector2;
|
||||||
|
///
|
||||||
|
/// let vec2 = Vector2::new(0, 0);
|
||||||
|
/// let array = vec2.to_array();
|
||||||
|
///
|
||||||
|
/// assert_eq!(array, [0, 0]);
|
||||||
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn to_array(self) -> [T; $size] {
|
||||||
|
[ $(self.$field), + ]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consumes the vector and returns its values as a tuple.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use fixed_wide_vectors::Vector2;
|
||||||
|
///
|
||||||
|
/// let vec2 = Vector2::new(0, 0);
|
||||||
|
/// let tuple = vec2.to_tuple();
|
||||||
|
///
|
||||||
|
/// assert_eq!(tuple, (0, 0));
|
||||||
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn to_tuple(self) -> ( $($generic), + ) {
|
||||||
|
( $(self.$field), + )
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consumes the vector and returns a new vector with the given function applied on each field.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use fixed_wide_vectors::Vector2;
|
||||||
|
///
|
||||||
|
/// let vec2 = Vector2::new(1, 2)
|
||||||
|
/// .map(|i| i * 2);
|
||||||
|
///
|
||||||
|
/// assert_eq!(vec2, Vector2::new(2, 4));
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn map<F, U>(self, f: F) -> $struct<U>
|
||||||
|
where
|
||||||
|
F: Fn(T) -> U
|
||||||
|
{
|
||||||
|
$struct {
|
||||||
|
$( $field: f(self.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> $struct<T> {
|
||||||
|
/// Constructs a vector using the given `value` as the value for all of its fields.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use fixed_wide_vectors::Vector2;
|
||||||
|
///
|
||||||
|
/// let vec2 = Vector2::from_value(0);
|
||||||
|
///
|
||||||
|
/// assert_eq!(vec2, Vector2::new(0, 0));
|
||||||
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
|
pub const fn from_value(value: T) -> Self {
|
||||||
|
Self {
|
||||||
|
$( $field: value ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<[T; $size]> for $struct<T> {
|
||||||
|
fn from(from: [T; $size]) -> Self {
|
||||||
|
let mut iterator = from.into_iter();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
// SAFETY: We know the size of `from` so `iterator.next()` is always `Some(..)`
|
||||||
|
$( $field: unsafe { iterator.next().unwrap_unchecked() } ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<($($generic), +)> for $struct<T> {
|
||||||
|
fn from(from: ($($generic), +)) -> Self {
|
||||||
|
let ( $($field), + ) = from;
|
||||||
|
|
||||||
|
Self {
|
||||||
|
$( $field ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::fmt::Debug> core::fmt::Debug for $struct<T> {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
let identifier = core::stringify!($struct);
|
||||||
|
|
||||||
|
f.debug_struct(identifier)
|
||||||
|
$( .field( core::stringify!($field), &self.$field ) ) +
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: PartialEq> PartialEq for $struct<T> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
$( self.$field == other.$field ) && +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Eq> Eq for $struct<T> { }
|
||||||
|
|
||||||
|
impl<T: core::hash::Hash> core::hash::Hash for $struct<T> {
|
||||||
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
$( self.$field.hash(state); ) +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Clone for $struct<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
$( $field: self.$field.clone() ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> Copy for $struct<T> { }
|
||||||
|
|
||||||
|
impl<T: Default> Default for $struct<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
$( $field: T::default() ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Ord> $struct<T> {
|
||||||
|
pub fn min(self, rhs: Self) -> $struct<T> {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.min(rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn max(self, rhs: Self) -> $struct<T> {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.max(rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn cmp(self, rhs: Self) -> $struct<core::cmp::Ordering> {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.cmp(&rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn lt(self, rhs: Self) -> $struct<bool> {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.lt(&rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn gt(self, rhs: Self) -> $struct<bool> {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.gt(&rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn ge(self, rhs: Self) -> $struct<bool> {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.ge(&rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn le(self, rhs: Self) -> $struct<bool> {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.le(&rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $struct<bool>{
|
||||||
|
pub fn all(&self)->bool{
|
||||||
|
const ALL:[bool;$size]=[true;$size];
|
||||||
|
core::matches!(self.to_array(),ALL)
|
||||||
|
}
|
||||||
|
pub fn any(&self)->bool{
|
||||||
|
$( self.$field )|| +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::ops::Neg<Output = T>> core::ops::Neg for $struct<T> {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
$( $field: -self.$field ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Impl arithmetic pperators
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, AddAssign, add_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, Add, add, Self );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, SubAssign, sub_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, Sub, sub, Self );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, MulAssign, mul_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, Mul, mul, Self );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, DivAssign, div_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, Div, div, Self );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, RemAssign, rem_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, Rem, rem, Self );
|
||||||
|
|
||||||
|
// Impl bitwise operators
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, BitAndAssign, bitand_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, BitAnd, bitand, Self );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, BitOrAssign, bitor_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, BitOr, bitor, Self );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, BitXorAssign, bitxor_assign );
|
||||||
|
$crate::impl_vector_operator!( $struct { $($field), + }, BitXor, bitxor, Self );
|
||||||
|
|
||||||
|
// Impl floating-point based methods
|
||||||
|
#[cfg(feature="fixed_wide_traits")]
|
||||||
|
$crate::impl_wide_vector_operations!( $struct { $($field), + }, $size );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export(local_inner_macros)]
|
||||||
|
macro_rules! impl_vector_operator {
|
||||||
|
( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident, $output: ty ) => {
|
||||||
|
impl<T:core::ops::$trait<Output=T>> core::ops::$trait for $struct<T> {
|
||||||
|
type Output = $output;
|
||||||
|
|
||||||
|
fn $method(self, other: Self) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
$( $field: self.$field.$method(other.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T:core::ops::$trait<Output=T>+Copy> core::ops::$trait<T> for $struct<T>{
|
||||||
|
type Output = $output;
|
||||||
|
|
||||||
|
fn $method(self, other: T) -> Self::Output {
|
||||||
|
$struct {
|
||||||
|
$( $field: self.$field.$method(other) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
( $struct: ident { $($field: ident), + }, $trait: ident, $method: ident ) => {
|
||||||
|
impl<T: core::ops::$trait> core::ops::$trait for $struct<T> {
|
||||||
|
fn $method(&mut self, other: Self) {
|
||||||
|
$( self.$field.$method(other.$field) ); +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::ops::$trait + Copy> core::ops::$trait<T> for $struct<T> {
|
||||||
|
fn $method(&mut self, other: T) {
|
||||||
|
$( self.$field.$method(other) ); +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export(local_inner_macros)]
|
#[macro_export(local_inner_macros)]
|
||||||
macro_rules! impl_wide_operations {
|
macro_rules! impl_wide_vector_operations {
|
||||||
( $struct: ident { $($field: ident), + }, $size: expr ) => {
|
( $struct: ident { $($field: ident), + }, $size: expr ) => {
|
||||||
impl<U,T:Copy+fixed_wide_traits::wide::WideMul<Output=U>> fixed_wide_traits::wide::WideMul for $struct<T> {
|
impl<U,T:Copy+fixed_wide_traits::wide::WideMul<Output=U>> fixed_wide_traits::wide::WideMul for $struct<T> {
|
||||||
type Output=$struct<U>;
|
type Output=$struct<U>;
|
||||||
|
Loading…
Reference in New Issue
Block a user