Skip to content

Commit ef3257b

Browse files
authored
Merge pull request #899 from dimforge/point_macro
Add a point! macro for constructing points
2 parents f9a128a + 0490a84 commit ef3257b

File tree

4 files changed

+86
-5
lines changed

4 files changed

+86
-5
lines changed

nalgebra-macros/src/lib.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,34 @@ pub fn dvector(stream: TokenStream) -> TokenStream {
280280
};
281281
proc_macro::TokenStream::from(output)
282282
}
283+
284+
/// Construct a fixed-size point directly from data.
285+
///
286+
/// **Note: Requires the `macro` feature to be enabled (enabled by default)**.
287+
///
288+
/// Similarly to [`vector!`], this macro facilitates easy construction of points.
289+
///
290+
/// `point!` is intended to be the most readable and performant way of constructing small,
291+
/// points, and it is usable in `const fn` contexts.
292+
///
293+
/// ## Examples
294+
///
295+
/// ```
296+
/// use nalgebra::point;
297+
///
298+
/// // Produces a Point3<_>
299+
/// let v = point![1, 2, 3];
300+
/// ```
301+
#[proc_macro]
302+
pub fn point(stream: TokenStream) -> TokenStream {
303+
let vector = parse_macro_input!(stream as Vector);
304+
let len = vector.len();
305+
let array_tokens = vector.to_array_tokens();
306+
let output = quote! {
307+
nalgebra::Point::<_, #len> {
308+
coords: nalgebra::SVector::<_, #len>
309+
::from_array_storage(nalgebra::ArrayStorage([#array_tokens]))
310+
}
311+
};
312+
proc_macro::TokenStream::from(output)
313+
}

nalgebra-macros/tests/tests.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use nalgebra::{
22
DMatrix, DVector, Matrix1x2, Matrix1x3, Matrix1x4, Matrix2, Matrix2x1, Matrix2x3, Matrix2x4,
3-
Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, SMatrix,
4-
SVector, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6,
3+
Matrix3, Matrix3x1, Matrix3x2, Matrix3x4, Matrix4, Matrix4x1, Matrix4x2, Matrix4x3, Point,
4+
Point1, Point2, Point3, Point4, Point5, Point6, SMatrix, SVector, Vector1, Vector2, Vector3,
5+
Vector4, Vector5, Vector6,
56
};
6-
use nalgebra_macros::{dmatrix, dvector, matrix, vector};
7+
use nalgebra_macros::{dmatrix, dvector, matrix, point, vector};
78

89
fn check_statically_same_type<T>(_: &T, _: &T) {}
910

@@ -106,6 +107,19 @@ fn vector_small_dims_exhaustive() {
106107
assert_eq_and_type!(vector![1, 2, 3, 4, 5, 6], Vector6::new(1, 2, 3, 4, 5, 6));
107108
}
108109

110+
// Skip rustfmt because it just makes the test bloated without making it more readable
111+
#[rustfmt::skip]
112+
#[test]
113+
fn point_small_dims_exhaustive() {
114+
assert_eq_and_type!(point![], Point::<i32, 0>::origin());
115+
assert_eq_and_type!(point![1], Point1::<i32>::new(1));
116+
assert_eq_and_type!(point![1, 2], Point2::new(1, 2));
117+
assert_eq_and_type!(point![1, 2, 3], Point3::new(1, 2, 3));
118+
assert_eq_and_type!(point![1, 2, 3, 4], Point4::new(1, 2, 3, 4));
119+
assert_eq_and_type!(point![1, 2, 3, 4, 5], Point5::new(1, 2, 3, 4, 5));
120+
assert_eq_and_type!(point![1, 2, 3, 4, 5, 6], Point6::new(1, 2, 3, 4, 5, 6));
121+
}
122+
109123
#[test]
110124
fn vector_const_fn() {
111125
// Ensure that vector! can be used in const contexts
@@ -115,6 +129,15 @@ fn vector_const_fn() {
115129
const _: Vector6<i32> = vector![1, 2, 3, 4, 5, 6];
116130
}
117131

132+
#[test]
133+
fn point_const_fn() {
134+
// Ensure that vector! can be used in const contexts
135+
const _: Point<i32, 0> = point![];
136+
const _: Point1<i32> = point![1];
137+
const _: Point2<i32> = point![1, 2];
138+
const _: Point6<i32> = point![1, 2, 3, 4, 5, 6];
139+
}
140+
118141
// Skip rustfmt because it just makes the test bloated without making it more readable
119142
#[rustfmt::skip]
120143
#[test]
@@ -195,6 +218,23 @@ fn dmatrix_builtin_types() {
195218
let _: DMatrix<f64> = dmatrix![0.0, 1.0; 2.0, 3.0];
196219
}
197220

221+
#[test]
222+
fn point_builtin_types() {
223+
// Check that point! compiles for all built-in types
224+
const _: Point<i8, 4> = point![0, 1, 2, 3];
225+
const _: Point<i16, 4> = point![0, 1, 2, 3];
226+
const _: Point<i32, 4> = point![0, 1, 2, 3];
227+
const _: Point<i64, 4> = point![0, 1, 2, 3];
228+
const _: Point<isize, 4> = point![0, 1, 2, 3];
229+
const _: Point<u8, 4> = point![0, 1, 2, 3];
230+
const _: Point<u16, 4> = point![0, 1, 2, 3];
231+
const _: Point<u32, 4> = point![0, 1, 2, 3];
232+
const _: Point<u64, 4> = point![0, 1, 2, 3];
233+
const _: Point<usize, 4> = point![0, 1, 2, 3];
234+
const _: Point<f32, 4> = point![0.0, 1.0, 2.0, 3.0];
235+
const _: Point<f64, 4> = point![0.0, 1.0, 2.0, 3.0];
236+
}
237+
198238
#[test]
199239
fn dvector_builtin_types() {
200240
// Check that dvector! compiles for all built-in types
@@ -248,6 +288,15 @@ fn vector_arbitrary_expressions() {
248288
assert_eq_and_type!(a, a_expected);
249289
}
250290

291+
#[rustfmt::skip]
292+
#[test]
293+
fn point_arbitrary_expressions() {
294+
// Test that point! supports arbitrary expressions for its elements
295+
let a = point![1 + 2, 2 * 3, 4 * f(5 + 6), 7 - 8 * 9];
296+
let a_expected = Point4::new(1 + 2, 2 * 3, 4 * f(5 + 6), 7 - 8 * 9);
297+
assert_eq_and_type!(a, a_expected);
298+
}
299+
251300
#[rustfmt::skip]
252301
#[test]
253302
fn dvector_arbitrary_expressions() {

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub use crate::sparse::*;
137137
pub use base as core;
138138

139139
#[cfg(feature = "macros")]
140-
pub use nalgebra_macros::{dmatrix, dvector, matrix, vector};
140+
pub use nalgebra_macros::{dmatrix, dvector, matrix, point, vector};
141141

142142
use simba::scalar::SupersetOf;
143143
use std::cmp::{self, Ordering, PartialOrd};

tests/core/macros.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use nalgebra::{dmatrix, dvector, matrix, vector};
1+
use nalgebra::{dmatrix, dvector, matrix, point, vector};
22

33
#[test]
44
fn sanity_test() {
55
// The macros are already tested in `nalgebra-macros`. Here we just test that they compile fine.
66

77
let _ = matrix![1, 2, 3; 4, 5, 6];
88
let _ = dmatrix![1, 2, 3; 4, 5, 6];
9+
let _ = point![1, 2, 3, 4, 5, 6];
910
let _ = vector![1, 2, 3, 4, 5, 6];
1011
let _ = dvector![1, 2, 3, 4, 5, 6];
1112
}

0 commit comments

Comments
 (0)