glam/f32/neon/
mat2.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3use crate::{f32::math, swizzles::*, DMat2, Mat3, Mat3A, Vec2};
4use core::fmt;
5use core::iter::{Product, Sum};
6use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8use core::arch::aarch64::*;
9
10#[cfg(feature = "zerocopy")]
11use zerocopy_derive::*;
12
13#[repr(C)]
14union UnionCast {
15    a: [f32; 4],
16    v: Mat2,
17}
18
19/// Creates a 2x2 matrix from two column vectors.
20#[inline(always)]
21#[must_use]
22pub const fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
23    Mat2::from_cols(x_axis, y_axis)
24}
25
26/// A 2x2 column major matrix.
27///
28/// SIMD vector types are used for storage on supported platforms.
29///
30/// This type is 16 byte aligned.
31#[derive(Clone, Copy)]
32#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
33#[cfg_attr(
34    feature = "zerocopy",
35    derive(FromBytes, Immutable, IntoBytes, KnownLayout)
36)]
37#[repr(transparent)]
38pub struct Mat2(pub(crate) float32x4_t);
39
40impl Mat2 {
41    /// A 2x2 matrix with all elements set to `0.0`.
42    pub const ZERO: Self = Self::from_cols(Vec2::ZERO, Vec2::ZERO);
43
44    /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
45    pub const IDENTITY: Self = Self::from_cols(Vec2::X, Vec2::Y);
46
47    /// All NAN:s.
48    pub const NAN: Self = Self::from_cols(Vec2::NAN, Vec2::NAN);
49
50    #[allow(clippy::too_many_arguments)]
51    #[inline(always)]
52    #[must_use]
53    const fn new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self {
54        unsafe {
55            UnionCast {
56                a: [m00, m01, m10, m11],
57            }
58            .v
59        }
60    }
61
62    /// Creates a 2x2 matrix from two column vectors.
63    #[inline(always)]
64    #[must_use]
65    pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
66        unsafe {
67            UnionCast {
68                a: [x_axis.x, x_axis.y, y_axis.x, y_axis.y],
69            }
70            .v
71        }
72    }
73
74    /// Creates a 2x2 matrix from a `[f32; 4]` array stored in column major order.
75    /// If your data is stored in row major you will need to `transpose` the returned
76    /// matrix.
77    #[inline]
78    #[must_use]
79    pub const fn from_cols_array(m: &[f32; 4]) -> Self {
80        Self::new(m[0], m[1], m[2], m[3])
81    }
82
83    /// Creates a `[f32; 4]` array storing data in column major order.
84    /// If you require data in row major order `transpose` the matrix first.
85    #[inline]
86    #[must_use]
87    pub const fn to_cols_array(&self) -> [f32; 4] {
88        unsafe { *(self as *const Self as *const [f32; 4]) }
89    }
90
91    /// Creates a 2x2 matrix from a `[[f32; 2]; 2]` 2D array stored in column major order.
92    /// If your data is in row major order you will need to `transpose` the returned
93    /// matrix.
94    #[inline]
95    #[must_use]
96    pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
97        Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
98    }
99
100    /// Creates a `[[f32; 2]; 2]` 2D array storing data in column major order.
101    /// If you require data in row major order `transpose` the matrix first.
102    #[inline]
103    #[must_use]
104    pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
105        unsafe { *(self as *const Self as *const [[f32; 2]; 2]) }
106    }
107
108    /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
109    #[doc(alias = "scale")]
110    #[inline]
111    #[must_use]
112    pub const fn from_diagonal(diagonal: Vec2) -> Self {
113        Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
114    }
115
116    /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
117    /// `angle` (in radians).
118    #[inline]
119    #[must_use]
120    pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
121        let (sin, cos) = math::sin_cos(angle);
122        Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
123    }
124
125    /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
126    #[inline]
127    #[must_use]
128    pub fn from_angle(angle: f32) -> Self {
129        let (sin, cos) = math::sin_cos(angle);
130        Self::new(cos, sin, -sin, cos)
131    }
132
133    /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
134    #[inline]
135    #[must_use]
136    pub fn from_mat3(m: Mat3) -> Self {
137        Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
138    }
139
140    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
141    /// and `j`th row.
142    ///
143    /// # Panics
144    ///
145    /// Panics if `i` or `j` is greater than 2.
146    #[inline]
147    #[must_use]
148    pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
149        match (i, j) {
150            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
151            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
152            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
153            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
154            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
155            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
156            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
157            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
158            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
159            _ => panic!("index out of bounds"),
160        }
161    }
162
163    /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
164    #[inline]
165    #[must_use]
166    pub fn from_mat3a(m: Mat3A) -> Self {
167        Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
168    }
169
170    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
171    /// and `j`th row.
172    ///
173    /// # Panics
174    ///
175    /// Panics if `i` or `j` is greater than 2.
176    #[inline]
177    #[must_use]
178    pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
179        match (i, j) {
180            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
181            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
182            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
183            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
184            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
185            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
186            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
187            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
188            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
189            _ => panic!("index out of bounds"),
190        }
191    }
192
193    /// Creates a 2x2 matrix from the first 4 values in `slice`.
194    ///
195    /// # Panics
196    ///
197    /// Panics if `slice` is less than 4 elements long.
198    #[inline]
199    #[must_use]
200    pub const fn from_cols_slice(slice: &[f32]) -> Self {
201        Self::new(slice[0], slice[1], slice[2], slice[3])
202    }
203
204    /// Writes the columns of `self` to the first 4 elements in `slice`.
205    ///
206    /// # Panics
207    ///
208    /// Panics if `slice` is less than 4 elements long.
209    #[inline]
210    pub fn write_cols_to_slice(self, slice: &mut [f32]) {
211        slice[0] = self.x_axis.x;
212        slice[1] = self.x_axis.y;
213        slice[2] = self.y_axis.x;
214        slice[3] = self.y_axis.y;
215    }
216
217    /// Returns the matrix column for the given `index`.
218    ///
219    /// # Panics
220    ///
221    /// Panics if `index` is greater than 1.
222    #[inline]
223    #[must_use]
224    pub fn col(&self, index: usize) -> Vec2 {
225        match index {
226            0 => self.x_axis,
227            1 => self.y_axis,
228            _ => panic!("index out of bounds"),
229        }
230    }
231
232    /// Returns a mutable reference to the matrix column for the given `index`.
233    ///
234    /// # Panics
235    ///
236    /// Panics if `index` is greater than 1.
237    #[inline]
238    pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
239        match index {
240            0 => &mut self.x_axis,
241            1 => &mut self.y_axis,
242            _ => panic!("index out of bounds"),
243        }
244    }
245
246    /// Returns the matrix row for the given `index`.
247    ///
248    /// # Panics
249    ///
250    /// Panics if `index` is greater than 1.
251    #[inline]
252    #[must_use]
253    pub fn row(&self, index: usize) -> Vec2 {
254        match index {
255            0 => Vec2::new(self.x_axis.x, self.y_axis.x),
256            1 => Vec2::new(self.x_axis.y, self.y_axis.y),
257            _ => panic!("index out of bounds"),
258        }
259    }
260
261    /// Returns `true` if, and only if, all elements are finite.
262    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
263    #[inline]
264    #[must_use]
265    pub fn is_finite(&self) -> bool {
266        self.x_axis.is_finite() && self.y_axis.is_finite()
267    }
268
269    /// Returns `true` if any elements are `NaN`.
270    #[inline]
271    #[must_use]
272    pub fn is_nan(&self) -> bool {
273        self.x_axis.is_nan() || self.y_axis.is_nan()
274    }
275
276    /// Returns the transpose of `self`.
277    #[inline]
278    #[must_use]
279    pub fn transpose(&self) -> Self {
280        Self(unsafe {
281            vsetq_lane_f32(
282                vgetq_lane_f32(self.0, 2),
283                vsetq_lane_f32(vgetq_lane_f32(self.0, 1), self.0, 2),
284                1,
285            )
286        })
287    }
288
289    /// Returns the determinant of `self`.
290    #[inline]
291    #[must_use]
292    pub fn determinant(&self) -> f32 {
293        unsafe {
294            let abcd = self.0;
295            let badc = vrev64q_f32(abcd);
296            let dcba = vextq_f32(badc, badc, 2);
297            let prod = vmulq_f32(abcd, dcba);
298            let det = vsubq_f32(prod, vdupq_laneq_f32(prod, 1));
299            vgetq_lane_f32(det, 0)
300        }
301    }
302
303    /// Returns the inverse of `self`.
304    ///
305    /// If the matrix is not invertible the returned matrix will be invalid.
306    ///
307    /// # Panics
308    ///
309    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
310    #[inline]
311    #[must_use]
312    pub fn inverse(&self) -> Self {
313        unsafe {
314            const SIGN: float32x4_t = crate::neon::f32x4_from_array([1.0, -1.0, -1.0, 1.0]);
315            let abcd = self.0;
316            let badc = vrev64q_f32(abcd);
317            let dcba = vextq_f32(badc, badc, 2);
318            let prod = vmulq_f32(abcd, dcba);
319            let sub = vsubq_f32(prod, vdupq_laneq_f32(prod, 1));
320            let det = vdupq_laneq_f32(sub, 0);
321            let tmp = vdivq_f32(SIGN, det);
322            glam_assert!(Mat2(tmp).is_finite());
323            //let dbca = simd_swizzle!(abcd, [3, 1, 2, 0]);
324            let dbca = vsetq_lane_f32(
325                vgetq_lane_f32(abcd, 0),
326                vsetq_lane_f32(vgetq_lane_f32(abcd, 3), abcd, 0),
327                3,
328            );
329            Self(vmulq_f32(dbca, tmp))
330        }
331    }
332
333    /// Transforms a 2D vector.
334    #[inline]
335    #[must_use]
336    pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
337        unsafe {
338            let abcd = self.0;
339            let xxyy = vld1q_f32([rhs.x, rhs.x, rhs.y, rhs.y].as_ptr());
340            let axbxcydy = vmulq_f32(abcd, xxyy);
341            // let cydyaxbx = simd_swizzle!(axbxcydy, [2, 3, 0, 1]);
342            let cydyaxbx = vextq_f32(axbxcydy, axbxcydy, 2);
343            let result = vaddq_f32(axbxcydy, cydyaxbx);
344            *(&result as *const float32x4_t as *const Vec2)
345        }
346    }
347
348    /// Multiplies two 2x2 matrices.
349    #[inline]
350    #[must_use]
351    pub fn mul_mat2(&self, rhs: &Self) -> Self {
352        self.mul(rhs)
353    }
354
355    /// Adds two 2x2 matrices.
356    #[inline]
357    #[must_use]
358    pub fn add_mat2(&self, rhs: &Self) -> Self {
359        self.add(rhs)
360    }
361
362    /// Subtracts two 2x2 matrices.
363    #[inline]
364    #[must_use]
365    pub fn sub_mat2(&self, rhs: &Self) -> Self {
366        self.sub(rhs)
367    }
368
369    /// Multiplies a 2x2 matrix by a scalar.
370    #[inline]
371    #[must_use]
372    pub fn mul_scalar(&self, rhs: f32) -> Self {
373        Self(unsafe { vmulq_f32(self.0, vld1q_dup_f32(&rhs)) })
374    }
375
376    /// Divides a 2x2 matrix by a scalar.
377    #[inline]
378    #[must_use]
379    pub fn div_scalar(&self, rhs: f32) -> Self {
380        Self(unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) })
381    }
382
383    /// Returns true if the absolute difference of all elements between `self` and `rhs`
384    /// is less than or equal to `max_abs_diff`.
385    ///
386    /// This can be used to compare if two matrices contain similar elements. It works best
387    /// when comparing with a known value. The `max_abs_diff` that should be used used
388    /// depends on the values being compared against.
389    ///
390    /// For more see
391    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
392    #[inline]
393    #[must_use]
394    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
395        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
396            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
397    }
398
399    /// Takes the absolute value of each element in `self`
400    #[inline]
401    #[must_use]
402    pub fn abs(&self) -> Self {
403        Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
404    }
405
406    #[inline]
407    pub fn as_dmat2(&self) -> DMat2 {
408        DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
409    }
410}
411
412impl Default for Mat2 {
413    #[inline]
414    fn default() -> Self {
415        Self::IDENTITY
416    }
417}
418
419impl Add for Mat2 {
420    type Output = Self;
421    #[inline]
422    fn add(self, rhs: Self) -> Self {
423        Self(unsafe { vaddq_f32(self.0, rhs.0) })
424    }
425}
426
427impl Add<&Self> for Mat2 {
428    type Output = Self;
429    #[inline]
430    fn add(self, rhs: &Self) -> Self {
431        self.add(*rhs)
432    }
433}
434
435impl Add<&Mat2> for &Mat2 {
436    type Output = Mat2;
437    #[inline]
438    fn add(self, rhs: &Mat2) -> Mat2 {
439        (*self).add(*rhs)
440    }
441}
442
443impl Add<Mat2> for &Mat2 {
444    type Output = Mat2;
445    #[inline]
446    fn add(self, rhs: Mat2) -> Mat2 {
447        (*self).add(rhs)
448    }
449}
450
451impl AddAssign for Mat2 {
452    #[inline]
453    fn add_assign(&mut self, rhs: Self) {
454        *self = self.add(rhs);
455    }
456}
457
458impl AddAssign<&Self> for Mat2 {
459    #[inline]
460    fn add_assign(&mut self, rhs: &Self) {
461        self.add_assign(*rhs);
462    }
463}
464
465impl Sub for Mat2 {
466    type Output = Self;
467    #[inline]
468    fn sub(self, rhs: Self) -> Self {
469        Self(unsafe { vsubq_f32(self.0, rhs.0) })
470    }
471}
472
473impl Sub<&Self> for Mat2 {
474    type Output = Self;
475    #[inline]
476    fn sub(self, rhs: &Self) -> Self {
477        self.sub(*rhs)
478    }
479}
480
481impl Sub<&Mat2> for &Mat2 {
482    type Output = Mat2;
483    #[inline]
484    fn sub(self, rhs: &Mat2) -> Mat2 {
485        (*self).sub(*rhs)
486    }
487}
488
489impl Sub<Mat2> for &Mat2 {
490    type Output = Mat2;
491    #[inline]
492    fn sub(self, rhs: Mat2) -> Mat2 {
493        (*self).sub(rhs)
494    }
495}
496
497impl SubAssign for Mat2 {
498    #[inline]
499    fn sub_assign(&mut self, rhs: Self) {
500        *self = self.sub(rhs);
501    }
502}
503
504impl SubAssign<&Self> for Mat2 {
505    #[inline]
506    fn sub_assign(&mut self, rhs: &Self) {
507        self.sub_assign(*rhs);
508    }
509}
510
511impl Neg for Mat2 {
512    type Output = Self;
513    #[inline]
514    fn neg(self) -> Self::Output {
515        Self(unsafe { vnegq_f32(self.0) })
516    }
517}
518
519impl Neg for &Mat2 {
520    type Output = Mat2;
521    #[inline]
522    fn neg(self) -> Mat2 {
523        (*self).neg()
524    }
525}
526
527impl Mul for Mat2 {
528    type Output = Self;
529    #[inline]
530    fn mul(self, rhs: Self) -> Self {
531        unsafe {
532            let abcd = self.0;
533            let xxyy0 = vzip1q_f32(rhs.0, rhs.0);
534            let xxyy1 = vzip2q_f32(rhs.0, rhs.0);
535            let axbxcydy0 = vmulq_f32(abcd, xxyy0);
536            let axbxcydy1 = vmulq_f32(abcd, xxyy1);
537            let cydyaxbx0 = vextq_f32(axbxcydy0, axbxcydy0, 2);
538            let cydyaxbx1 = vextq_f32(axbxcydy1, axbxcydy1, 2);
539            let result0 = vaddq_f32(axbxcydy0, cydyaxbx0);
540            let result1 = vaddq_f32(axbxcydy1, cydyaxbx1);
541            Self(vreinterpretq_f32_u64(vsetq_lane_u64(
542                vgetq_lane_u64(vreinterpretq_u64_f32(result1), 0),
543                vreinterpretq_u64_f32(result0),
544                1,
545            )))
546        }
547    }
548}
549
550impl Mul<&Self> for Mat2 {
551    type Output = Self;
552    #[inline]
553    fn mul(self, rhs: &Self) -> Self {
554        self.mul(*rhs)
555    }
556}
557
558impl Mul<&Mat2> for &Mat2 {
559    type Output = Mat2;
560    #[inline]
561    fn mul(self, rhs: &Mat2) -> Mat2 {
562        (*self).mul(*rhs)
563    }
564}
565
566impl Mul<Mat2> for &Mat2 {
567    type Output = Mat2;
568    #[inline]
569    fn mul(self, rhs: Mat2) -> Mat2 {
570        (*self).mul(rhs)
571    }
572}
573
574impl MulAssign for Mat2 {
575    #[inline]
576    fn mul_assign(&mut self, rhs: Self) {
577        *self = self.mul(rhs);
578    }
579}
580
581impl MulAssign<&Self> for Mat2 {
582    #[inline]
583    fn mul_assign(&mut self, rhs: &Self) {
584        self.mul_assign(*rhs);
585    }
586}
587
588impl Mul<Vec2> for Mat2 {
589    type Output = Vec2;
590    #[inline]
591    fn mul(self, rhs: Vec2) -> Self::Output {
592        self.mul_vec2(rhs)
593    }
594}
595
596impl Mul<&Vec2> for Mat2 {
597    type Output = Vec2;
598    #[inline]
599    fn mul(self, rhs: &Vec2) -> Vec2 {
600        self.mul(*rhs)
601    }
602}
603
604impl Mul<&Vec2> for &Mat2 {
605    type Output = Vec2;
606    #[inline]
607    fn mul(self, rhs: &Vec2) -> Vec2 {
608        (*self).mul(*rhs)
609    }
610}
611
612impl Mul<Vec2> for &Mat2 {
613    type Output = Vec2;
614    #[inline]
615    fn mul(self, rhs: Vec2) -> Vec2 {
616        (*self).mul(rhs)
617    }
618}
619
620impl Mul<Mat2> for f32 {
621    type Output = Mat2;
622    #[inline]
623    fn mul(self, rhs: Mat2) -> Self::Output {
624        rhs.mul_scalar(self)
625    }
626}
627
628impl Mul<&Mat2> for f32 {
629    type Output = Mat2;
630    #[inline]
631    fn mul(self, rhs: &Mat2) -> Mat2 {
632        self.mul(*rhs)
633    }
634}
635
636impl Mul<&Mat2> for &f32 {
637    type Output = Mat2;
638    #[inline]
639    fn mul(self, rhs: &Mat2) -> Mat2 {
640        (*self).mul(*rhs)
641    }
642}
643
644impl Mul<Mat2> for &f32 {
645    type Output = Mat2;
646    #[inline]
647    fn mul(self, rhs: Mat2) -> Mat2 {
648        (*self).mul(rhs)
649    }
650}
651
652impl Mul<f32> for Mat2 {
653    type Output = Self;
654    #[inline]
655    fn mul(self, rhs: f32) -> Self {
656        self.mul_scalar(rhs)
657    }
658}
659
660impl Mul<&f32> for Mat2 {
661    type Output = Self;
662    #[inline]
663    fn mul(self, rhs: &f32) -> Self {
664        self.mul(*rhs)
665    }
666}
667
668impl Mul<&f32> for &Mat2 {
669    type Output = Mat2;
670    #[inline]
671    fn mul(self, rhs: &f32) -> Mat2 {
672        (*self).mul(*rhs)
673    }
674}
675
676impl Mul<f32> for &Mat2 {
677    type Output = Mat2;
678    #[inline]
679    fn mul(self, rhs: f32) -> Mat2 {
680        (*self).mul(rhs)
681    }
682}
683
684impl MulAssign<f32> for Mat2 {
685    #[inline]
686    fn mul_assign(&mut self, rhs: f32) {
687        *self = self.mul(rhs);
688    }
689}
690
691impl MulAssign<&f32> for Mat2 {
692    #[inline]
693    fn mul_assign(&mut self, rhs: &f32) {
694        self.mul_assign(*rhs);
695    }
696}
697
698impl Div<Mat2> for f32 {
699    type Output = Mat2;
700    #[inline]
701    fn div(self, rhs: Mat2) -> Self::Output {
702        rhs.div_scalar(self)
703    }
704}
705
706impl Div<&Mat2> for f32 {
707    type Output = Mat2;
708    #[inline]
709    fn div(self, rhs: &Mat2) -> Mat2 {
710        self.div(*rhs)
711    }
712}
713
714impl Div<&Mat2> for &f32 {
715    type Output = Mat2;
716    #[inline]
717    fn div(self, rhs: &Mat2) -> Mat2 {
718        (*self).div(*rhs)
719    }
720}
721
722impl Div<Mat2> for &f32 {
723    type Output = Mat2;
724    #[inline]
725    fn div(self, rhs: Mat2) -> Mat2 {
726        (*self).div(rhs)
727    }
728}
729
730impl Div<f32> for Mat2 {
731    type Output = Self;
732    #[inline]
733    fn div(self, rhs: f32) -> Self {
734        self.div_scalar(rhs)
735    }
736}
737
738impl Div<&f32> for Mat2 {
739    type Output = Self;
740    #[inline]
741    fn div(self, rhs: &f32) -> Self {
742        self.div(*rhs)
743    }
744}
745
746impl Div<&f32> for &Mat2 {
747    type Output = Mat2;
748    #[inline]
749    fn div(self, rhs: &f32) -> Mat2 {
750        (*self).div(*rhs)
751    }
752}
753
754impl Div<f32> for &Mat2 {
755    type Output = Mat2;
756    #[inline]
757    fn div(self, rhs: f32) -> Mat2 {
758        (*self).div(rhs)
759    }
760}
761
762impl DivAssign<f32> for Mat2 {
763    #[inline]
764    fn div_assign(&mut self, rhs: f32) {
765        *self = self.div(rhs);
766    }
767}
768
769impl DivAssign<&f32> for Mat2 {
770    #[inline]
771    fn div_assign(&mut self, rhs: &f32) {
772        self.div_assign(*rhs);
773    }
774}
775
776impl Sum<Self> for Mat2 {
777    fn sum<I>(iter: I) -> Self
778    where
779        I: Iterator<Item = Self>,
780    {
781        iter.fold(Self::ZERO, Self::add)
782    }
783}
784
785impl<'a> Sum<&'a Self> for Mat2 {
786    fn sum<I>(iter: I) -> Self
787    where
788        I: Iterator<Item = &'a Self>,
789    {
790        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
791    }
792}
793
794impl Product for Mat2 {
795    fn product<I>(iter: I) -> Self
796    where
797        I: Iterator<Item = Self>,
798    {
799        iter.fold(Self::IDENTITY, Self::mul)
800    }
801}
802
803impl<'a> Product<&'a Self> for Mat2 {
804    fn product<I>(iter: I) -> Self
805    where
806        I: Iterator<Item = &'a Self>,
807    {
808        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
809    }
810}
811
812impl PartialEq for Mat2 {
813    #[inline]
814    fn eq(&self, rhs: &Self) -> bool {
815        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
816    }
817}
818
819impl AsRef<[f32; 4]> for Mat2 {
820    #[inline]
821    fn as_ref(&self) -> &[f32; 4] {
822        unsafe { &*(self as *const Self as *const [f32; 4]) }
823    }
824}
825
826impl AsMut<[f32; 4]> for Mat2 {
827    #[inline]
828    fn as_mut(&mut self) -> &mut [f32; 4] {
829        unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
830    }
831}
832
833impl core::ops::Deref for Mat2 {
834    type Target = crate::deref::Cols2<Vec2>;
835    #[inline]
836    fn deref(&self) -> &Self::Target {
837        unsafe { &*(self as *const Self as *const Self::Target) }
838    }
839}
840
841impl core::ops::DerefMut for Mat2 {
842    #[inline]
843    fn deref_mut(&mut self) -> &mut Self::Target {
844        unsafe { &mut *(self as *mut Self as *mut Self::Target) }
845    }
846}
847
848impl fmt::Debug for Mat2 {
849    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
850        fmt.debug_struct(stringify!(Mat2))
851            .field("x_axis", &self.x_axis)
852            .field("y_axis", &self.y_axis)
853            .finish()
854    }
855}
856
857impl fmt::Display for Mat2 {
858    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
859        if let Some(p) = f.precision() {
860            write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
861        } else {
862            write!(f, "[{}, {}]", self.x_axis, self.y_axis)
863        }
864    }
865}