From a5094fe873603cb71ef1e080485f60930504d604 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 2 Sep 2024 14:04:52 -0700 Subject: [PATCH] common impls between matrix and vector --- fixed_wide_vectors/src/macros/common.rs | 102 ++++++++++++++++++++++++ fixed_wide_vectors/src/macros/matrix.rs | 20 +++++ fixed_wide_vectors/src/macros/mod.rs | 1 + fixed_wide_vectors/src/macros/vector.rs | 97 +--------------------- fixed_wide_vectors/src/matrix.rs | 22 ++--- fixed_wide_vectors/src/vector.rs | 18 ++--- 6 files changed, 146 insertions(+), 114 deletions(-) create mode 100644 fixed_wide_vectors/src/macros/common.rs diff --git a/fixed_wide_vectors/src/macros/common.rs b/fixed_wide_vectors/src/macros/common.rs new file mode 100644 index 0000000..952ff30 --- /dev/null +++ b/fixed_wide_vectors/src/macros/common.rs @@ -0,0 +1,102 @@ +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_common { + ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { + impl $struct { + /// 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(self, f: F) -> $struct + where + F: Fn(T) -> U + { + $struct { + $( $field: f(self.$field) ), + + } + } + } + + impl $struct { + /// 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 ), + + } + } + } + } +} diff --git a/fixed_wide_vectors/src/macros/matrix.rs b/fixed_wide_vectors/src/macros/matrix.rs index f9375e7..d9a858f 100644 --- a/fixed_wide_vectors/src/macros/matrix.rs +++ b/fixed_wide_vectors/src/macros/matrix.rs @@ -2,6 +2,26 @@ #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix { + ( + ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), + ( $($generic_outer: tt), + ) + ) => { + $crate::impl_common!($struct_outer { $($field_outer), + }, ( $($generic_outer), + ), $size_outer); + impl $struct_outer { + #[inline(always)] + pub fn to_vector(self) -> $vector_outer { + $vector_outer { + $( + $vector_field_outer: self.$field_outer + ), + + } + } + } + } +} +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_matrix_inner { ( ($struct_outer: ident { $($field_outer: ident), + }, $vector_outer: ident { $($vector_field_outer: ident), + }, $size_outer: expr), ($struct_inner: ident { $($field_inner: ident), + }, $matrix_inner: ident { $($matrix_field_inner: ident), + }, $size_inner: expr), diff --git a/fixed_wide_vectors/src/macros/mod.rs b/fixed_wide_vectors/src/macros/mod.rs index 9dfc914..30d20cc 100644 --- a/fixed_wide_vectors/src/macros/mod.rs +++ b/fixed_wide_vectors/src/macros/mod.rs @@ -1,5 +1,6 @@ #[cfg(feature="fixed_wide")] pub mod fixed_wide; +pub mod common; pub mod vector; pub mod matrix; diff --git a/fixed_wide_vectors/src/macros/vector.rs b/fixed_wide_vectors/src/macros/vector.rs index a68d0d7..034f8ed 100644 --- a/fixed_wide_vectors/src/macros/vector.rs +++ b/fixed_wide_vectors/src/macros/vector.rs @@ -3,102 +3,7 @@ #[macro_export(local_inner_macros)] macro_rules! impl_vector { ( $struct: ident { $($field: ident), + }, ( $($generic: ident), + ), $size: expr ) => { - impl $struct { - /// 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(self, f: F) -> $struct - where - F: Fn(T) -> U - { - $struct { - $( $field: f(self.$field) ), + - } - } - } - - impl $struct { - /// 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 ), + - } - } - } + $crate::impl_common!($struct { $($field), + }, ( $($generic), + ), $size); impl From<[T; $size]> for $struct { fn from(from: [T; $size]) -> Self { diff --git a/fixed_wide_vectors/src/matrix.rs b/fixed_wide_vectors/src/matrix.rs index a1e6943..908cd3d 100644 --- a/fixed_wide_vectors/src/matrix.rs +++ b/fixed_wide_vectors/src/matrix.rs @@ -16,15 +16,19 @@ pub struct Matrix4 { pub w_axis: T, } +crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (T, T)); +crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (T, T, T)); +crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (T, T, T, T)); + crate::impl_extend!(Matrix2 { x_axis, y_axis }, Matrix3, z_axis); crate::impl_extend!(Matrix3 { x_axis, y_axis, z_axis }, Matrix4, w_axis); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T)) ); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T)) ); -crate::impl_matrix!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T)) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Matrix2 { x_axis, y_axis }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Matrix3 { x_axis, y_axis, z_axis }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Matrix2 { x_axis, y_axis }, 2), ((T, T), (T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Matrix3 { x_axis, y_axis, z_axis }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Matrix4 { x_axis, y_axis, z_axis, w_axis }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Matrix4 { x_axis, y_axis, z_axis, w_axis }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); diff --git a/fixed_wide_vectors/src/vector.rs b/fixed_wide_vectors/src/vector.rs index c528b5c..9d9a31e 100644 --- a/fixed_wide_vectors/src/vector.rs +++ b/fixed_wide_vectors/src/vector.rs @@ -70,12 +70,12 @@ crate::impl_vector!(Vector4 { x, y, z, w }, (T, T, T, T), 4); crate::impl_extend!(Vector2 { x, y }, Vector3, z); crate::impl_extend!(Vector3 { x, y, z }, Vector4, w); -crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T)) ); -crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T)) ); -crate::impl_matrix!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T), (T, T)) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); -crate::impl_matrix!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T)) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Vector2 { x, y }, Vector2 { x, y }, 2), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Vector3 { x, y, z }, Vector3 { x, y, z }, 3), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T)) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector2 { x, y }, Vector2 { x, y }, 2), ((T, T), (T, T), (T, T), (T, T)) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector3 { x, y, z }, Vector3 { x, y, z }, 3), ((T, T, T), (T, T, T), (T, T, T), (T, T, T)) ); +crate::impl_matrix_inner!((Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), (Vector4 { x, y, z, w }, Vector4 { x, y, z, w }, 4), ((T, T, T, T), (T, T, T, T), (T, T, T, T), (T, T, T, T)) );