1#![cfg_attr(feature = "no_std", no_std)]
51
52#[cfg(feature = "no_std")]
53extern crate alloc;
54
55#[cfg(not(feature = "no_std"))]
56use std::{
57 fmt,
58 hash::{Hash, Hasher},
59 iter::FromIterator,
60 mem::{self, MaybeUninit},
61 ops::{Deref, DerefMut, Index, IndexMut},
62};
63
64#[cfg(feature = "no_std")]
65use core::{
66 fmt,
67 hash::{Hash, Hasher},
68 iter::FromIterator,
69 mem::{self, MaybeUninit},
70 ops::{Deref, DerefMut, Index, IndexMut},
71};
72
73#[cfg(feature = "no_std")]
74use alloc::{boxed::Box, vec::Vec};
75
76pub struct VecArray<T> {
82 len: usize,
84 array_store: [MaybeUninit<T>; MAX_ARRAY_SIZE],
86 vec_store: Vec<T>,
88}
89
90pub const MAX_ARRAY_SIZE: usize = 4;
100
101impl<T> Drop for VecArray<T> {
102 fn drop(&mut self) {
103 self.clear();
104 }
105}
106
107impl<T: Hash> Hash for VecArray<T> {
108 fn hash<H: Hasher>(&self, state: &mut H) {
109 self.iter().for_each(|x| x.hash(state));
110 }
111}
112
113impl<T> Default for VecArray<T> {
114 fn default() -> Self {
115 Self {
116 len: 0,
117 array_store: unsafe { mem::MaybeUninit::uninit().assume_init() },
118 vec_store: Vec::new(),
119 }
120 }
121}
122
123impl<T: PartialEq> PartialEq for VecArray<T> {
124 fn eq(&self, other: &Self) -> bool {
125 if self.len != other.len || self.vec_store != other.vec_store {
126 return false;
127 }
128
129 if self.len > MAX_ARRAY_SIZE {
130 return true;
131 }
132
133 unsafe {
134 mem::transmute::<_, &[T; MAX_ARRAY_SIZE]>(&self.array_store)
135 == mem::transmute::<_, &[T; MAX_ARRAY_SIZE]>(&other.array_store)
136 }
137 }
138}
139
140impl<T: Clone> Clone for VecArray<T> {
141 fn clone(&self) -> Self {
142 let mut value: Self = Default::default();
143 value.len = self.len;
144
145 if self.is_fixed_storage() {
146 for x in 0..self.len {
147 let item = self.array_store.get(x).unwrap();
148 let item_value = unsafe { mem::transmute::<_, &T>(item) };
149 value.array_store[x] = MaybeUninit::new(item_value.clone());
150 }
151 } else {
152 value.vec_store = self.vec_store.clone();
153 }
154
155 value
156 }
157}
158
159impl<T: Eq> Eq for VecArray<T> {}
160
161impl<T> FromIterator<T> for VecArray<T> {
162 fn from_iter<X: IntoIterator<Item = T>>(iter: X) -> Self {
163 let mut vec = VecArray::new();
164
165 for x in iter {
166 vec.push(x);
167 }
168
169 vec
170 }
171}
172
173impl<T: 'static> IntoIterator for VecArray<T> {
174 type Item = T;
175 type IntoIter = Box<dyn Iterator<Item = T>>;
176
177 fn into_iter(self) -> Self::IntoIter {
178 self.into_iter()
179 }
180}
181
182impl<T> VecArray<T> {
183 pub fn new() -> Self {
185 Default::default()
186 }
187
188 pub fn clear(&mut self) {
190 if self.is_fixed_storage() {
191 for x in 0..self.len {
192 self.extract_from_list(x);
193 }
194 } else {
195 self.vec_store.clear();
196 }
197 self.len = 0;
198 }
199
200 fn extract(value: MaybeUninit<T>) -> T {
202 unsafe { value.assume_init() }
203 }
204
205 fn extract_from_list(&mut self, index: usize) -> T {
211 if !self.is_fixed_storage() {
212 panic!("not fixed storage in VecArray");
213 }
214 if index >= self.len {
215 panic!("index OOB in VecArray");
216 }
217 Self::extract(mem::replace(
218 self.array_store.get_mut(index).unwrap(),
219 MaybeUninit::uninit(),
220 ))
221 }
222
223 fn set_into_list(&mut self, index: usize, value: T, drop: bool) {
230 if !self.is_fixed_storage() {
231 panic!("not fixed storage in VecArray");
232 }
233 if index > self.len {
235 panic!("index OOB in VecArray");
236 }
237 let temp = mem::replace(
238 self.array_store.get_mut(index).unwrap(),
239 MaybeUninit::new(value),
240 );
241 if drop {
242 Self::extract(temp);
244 }
245 }
246
247 fn move_fixed_into_vec(&mut self, num: usize) {
253 if !self.is_fixed_storage() {
254 panic!("not fixed storage in VecArray");
255 }
256 if self.len != num {
257 panic!("fixed storage is not full in VecArray");
258 }
259 self.vec_store.extend(
260 self.array_store
261 .iter_mut()
262 .take(num)
263 .map(|v| mem::replace(v, MaybeUninit::uninit()))
264 .map(Self::extract),
265 );
266 }
267
268 fn is_fixed_storage(&self) -> bool {
270 self.len <= MAX_ARRAY_SIZE
271 }
272
273 pub fn push<X: Into<T>>(&mut self, value: X) {
275 if self.len == MAX_ARRAY_SIZE {
276 self.move_fixed_into_vec(MAX_ARRAY_SIZE);
277 self.vec_store.push(value.into());
278 } else if self.is_fixed_storage() {
279 self.set_into_list(self.len, value.into(), false);
280 } else {
281 self.vec_store.push(value.into());
282 }
283 self.len += 1;
284 }
285
286 pub fn insert<X: Into<T>>(&mut self, index: usize, value: X) {
288 let index = if index > self.len { self.len } else { index };
289
290 if self.len == MAX_ARRAY_SIZE {
291 self.move_fixed_into_vec(MAX_ARRAY_SIZE);
292 self.vec_store.insert(index, value.into());
293 } else if self.is_fixed_storage() {
294 for x in (index..self.len).rev() {
296 let orig_value = self.extract_from_list(x);
297 self.set_into_list(x + 1, orig_value, false);
298 }
299 self.set_into_list(index, value.into(), false);
300 } else {
301 self.vec_store.insert(index, value.into());
302 }
303 self.len += 1;
304 }
305
306 pub fn pop(&mut self) -> Option<T> {
308 if self.is_empty() {
309 return None;
310 }
311
312 Some(if self.is_fixed_storage() {
313 let value = self.extract_from_list(self.len - 1);
314 self.len -= 1;
315 value
316 } else {
317 let value = self.vec_store.pop().unwrap();
318 self.len -= 1;
319
320 if self.vec_store.len() == MAX_ARRAY_SIZE {
322 for index in (0..MAX_ARRAY_SIZE).rev() {
323 let item = self.vec_store.pop().unwrap();
324 self.set_into_list(index, item, false);
325 }
326 }
327
328 value
329 })
330 }
331
332 pub fn remove(&mut self, index: usize) -> Option<T> {
334 if index >= self.len {
335 return None;
336 }
337
338 Some(if self.is_fixed_storage() {
339 let value = self.extract_from_list(index);
340
341 for x in index + 1..self.len {
343 let orig_value = self.extract_from_list(x);
344 self.set_into_list(x - 1, orig_value, false);
345 }
346 self.len -= 1;
347
348 value
349 } else {
350 let value = self.vec_store.remove(index);
351 self.len -= 1;
352
353 if self.vec_store.len() == MAX_ARRAY_SIZE {
355 for index in (0..MAX_ARRAY_SIZE).rev() {
356 let item = self.vec_store.pop().unwrap();
357 self.set_into_list(index, item, false);
358 }
359 }
360
361 value
362 })
363 }
364
365 pub fn len(&self) -> usize {
367 self.len
368 }
369
370 pub fn is_empty(&self) -> bool {
372 self.len == 0
373 }
374
375 pub fn get(&self, index: usize) -> Option<&T> {
377 if index >= self.len {
378 return None;
379 }
380
381 let list = unsafe { mem::transmute::<_, &[T; MAX_ARRAY_SIZE]>(&self.array_store) };
382
383 if self.is_fixed_storage() {
384 list.get(index)
385 } else {
386 self.vec_store.get(index)
387 }
388 }
389
390 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
392 if index >= self.len {
393 return None;
394 }
395
396 let list = unsafe { mem::transmute::<_, &mut [T; MAX_ARRAY_SIZE]>(&mut self.array_store) };
397
398 if self.is_fixed_storage() {
399 list.get_mut(index)
400 } else {
401 self.vec_store.get_mut(index)
402 }
403 }
404
405 pub fn iter(&self) -> impl Iterator<Item = &T> {
407 let list = unsafe { mem::transmute::<_, &[T; MAX_ARRAY_SIZE]>(&self.array_store) };
408
409 if self.is_fixed_storage() {
410 list[..self.len].iter()
411 } else {
412 self.vec_store.iter()
413 }
414 }
415
416 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
418 let list = unsafe { mem::transmute::<_, &mut [T; MAX_ARRAY_SIZE]>(&mut self.array_store) };
419
420 if self.is_fixed_storage() {
421 list[..self.len].iter_mut()
422 } else {
423 self.vec_store.iter_mut()
424 }
425 }
426}
427
428impl<T: 'static> VecArray<T> {
429 pub fn into_iter(mut self) -> Box<dyn Iterator<Item = T>> {
431 if self.is_fixed_storage() {
432 let mut it = FixedStorageIterator {
433 data: unsafe { mem::MaybeUninit::uninit().assume_init() },
434 index: 0,
435 limit: self.len,
436 };
437
438 for x in 0..self.len {
439 it.data[x] =
440 mem::replace(self.array_store.get_mut(x).unwrap(), MaybeUninit::uninit());
441 }
442 self.len = 0;
443
444 Box::new(it)
445 } else {
446 Box::new(Vec::from(self).into_iter())
447 }
448 }
449}
450
451struct FixedStorageIterator<T> {
453 data: [MaybeUninit<T>; MAX_ARRAY_SIZE],
454 index: usize,
455 limit: usize,
456}
457
458impl<T> Iterator for FixedStorageIterator<T> {
459 type Item = T;
460
461 fn next(&mut self) -> Option<Self::Item> {
462 if self.index >= self.limit {
463 None
464 } else {
465 self.index += 1;
466
467 let value = mem::replace(
468 self.data.get_mut(self.index - 1).unwrap(),
469 MaybeUninit::uninit(),
470 );
471
472 unsafe { Some(value.assume_init()) }
473 }
474 }
475}
476
477impl<T: Default> VecArray<T> {
478 pub fn take(&mut self, index: usize) -> Option<T> {
480 if index >= self.len {
481 return None;
482 }
483
484 if self.is_fixed_storage() {
485 self.array_store
486 .get_mut(index)
487 .map(|v| unsafe { mem::transmute(v) })
488 } else {
489 self.vec_store.get_mut(index)
490 }
491 .map(mem::take)
492 }
493}
494
495impl<T: fmt::Debug> fmt::Debug for VecArray<T> {
496 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
497 fmt::Debug::fmt(&self.iter().collect::<Vec<_>>(), f)
498 }
499}
500
501impl<T> AsRef<[T]> for VecArray<T> {
502 fn as_ref(&self) -> &[T] {
503 let list = unsafe { mem::transmute::<_, &[T; MAX_ARRAY_SIZE]>(&self.array_store) };
504
505 if self.is_fixed_storage() {
506 &list[..self.len]
507 } else {
508 &self.vec_store[..]
509 }
510 }
511}
512
513impl<T> AsMut<[T]> for VecArray<T> {
514 fn as_mut(&mut self) -> &mut [T] {
515 let list = unsafe { mem::transmute::<_, &mut [T; MAX_ARRAY_SIZE]>(&mut self.array_store) };
516
517 if self.is_fixed_storage() {
518 &mut list[..self.len]
519 } else {
520 &mut self.vec_store[..]
521 }
522 }
523}
524
525impl<T> Deref for VecArray<T> {
526 type Target = [T];
527 fn deref(&self) -> &Self::Target {
528 self.as_ref()
529 }
530}
531
532impl<T> DerefMut for VecArray<T> {
533 fn deref_mut(&mut self) -> &mut Self::Target {
534 self.as_mut()
535 }
536}
537
538impl<T> Index<usize> for VecArray<T> {
539 type Output = T;
540
541 fn index(&self, index: usize) -> &Self::Output {
542 self.get(index).unwrap()
543 }
544}
545
546impl<T> IndexMut<usize> for VecArray<T> {
547 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
548 self.get_mut(index).unwrap()
549 }
550}
551
552impl<T> From<VecArray<T>> for Vec<T> {
553 fn from(mut value: VecArray<T>) -> Self {
554 if value.len <= MAX_ARRAY_SIZE {
555 value.move_fixed_into_vec(value.len);
556 }
557 value.len = 0;
558
559 let mut arr = Self::new();
560 arr.append(&mut value.vec_store);
561 arr
562 }
563}
564
565impl<T> From<Vec<T>> for VecArray<T> {
566 fn from(mut value: Vec<T>) -> Self {
567 let mut arr: Self = Default::default();
568 arr.len = value.len();
569
570 if arr.len <= MAX_ARRAY_SIZE {
571 for x in (0..arr.len).rev() {
572 arr.set_into_list(x, value.pop().unwrap(), false);
573 }
574 } else {
575 arr.vec_store = value;
576 }
577
578 arr
579 }
580}