vectrix/
vector.rs

1//! Component access for vectors and constructors from components.
2
3use core::ops::{Deref, DerefMut};
4
5use crate::{Matrix, RowVector, Vector};
6
7////////////////////////////////////////////////////////////////////////////////
8// Accessors
9////////////////////////////////////////////////////////////////////////////////
10
11macro_rules! struct_coord {
12    ($Coord:ident: $($comp:ident),*) => {
13        #[allow(clippy::upper_case_acronyms)]
14        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15        #[repr(C)]
16        pub struct $Coord<T> {
17            $(pub $comp: T),*
18        }
19    };
20}
21
22macro_rules! impl_deref {
23    (($M:literal, $N:literal) -> $Target:ident) => {
24        impl<T> Deref for Matrix<T, $M, $N> {
25            type Target = $Target<T>;
26
27            #[inline]
28            fn deref(&self) -> &Self::Target {
29                let ptr = self.as_ptr() as *const $Target<T>;
30                unsafe { &*ptr }
31            }
32        }
33
34        impl<T> DerefMut for Matrix<T, $M, $N> {
35            #[inline]
36            fn deref_mut(&mut self) -> &mut Self::Target {
37                let ptr = self.as_mut_ptr() as *mut $Target<T>;
38                unsafe { &mut *ptr }
39            }
40        }
41    };
42}
43
44struct_coord! { X: x }
45struct_coord! { XY: x, y }
46struct_coord! { XYZ: x, y, z }
47struct_coord! { XYZW: x, y, z, w }
48struct_coord! { XYZWA: x, y, z, w, a }
49struct_coord! { XYZWAB: x, y, z, w, a, b }
50
51// SAFETY: given ($M, $N) -> $Target
52//         - $Target should be marked #[repr(C)].
53//         - $Target<T> should be the same size as [T; $N].
54impl_deref! { (1, 1) -> X }
55// row vectors
56impl_deref! { (1, 2) -> XY }
57impl_deref! { (1, 3) -> XYZ }
58impl_deref! { (1, 4) -> XYZW }
59impl_deref! { (1, 5) -> XYZWA }
60impl_deref! { (1, 6) -> XYZWAB }
61// column vectors
62impl_deref! { (2, 1) -> XY }
63impl_deref! { (3, 1) -> XYZ }
64impl_deref! { (4, 1) -> XYZW }
65impl_deref! { (5, 1) -> XYZWA }
66impl_deref! { (6, 1) -> XYZWAB }
67
68////////////////////////////////////////////////////////////////////////////////
69// Macros
70////////////////////////////////////////////////////////////////////////////////
71
72/// A macro for composing row vectors.
73#[macro_export]
74macro_rules! row_vector {
75    ($repeat:expr; $n:expr) => {
76        $crate::RowVector::from_column_major_order([[$repeat]; $n])
77    };
78    ($($value:expr),* $(,)?) => {
79        $crate::RowVector::from_column_major_order([$([$value]),*])
80    };
81}
82
83/// A macro for composing vectors.
84#[macro_export]
85macro_rules! vector {
86    ($repeat:expr; $n:expr) => {
87        $crate::Vector::from_column_major_order([[$repeat; $n]])
88    };
89    ($($value:expr),* $(,)?) => {
90        $crate::Vector::from_column_major_order([[$($value),*]])
91    };
92}
93
94////////////////////////////////////////////////////////////////////////////////
95// Component constructors
96////////////////////////////////////////////////////////////////////////////////
97
98impl<T> RowVector<T, 1> {
99    /// Creates a new vector from the given components.
100    pub const fn new(x: T) -> Self {
101        Self { data: [[x]] }
102    }
103}
104
105impl<T> RowVector<T, 2> {
106    /// Creates a new vector from the given components.
107    pub const fn new(x: T, y: T) -> Self {
108        Self { data: [[x], [y]] }
109    }
110}
111
112impl<T> RowVector<T, 3> {
113    /// Creates a new vector from the given components.
114    pub const fn new(x: T, y: T, z: T) -> Self {
115        Self {
116            data: [[x], [y], [z]],
117        }
118    }
119}
120
121impl<T> RowVector<T, 4> {
122    /// Creates a new vector from the given components.
123    pub const fn new(x: T, y: T, z: T, w: T) -> Self {
124        Self {
125            data: [[x], [y], [z], [w]],
126        }
127    }
128}
129
130impl<T> RowVector<T, 5> {
131    /// Creates a new vector from the given components.
132    pub const fn new(x: T, y: T, z: T, w: T, a: T) -> Self {
133        Self {
134            data: [[x], [y], [z], [w], [a]],
135        }
136    }
137}
138
139impl<T> RowVector<T, 6> {
140    /// Creates a new vector from the given components.
141    pub const fn new(x: T, y: T, z: T, w: T, a: T, b: T) -> Self {
142        Self {
143            data: [[x], [y], [z], [w], [a], [b]],
144        }
145    }
146}
147
148impl<T> Vector<T, 2> {
149    /// Creates a new vector from the given components.
150    pub const fn new(x: T, y: T) -> Self {
151        Self { data: [[x, y]] }
152    }
153}
154
155impl<T> Vector<T, 3> {
156    /// Creates a new vector from the given components.
157    pub const fn new(x: T, y: T, z: T) -> Self {
158        Self { data: [[x, y, z]] }
159    }
160}
161
162impl<T> Vector<T, 4> {
163    /// Creates a new vector from the given components.
164    pub const fn new(x: T, y: T, z: T, w: T) -> Self {
165        Self {
166            data: [[x, y, z, w]],
167        }
168    }
169}
170
171impl<T> Vector<T, 5> {
172    /// Creates a new vector from the given components.
173    pub const fn new(x: T, y: T, z: T, w: T, a: T) -> Self {
174        Self {
175            data: [[x, y, z, w, a]],
176        }
177    }
178}
179impl<T> Vector<T, 6> {
180    /// Creates a new vector from the given components.
181    pub const fn new(x: T, y: T, z: T, w: T, a: T, b: T) -> Self {
182        Self {
183            data: [[x, y, z, w, a, b]],
184        }
185    }
186}
187
188////////////////////////////////////////////////////////////////////////////////
189// From array
190////////////////////////////////////////////////////////////////////////////////
191
192impl<T> From<[T; 1]> for Matrix<T, 1, 1> {
193    fn from(arr: [T; 1]) -> Self {
194        Self { data: [arr] }
195    }
196}
197
198impl<T> From<[T; 2]> for RowVector<T, 2> {
199    fn from([x, y]: [T; 2]) -> Self {
200        Self { data: [[x], [y]] }
201    }
202}
203
204impl<T> From<[T; 3]> for RowVector<T, 3> {
205    fn from([x, y, z]: [T; 3]) -> Self {
206        Self {
207            data: [[x], [y], [z]],
208        }
209    }
210}
211
212impl<T> From<[T; 4]> for RowVector<T, 4> {
213    fn from([x, y, z, w]: [T; 4]) -> Self {
214        Self {
215            data: [[x], [y], [z], [w]],
216        }
217    }
218}
219
220impl<T> From<[T; 5]> for RowVector<T, 5> {
221    fn from([x, y, z, w, a]: [T; 5]) -> Self {
222        Self {
223            data: [[x], [y], [z], [w], [a]],
224        }
225    }
226}
227
228impl<T> From<[T; 6]> for RowVector<T, 6> {
229    fn from([x, y, z, w, a, b]: [T; 6]) -> Self {
230        Self {
231            data: [[x], [y], [z], [w], [a], [b]],
232        }
233    }
234}
235
236impl<T> From<[T; 2]> for Vector<T, 2> {
237    fn from(arr: [T; 2]) -> Self {
238        Self { data: [arr] }
239    }
240}
241
242impl<T> From<[T; 3]> for Vector<T, 3> {
243    fn from(arr: [T; 3]) -> Self {
244        Self { data: [arr] }
245    }
246}
247
248impl<T> From<[T; 4]> for Vector<T, 4> {
249    fn from(arr: [T; 4]) -> Self {
250        Self { data: [arr] }
251    }
252}
253
254impl<T> From<[T; 5]> for Vector<T, 5> {
255    fn from(arr: [T; 5]) -> Self {
256        Self { data: [arr] }
257    }
258}
259
260impl<T> From<[T; 6]> for Vector<T, 6> {
261    fn from(arr: [T; 6]) -> Self {
262        Self { data: [arr] }
263    }
264}
265
266////////////////////////////////////////////////////////////////////////////////
267// From tuple
268////////////////////////////////////////////////////////////////////////////////
269
270impl<T> From<(T,)> for Matrix<T, 1, 1> {
271    fn from((x,): (T,)) -> Self {
272        Self { data: [[x]] }
273    }
274}
275
276impl<T> From<(T, T)> for RowVector<T, 2> {
277    fn from((x, y): (T, T)) -> Self {
278        Self { data: [[x], [y]] }
279    }
280}
281
282impl<T> From<(T, T, T)> for RowVector<T, 3> {
283    fn from((x, y, z): (T, T, T)) -> Self {
284        Self {
285            data: [[x], [y], [z]],
286        }
287    }
288}
289
290impl<T> From<(T, T, T, T)> for RowVector<T, 4> {
291    fn from((x, y, z, w): (T, T, T, T)) -> Self {
292        Self {
293            data: [[x], [y], [z], [w]],
294        }
295    }
296}
297
298impl<T> From<(T, T, T, T, T)> for RowVector<T, 5> {
299    fn from((x, y, z, w, a): (T, T, T, T, T)) -> Self {
300        Self {
301            data: [[x], [y], [z], [w], [a]],
302        }
303    }
304}
305
306impl<T> From<(T, T, T, T, T, T)> for RowVector<T, 6> {
307    fn from((x, y, z, w, a, b): (T, T, T, T, T, T)) -> Self {
308        Self {
309            data: [[x], [y], [z], [w], [a], [b]],
310        }
311    }
312}
313
314impl<T> From<(T, T)> for Vector<T, 2> {
315    fn from((x, y): (T, T)) -> Self {
316        Self { data: [[x, y]] }
317    }
318}
319
320impl<T> From<(T, T, T)> for Vector<T, 3> {
321    fn from((x, y, z): (T, T, T)) -> Self {
322        Self { data: [[x, y, z]] }
323    }
324}
325
326impl<T> From<(T, T, T, T)> for Vector<T, 4> {
327    fn from((x, y, z, w): (T, T, T, T)) -> Self {
328        Self {
329            data: [[x, y, z, w]],
330        }
331    }
332}
333
334impl<T> From<(T, T, T, T, T)> for Vector<T, 5> {
335    fn from((x, y, z, w, a): (T, T, T, T, T)) -> Self {
336        Self {
337            data: [[x, y, z, w, a]],
338        }
339    }
340}
341
342impl<T> From<(T, T, T, T, T, T)> for Vector<T, 6> {
343    fn from((x, y, z, w, a, b): (T, T, T, T, T, T)) -> Self {
344        Self {
345            data: [[x, y, z, w, a, b]],
346        }
347    }
348}
349
350////////////////////////////////////////////////////////////////////////////////
351// Swizzling
352////////////////////////////////////////////////////////////////////////////////
353
354impl<T: Copy> Vector<T, 1> {
355    #[inline]
356    pub const fn xx(&self) -> Vector<T, 2> {
357        let Vector { data: [[x]] } = *self;
358        Vector { data: [[x, x]] }
359    }
360
361    #[inline]
362    pub const fn xxx(&self) -> Vector<T, 3> {
363        let Vector { data: [[x]] } = *self;
364        Vector { data: [[x, x, x]] }
365    }
366}
367
368macro_rules! impl_swizzle {
369    ($(impl Vector<$N:literal> { $( $name:ident() -> Vector<$M:literal>[$($d:literal),+]; )* } )*) => {
370        $(
371            impl<T: Copy> Vector<T, $N> {
372                $(
373                    #[inline]
374                    pub const fn $name(&self) -> Vector<T, $M> {
375                        Vector {
376                            data: [[$( unsafe { *self.as_ptr().add($d) } ),*]],
377                        }
378                    }
379                )*
380            }
381
382            impl<T: Copy> RowVector<T, $N> {
383                $(
384                    #[inline]
385                    pub const fn $name(&self) -> RowVector<T, $M> {
386                        RowVector {
387                            data: [$( [unsafe { *self.as_ptr().add($d) }] ),*],
388                        }
389                    }
390                )*
391            }
392        )*
393    };
394}
395
396impl_swizzle! {
397    impl Vector<2> {
398         xx() -> Vector<2>[0, 0];
399         xy() -> Vector<2>[0, 1];
400         yx() -> Vector<2>[1, 0];
401         yy() -> Vector<2>[1, 1];
402        xxx() -> Vector<3>[0, 0, 0];
403        xxy() -> Vector<3>[0, 0, 1];
404        xyx() -> Vector<3>[0, 1, 0];
405        xyy() -> Vector<3>[0, 1, 1];
406        yxx() -> Vector<3>[1, 0, 0];
407        yxy() -> Vector<3>[1, 0, 1];
408        yyx() -> Vector<3>[1, 1, 0];
409        yyy() -> Vector<3>[1, 1, 1];
410    }
411
412    impl Vector<3> {
413         xx() -> Vector<2>[0, 0];
414         xy() -> Vector<2>[0, 1];
415         xz() -> Vector<2>[0, 2];
416         yx() -> Vector<2>[1, 0];
417         yy() -> Vector<2>[1, 1];
418         yz() -> Vector<2>[1, 2];
419         zx() -> Vector<2>[2, 0];
420         zy() -> Vector<2>[2, 1];
421         zz() -> Vector<2>[2, 2];
422        xxx() -> Vector<3>[0, 0, 0];
423        xxy() -> Vector<3>[0, 0, 1];
424        xxz() -> Vector<3>[0, 0, 2];
425        xyx() -> Vector<3>[0, 1, 0];
426        xyy() -> Vector<3>[0, 1, 1];
427        xyz() -> Vector<3>[0, 1, 2];
428        xzx() -> Vector<3>[0, 2, 0];
429        xzy() -> Vector<3>[0, 2, 1];
430        xzz() -> Vector<3>[0, 2, 2];
431        yxx() -> Vector<3>[1, 0, 0];
432        yxy() -> Vector<3>[1, 0, 1];
433        yxz() -> Vector<3>[1, 0, 2];
434        yyx() -> Vector<3>[1, 1, 0];
435        yyy() -> Vector<3>[1, 1, 1];
436        yyz() -> Vector<3>[1, 1, 2];
437        yzx() -> Vector<3>[1, 2, 0];
438        yzy() -> Vector<3>[1, 2, 1];
439        yzz() -> Vector<3>[1, 2, 2];
440        zxx() -> Vector<3>[2, 0, 0];
441        zxy() -> Vector<3>[2, 0, 1];
442        zxz() -> Vector<3>[2, 0, 2];
443        zyx() -> Vector<3>[2, 1, 0];
444        zyy() -> Vector<3>[2, 1, 1];
445        zyz() -> Vector<3>[2, 1, 2];
446        zzx() -> Vector<3>[2, 2, 0];
447        zzy() -> Vector<3>[2, 2, 1];
448        zzz() -> Vector<3>[2, 2, 2];
449    }
450}