From 8810b85a2f23981f61770747edf125b9535d4902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crozet=20S=C3=A9bastien?= Date: Mon, 24 May 2021 17:53:59 +0200 Subject: [PATCH 1/3] Add a point! macro for construction points This macro is similar to the `vector!` macro, except that it builds a point instead of a vector. --- nalgebra-macros/src/lib.rs | 31 +++++++++++++++++++ nalgebra-macros/tests/tests.rs | 55 ++++++++++++++++++++++++++++++++-- src/lib.rs | 2 +- tests/core/macros.rs | 3 +- 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/nalgebra-macros/src/lib.rs b/nalgebra-macros/src/lib.rs index 5b1dd677..beddfc74 100644 --- a/nalgebra-macros/src/lib.rs +++ b/nalgebra-macros/src/lib.rs @@ -280,3 +280,34 @@ pub fn dvector(stream: TokenStream) -> TokenStream { }; proc_macro::TokenStream::from(output) } + +/// Construct a fixed-size point directly from data. +/// +/// **Note: Requires the `macro` feature to be enabled (enabled by default)**. +/// +/// Similarly to [`vector!`], this macro facilitates easy construction of points. +/// +/// `point!` is intended to be the most readable and performant way of constructing small, +/// points, and it is usable in `const fn` contexts. +/// +/// ## Examples +/// +/// ``` +/// use nalgebra::point; +/// +/// // Produces a Point3<_> +/// let v = point![1, 2, 3]; +/// ``` +#[proc_macro] +pub fn point(stream: TokenStream) -> TokenStream { + let vector = parse_macro_input!(stream as Vector); + let len = vector.len(); + let array_tokens = vector.to_array_tokens(); + let output = quote! { + nalgebra::Point::<_, #len> { + coords: nalgebra::SVector::<_, #len> + ::from_array_storage(nalgebra::ArrayStorage([#array_tokens])) + } + }; + proc_macro::TokenStream::from(output) +} diff --git a/nalgebra-macros/tests/tests.rs b/nalgebra-macros/tests/tests.rs index 339dd048..e69f9e6b 100644 --- a/nalgebra-macros/tests/tests.rs +++ b/nalgebra-macros/tests/tests.rs @@ -1,9 +1,10 @@ use nalgebra::{ DMatrix, DVector, Matrix1x2, Matrix1x3, Matrix1x4, Matrix2, Matrix2x1, Matrix2x3, Matrix2x4, - Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, SMatrix, - SVector, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, + Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, PEoint4, + Point, Point1, Point2, Point3, Point4, Point5, Point6, SMatrix, SVector, Vector1, Vector2, + Vector3, Vector4, Vector5, Vector6, }; -use nalgebra_macros::{dmatrix, dvector, matrix, vector}; +use nalgebra_macros::{dmatrix, dvector, matrix, point, vector}; fn check_statically_same_type(_: &T, _: &T) {} @@ -106,6 +107,19 @@ fn vector_small_dims_exhaustive() { assert_eq_and_type!(vector![1, 2, 3, 4, 5, 6], Vector6::new(1, 2, 3, 4, 5, 6)); } +// Skip rustfmt because it just makes the test bloated without making it more readable +#[rustfmt::skip] +#[test] +fn point_small_dims_exhaustive() { + assert_eq_and_type!(point![], Point::::origin()); + assert_eq_and_type!(point![1], Point1::::new(1)); + assert_eq_and_type!(point![1, 2], Point2::new(1, 2)); + assert_eq_and_type!(point![1, 2, 3], Point3::new(1, 2, 3)); + assert_eq_and_type!(point![1, 2, 3, 4], Point4::new(1, 2, 3, 4)); + assert_eq_and_type!(point![1, 2, 3, 4, 5], Point5::new(1, 2, 3, 4, 5)); + assert_eq_and_type!(point![1, 2, 3, 4, 5, 6], Point6::new(1, 2, 3, 4, 5, 6)); +} + #[test] fn vector_const_fn() { // Ensure that vector! can be used in const contexts @@ -115,6 +129,15 @@ fn vector_const_fn() { const _: Vector6 = vector![1, 2, 3, 4, 5, 6]; } +#[test] +fn point_const_fn() { + // Ensure that vector! can be used in const contexts + const _: Point = vector![]; + const _: Point1 = vector![1]; + const _: Point2 = vector![1, 2]; + const _: Point6 = vector![1, 2, 3, 4, 5, 6]; +} + // Skip rustfmt because it just makes the test bloated without making it more readable #[rustfmt::skip] #[test] @@ -195,6 +218,23 @@ fn dmatrix_builtin_types() { let _: DMatrix = dmatrix![0.0, 1.0; 2.0, 3.0]; } +#[test] +fn point_builtin_types() { + // Check that point! compiles for all built-in types + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0, 1, 2, 3]; + const _: Point = point![0.0, 1.0, 2.0, 3.0]; + const _: Point = point![0.0, 1.0, 2.0, 3.0]; +} + #[test] fn dvector_builtin_types() { // Check that dvector! compiles for all built-in types @@ -248,6 +288,15 @@ fn vector_arbitrary_expressions() { assert_eq_and_type!(a, a_expected); } +#[rustfmt::skip] +#[test] +fn point_arbitrary_expressions() { + // Test that point! supports arbitrary expressions for its elements + let a = point![1 + 2, 2 * 3, 4 * f(5 + 6), 7 - 8 * 9]; + let a_expected = Point4::new(1 + 2, 2 * 3, 4 * f(5 + 6), 7 - 8 * 9); + assert_eq_and_type!(a, a_expected); +} + #[rustfmt::skip] #[test] fn dvector_arbitrary_expressions() { diff --git a/src/lib.rs b/src/lib.rs index ea05e17d..8378b272 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,7 +137,7 @@ pub use crate::sparse::*; pub use base as core; #[cfg(feature = "macros")] -pub use nalgebra_macros::{dmatrix, dvector, matrix, vector}; +pub use nalgebra_macros::{dmatrix, dvector, matrix, point, vector}; use simba::scalar::SupersetOf; use std::cmp::{self, Ordering, PartialOrd}; diff --git a/tests/core/macros.rs b/tests/core/macros.rs index eaa134ff..2987a41b 100644 --- a/tests/core/macros.rs +++ b/tests/core/macros.rs @@ -1,4 +1,4 @@ -use nalgebra::{dmatrix, dvector, matrix, vector}; +use nalgebra::{dmatrix, dvector, matrix, point, vector}; #[test] fn sanity_test() { @@ -6,6 +6,7 @@ fn sanity_test() { let _ = matrix![1, 2, 3; 4, 5, 6]; let _ = dmatrix![1, 2, 3; 4, 5, 6]; + let _ = point![1, 2, 3, 4, 5, 6]; let _ = vector![1, 2, 3, 4, 5, 6]; let _ = dvector![1, 2, 3, 4, 5, 6]; } From d6d2a3e96869c9bb6f90ff4844898bf1161d2721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crozet=20S=C3=A9bastien?= Date: Mon, 24 May 2021 18:00:30 +0200 Subject: [PATCH 2/3] Fix macros tests. --- nalgebra-macros/tests/tests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nalgebra-macros/tests/tests.rs b/nalgebra-macros/tests/tests.rs index e69f9e6b..68b09610 100644 --- a/nalgebra-macros/tests/tests.rs +++ b/nalgebra-macros/tests/tests.rs @@ -132,10 +132,10 @@ fn vector_const_fn() { #[test] fn point_const_fn() { // Ensure that vector! can be used in const contexts - const _: Point = vector![]; - const _: Point1 = vector![1]; - const _: Point2 = vector![1, 2]; - const _: Point6 = vector![1, 2, 3, 4, 5, 6]; + const _: Point = point![]; + const _: Point1 = point![1]; + const _: Point2 = point![1, 2]; + const _: Point6 = point![1, 2, 3, 4, 5, 6]; } // Skip rustfmt because it just makes the test bloated without making it more readable From 0490a844fbc5b1f99e949b699449838c8eb25d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crozet=20S=C3=A9bastien?= Date: Mon, 24 May 2021 18:10:26 +0200 Subject: [PATCH 3/3] Fix typo --- nalgebra-macros/tests/tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nalgebra-macros/tests/tests.rs b/nalgebra-macros/tests/tests.rs index 68b09610..0e52da1f 100644 --- a/nalgebra-macros/tests/tests.rs +++ b/nalgebra-macros/tests/tests.rs @@ -1,8 +1,8 @@ use nalgebra::{ DMatrix, DVector, Matrix1x2, Matrix1x3, Matrix1x4, Matrix2, Matrix2x1, Matrix2x3, Matrix2x4, - Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, PEoint4, - Point, Point1, Point2, Point3, Point4, Point5, Point6, SMatrix, SVector, Vector1, Vector2, - Vector3, Vector4, Vector5, Vector6, + Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, Point, + Point1, Point2, Point3, Point4, Point5, Point6, SMatrix, SVector, Vector1, Vector2, Vector3, + Vector4, Vector5, Vector6, }; use nalgebra_macros::{dmatrix, dvector, matrix, point, vector};