ndarray/dimension/
dynindeximpl.rs1use crate::imp_prelude::*;
2#[cfg(not(feature = "std"))]
3use alloc::boxed::Box;
4use alloc::vec;
5#[cfg(not(feature = "std"))]
6use alloc::vec::Vec;
7use std::hash::{Hash, Hasher};
8use std::ops::{Deref, DerefMut, Index, IndexMut};
9const CAP: usize = 4;
10
11#[derive(Debug)]
13enum IxDynRepr<T>
14{
15 Inline(u32, [T; CAP]),
16 Alloc(Box<[T]>),
17}
18
19impl<T> Deref for IxDynRepr<T>
20{
21 type Target = [T];
22 fn deref(&self) -> &[T]
23 {
24 match *self {
25 IxDynRepr::Inline(len, ref ar) => {
26 debug_assert!(len as usize <= ar.len());
27 unsafe { ar.get_unchecked(..len as usize) }
28 }
29 IxDynRepr::Alloc(ref ar) => ar,
30 }
31 }
32}
33
34impl<T> DerefMut for IxDynRepr<T>
35{
36 fn deref_mut(&mut self) -> &mut [T]
37 {
38 match *self {
39 IxDynRepr::Inline(len, ref mut ar) => {
40 debug_assert!(len as usize <= ar.len());
41 unsafe { ar.get_unchecked_mut(..len as usize) }
42 }
43 IxDynRepr::Alloc(ref mut ar) => ar,
44 }
45 }
46}
47
48impl Default for IxDynRepr<Ix>
50{
51 fn default() -> Self
52 {
53 Self::copy_from(&[0])
54 }
55}
56
57use num_traits::Zero;
58
59impl<T: Copy + Zero> IxDynRepr<T>
60{
61 pub fn copy_from(x: &[T]) -> Self
62 {
63 if x.len() <= CAP {
64 let mut arr = [T::zero(); CAP];
65 arr[..x.len()].copy_from_slice(x);
66 IxDynRepr::Inline(x.len() as _, arr)
67 } else {
68 Self::from(x)
69 }
70 }
71}
72
73impl<T: Copy + Zero> IxDynRepr<T>
74{
75 fn from_vec_auto(v: Vec<T>) -> Self
77 {
78 if v.len() <= CAP {
79 Self::copy_from(&v)
80 } else {
81 Self::from_vec(v)
82 }
83 }
84}
85
86impl<T: Copy> IxDynRepr<T>
87{
88 fn from_vec(v: Vec<T>) -> Self
89 {
90 IxDynRepr::Alloc(v.into_boxed_slice())
91 }
92
93 fn from(x: &[T]) -> Self
94 {
95 Self::from_vec(x.to_vec())
96 }
97}
98
99impl<T: Copy> Clone for IxDynRepr<T>
100{
101 fn clone(&self) -> Self
102 {
103 match *self {
104 IxDynRepr::Inline(len, arr) => IxDynRepr::Inline(len, arr),
105 _ => Self::from(&self[..]),
106 }
107 }
108}
109
110impl<T: Eq> Eq for IxDynRepr<T> {}
111
112impl<T: PartialEq> PartialEq for IxDynRepr<T>
113{
114 fn eq(&self, rhs: &Self) -> bool
115 {
116 match (self, rhs) {
117 (&IxDynRepr::Inline(slen, ref sarr), &IxDynRepr::Inline(rlen, ref rarr)) =>
118 slen == rlen
119 && (0..CAP)
120 .filter(|&i| i < slen as usize)
121 .all(|i| sarr[i] == rarr[i]),
122 _ => self[..] == rhs[..],
123 }
124 }
125}
126
127impl<T: Hash> Hash for IxDynRepr<T>
128{
129 fn hash<H: Hasher>(&self, state: &mut H)
130 {
131 Hash::hash(&self[..], state)
132 }
133}
134
135#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
141pub struct IxDynImpl(IxDynRepr<Ix>);
142
143impl IxDynImpl
144{
145 pub(crate) fn insert(&self, i: usize) -> Self
146 {
147 let len = self.len();
148 debug_assert!(i <= len);
149 IxDynImpl(if len < CAP {
150 let mut out = [1; CAP];
151 out[0..i].copy_from_slice(&self[0..i]);
152 out[i + 1..=len].copy_from_slice(&self[i..len]);
153 IxDynRepr::Inline((len + 1) as u32, out)
154 } else {
155 let mut out = Vec::with_capacity(len + 1);
156 out.extend_from_slice(&self[0..i]);
157 out.push(1);
158 out.extend_from_slice(&self[i..len]);
159 IxDynRepr::from_vec(out)
160 })
161 }
162
163 fn remove(&self, i: usize) -> Self
164 {
165 IxDynImpl(match self.0 {
166 IxDynRepr::Inline(0, _) => IxDynRepr::Inline(0, [0; CAP]),
167 IxDynRepr::Inline(1, _) => IxDynRepr::Inline(0, [0; CAP]),
168 IxDynRepr::Inline(2, ref arr) => {
169 let mut out = [0; CAP];
170 out[0] = arr[1 - i];
171 IxDynRepr::Inline(1, out)
172 }
173 ref ixdyn => {
174 let len = ixdyn.len();
175 let mut result = IxDynRepr::copy_from(&ixdyn[..len - 1]);
176 for j in i..len - 1 {
177 result[j] = ixdyn[j + 1]
178 }
179 result
180 }
181 })
182 }
183}
184
185impl<'a> From<&'a [Ix]> for IxDynImpl
186{
187 #[inline]
188 fn from(ix: &'a [Ix]) -> Self
189 {
190 IxDynImpl(IxDynRepr::copy_from(ix))
191 }
192}
193
194impl From<Vec<Ix>> for IxDynImpl
195{
196 #[inline]
197 fn from(ix: Vec<Ix>) -> Self
198 {
199 IxDynImpl(IxDynRepr::from_vec_auto(ix))
200 }
201}
202
203impl<J> Index<J> for IxDynImpl
204where [Ix]: Index<J>
205{
206 type Output = <[Ix] as Index<J>>::Output;
207 fn index(&self, index: J) -> &Self::Output
208 {
209 &self.0[index]
210 }
211}
212
213impl<J> IndexMut<J> for IxDynImpl
214where [Ix]: IndexMut<J>
215{
216 fn index_mut(&mut self, index: J) -> &mut Self::Output
217 {
218 &mut self.0[index]
219 }
220}
221
222impl Deref for IxDynImpl
223{
224 type Target = [Ix];
225 #[inline]
226 fn deref(&self) -> &[Ix]
227 {
228 &self.0
229 }
230}
231
232impl DerefMut for IxDynImpl
233{
234 #[inline]
235 fn deref_mut(&mut self) -> &mut [Ix]
236 {
237 &mut self.0
238 }
239}
240
241impl<'a> IntoIterator for &'a IxDynImpl
242{
243 type Item = &'a Ix;
244 type IntoIter = <&'a [Ix] as IntoIterator>::IntoIter;
245 #[inline]
246 fn into_iter(self) -> Self::IntoIter
247 {
248 self[..].iter()
249 }
250}
251
252impl RemoveAxis for Dim<IxDynImpl>
253{
254 fn remove_axis(&self, axis: Axis) -> Self
255 {
256 debug_assert!(axis.index() < self.ndim());
257 Dim::new(self.ix().remove(axis.index()))
258 }
259}
260
261impl IxDyn
262{
263 #[inline]
265 pub fn zeros(n: usize) -> IxDyn
266 {
267 const ZEROS: &[usize] = &[0; 4];
268 if n <= ZEROS.len() {
269 Dim(&ZEROS[..n])
270 } else {
271 Dim(vec![0; n])
272 }
273 }
274}