1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub struct NDim<const N: usize, T>(pub [T; N]);
3
4impl<const N: usize, T: PartialEq> PartialEq<[T; N]> for NDim<N, T> {
5 fn eq(&self, other: &[T; N]) -> bool {
6 self.0 == *other
7 }
8}
9
10#[repr(C)]
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct Xy<T> {
13 pub x: T,
14 pub y: T,
15}
16
17#[repr(C)]
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct Xyz<T> {
20 pub x: T,
21 pub y: T,
22 pub z: T,
23}
24
25#[repr(C)]
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub struct Xyzw<T> {
28 pub x: T,
29 pub y: T,
30 pub z: T,
31 pub w: T,
32}
33
34impl<T> std::ops::Deref for NDim<2, T> {
35 type Target = Xy<T>;
36 fn deref(&self) -> &Self::Target {
37 unsafe { std::mem::transmute(self) }
38 }
39}
40impl<T> std::ops::DerefMut for NDim<2, T> {
41 fn deref_mut(&mut self) -> &mut Self::Target {
42 unsafe { std::mem::transmute(self) }
43 }
44}
45impl<T> std::ops::Deref for NDim<3, T> {
46 type Target = Xyz<T>;
47 fn deref(&self) -> &Self::Target {
48 unsafe { std::mem::transmute(self) }
49 }
50}
51impl<T> std::ops::DerefMut for NDim<3, T> {
52 fn deref_mut(&mut self) -> &mut Self::Target {
53 unsafe { std::mem::transmute(self) }
54 }
55}
56impl<T> std::ops::Deref for NDim<4, T> {
57 type Target = Xyzw<T>;
58 fn deref(&self) -> &Self::Target {
59 unsafe { std::mem::transmute(self) }
60 }
61}
62impl<T> std::ops::DerefMut for NDim<4, T> {
63 fn deref_mut(&mut self) -> &mut Self::Target {
64 unsafe { std::mem::transmute(self) }
65 }
66}
67
68impl<const N: usize, T> NDim<N, T> {
69 pub fn as_array(&self) -> &[T; N] {
70 &self.0
71 }
72 pub fn as_array_mut(&mut self) -> &mut [T; N] {
73 &mut self.0
74 }
75 pub fn into_array(self) -> [T; N] {
76 self.0
77 }
78 pub fn iter(&self) -> std::slice::Iter<T> {
79 self.0.iter()
80 }
81}
82impl<T> NDim<2, T> {
83 pub fn new(x: T, y: T) -> Self {
84 Self([x, y])
85 }
86}
87impl<T> NDim<3, T> {
88 pub fn new(x: T, y: T, z: T) -> Self {
89 Self([x, y, z])
90 }
91}
92impl<T> NDim<4, T> {
93 pub fn new(x: T, y: T, z: T, w: T) -> Self {
94 Self([x, y, z, w])
95 }
96}
97impl<const N: usize, T> std::ops::Index<usize> for NDim<N, T> {
98 type Output = T;
99 fn index(&self, index: usize) -> &Self::Output {
100 &self.0[index]
101 }
102}
103impl<const N: usize, T> std::ops::IndexMut<usize> for NDim<N, T> {
104 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
105 &mut self.0[index]
106 }
107}
108impl<const N: usize, T> From<[T; N]> for NDim<N, T> {
109 fn from(array: [T; N]) -> Self {
110 Self(array)
111 }
112}
113impl<const N: usize, T> From<NDim<N, T>> for [T; N] {
114 fn from(ndim: NDim<N, T>) -> Self {
115 ndim.0
116 }
117}
118impl<const N: usize, T> IntoIterator for NDim<N, T> {
119 type Item = T;
120 type IntoIter = std::array::IntoIter<T, N>;
121 fn into_iter(self) -> Self::IntoIter {
122 self.0.into_iter()
123 }
124}
125impl<'a, const N: usize, T> IntoIterator for &'a NDim<N, T> {
126 type Item = &'a T;
127 type IntoIter = std::slice::Iter<'a, T>;
128 fn into_iter(self) -> Self::IntoIter {
129 self.iter()
130 }
131}