inter_val/
ndim.rs

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}