1use crate::{error::Result, types::bitset::BitAlloc};
4
5use super::{
6 boxed::Box,
7 traits::{Get, GetMut, ToIndex},
8};
9
10use core::mem::ManuallyDrop;
11use core::ops::{Index, IndexMut};
12use core::{borrow::Borrow, mem::MaybeUninit};
13
14#[proc_macros::fmt]
16pub struct IndexMap<K: ?Sized + ToIndex, V, const N: usize> {
17 data: [Option<V>; N],
18 phantom: core::marker::PhantomData<K>,
19}
20
21#[allow(dead_code)]
22impl<K: ?Sized + ToIndex, V, const N: usize> IndexMap<K, V, N> {
23 pub const fn new() -> Self {
27 Self {
28 data: [const { None }; N],
29 phantom: core::marker::PhantomData,
30 }
31 }
32
33 pub fn insert(&mut self, idx: &K, value: V) -> Result<()> {
40 let idx = K::to_index(Some(idx));
41
42 if idx < N {
43 self.data[idx] = Some(value);
44 Ok(())
45 } else {
46 Err(kerr!(ENOMEM))
47 }
48 }
49
50 pub fn remove(&mut self, idx: &K) -> Option<V> {
56 let idx = K::to_index(Some(idx));
57
58 if idx < N { self.data[idx].take() } else { None }
59 }
60
61 pub fn raw_insert(&mut self, idx: usize, value: V) -> Result<()> {
62 if idx < N {
63 self.data[idx] = Some(value);
64 Ok(())
65 } else {
66 Err(kerr!(ENOMEM))
67 }
68 }
69
70 pub fn raw_remove(&mut self, idx: usize) -> Option<V> {
71 if idx < N { self.data[idx].take() } else { None }
72 }
73
74 pub fn raw_at(&self, idx: usize) -> Option<&V> {
75 if idx < N {
76 self.data[idx].as_ref()
77 } else {
78 None
79 }
80 }
81
82 pub fn raw_at_mut(&mut self, idx: usize) -> Option<&mut V> {
83 if idx < N {
84 self.data[idx].as_mut()
85 } else {
86 None
87 }
88 }
89}
90
91impl<K: Copy + ToIndex, V, const N: usize> Index<K> for IndexMap<K, V, N> {
92 type Output = V;
93
94 fn index(&self, index: K) -> &Self::Output {
95 self.get::<K>(index).unwrap()
96 }
97}
98
99impl<K: Copy + ToIndex, V, const N: usize> IndexMut<K> for IndexMap<K, V, N> {
100 fn index_mut(&mut self, index: K) -> &mut Self::Output {
101 self.get_mut::<K>(index).unwrap()
102 }
103}
104
105impl<K: ?Sized + ToIndex, V, const N: usize> Get<K> for IndexMap<K, V, N> {
106 type Output = V;
107
108 fn get<Q: Borrow<K>>(&self, index: Q) -> Option<&Self::Output> {
109 let idx = K::to_index(Some(index.borrow()));
110 if idx < N {
111 self.data[idx].as_ref()
112 } else {
113 None
114 }
115 }
116}
117
118impl<K: ?Sized + ToIndex, V, const N: usize> GetMut<K> for IndexMap<K, V, N> {
119 fn get_mut<Q: Borrow<K>>(&mut self, index: Q) -> Option<&mut Self::Output> {
120 let idx = K::to_index(Some(index.borrow()));
121 if idx < N {
122 self.data[idx].as_mut()
123 } else {
124 None
125 }
126 }
127
128 fn get2_mut<Q: Borrow<K>>(
129 &mut self,
130 index1: Q,
131 index2: Q,
132 ) -> (Option<&mut Self::Output>, Option<&mut Self::Output>) {
133 let idx1 = K::to_index(Some(index1.borrow()));
134 let idx2 = K::to_index(Some(index2.borrow()));
135
136 if idx1 == idx2 {
137 debug_assert!(false, "get2_mut called with identical indices");
138 return (None, None);
139 }
140
141 if idx1 >= N {
142 return (
143 None,
144 if idx2 < N {
145 self.data[idx2].as_mut()
146 } else {
147 None
148 },
149 );
150 }
151 if idx2 >= N {
152 return (self.data[idx1].as_mut(), None);
153 }
154
155 let (left, right) = self.data.split_at_mut(idx1.max(idx2));
156
157 if idx1 < idx2 {
158 let elem1 = left[idx1].as_mut();
159 let elem2 = right[0].as_mut();
160 (elem1, elem2)
161 } else {
162 let elem1 = right[0].as_mut();
163 let elem2 = left[idx2].as_mut();
164 (elem1, elem2)
165 }
166 }
167
168 fn get3_mut<Q: Borrow<K>>(
169 &mut self,
170 index1: Q,
171 index2: Q,
172 index3: Q,
173 ) -> (
174 Option<&mut Self::Output>,
175 Option<&mut Self::Output>,
176 Option<&mut Self::Output>,
177 ) {
178 let idx1 = K::to_index(Some(index1.borrow()));
179 let idx2 = K::to_index(Some(index2.borrow()));
180 let idx3 = K::to_index(Some(index3.borrow()));
181
182 if idx1 == idx2 || idx1 == idx3 || idx2 == idx3 {
183 debug_assert!(false, "get3_mut called with identical indices");
184 return (None, None, None);
185 }
186
187 let ptr1 = if idx1 < N {
188 Some(&mut self.data[idx1] as *mut Option<V>)
189 } else {
190 None
191 };
192 let ptr2 = if idx2 < N {
193 Some(&mut self.data[idx2] as *mut Option<V>)
194 } else {
195 None
196 };
197 let ptr3 = if idx3 < N {
198 Some(&mut self.data[idx3] as *mut Option<V>)
199 } else {
200 None
201 };
202
203 unsafe {
206 (
207 ptr1.and_then(|p| (*p).as_mut()),
208 ptr2.and_then(|p| (*p).as_mut()),
209 ptr3.and_then(|p| (*p).as_mut()),
210 )
211 }
212 }
213}
214
215#[proc_macros::fmt]
217pub struct Vec<T, const N: usize> {
218 len: usize,
219 data: [MaybeUninit<T>; N],
220 extra: Box<[MaybeUninit<T>]>,
221}
222
223#[allow(dead_code)]
224impl<T, const N: usize> Vec<T, N> {
225 pub const fn new() -> Self {
229 Self {
230 len: 0,
231 data: [const { MaybeUninit::uninit() }; N],
232 extra: Box::new_slice_empty(),
233 }
234 }
235
236 pub const fn from_array(arr: [T; N]) -> Self {
237 let arr = ManuallyDrop::new(arr);
238 let mut data = [const { MaybeUninit::uninit() }; N];
239
240 let src: *const [T; N] = &arr as *const ManuallyDrop<[T; N]> as *const [T; N];
241 let dst: *mut [MaybeUninit<T>; N] = &mut data;
242
243 let mut i = 0;
244 while i < N {
245 unsafe {
246 let value = core::ptr::read((src as *const T).add(i));
247 (dst as *mut MaybeUninit<T>)
248 .add(i)
249 .write(MaybeUninit::new(value));
250 }
251 i += 1;
252 }
253
254 Self {
255 len: N,
256 data,
257 extra: Box::new_slice_empty(),
258 }
259 }
260
261 unsafe fn move_from_slice_to_uninit(dst: &mut [MaybeUninit<T>], src: &[MaybeUninit<T>]) {
262 assert_eq!(dst.len(), src.len());
263
264 unsafe {
265 for i in 0..dst.len() {
266 dst[i].write(src[i].as_ptr().read());
267 }
268 }
269 }
270
271 unsafe fn move_within_to_uninit(
272 slice: &mut [MaybeUninit<T>],
273 src_index: usize,
274 dst_index: usize,
275 count: usize,
276 ) {
277 assert!(src_index + count <= slice.len());
278 assert!(dst_index + count <= slice.len());
279
280 unsafe {
281 for i in 0..count {
282 let value = slice[src_index + i].as_ptr().read();
283 slice[dst_index + i].write(value);
284 }
285 }
286 }
287
288 pub fn reserve(&mut self, additional: usize) -> Result<()> {
294 let len_extra = self.extra.len();
295
296 if self.len + additional <= N + len_extra {
298 return Ok(());
299 }
300
301 let grow = self.len + additional - N;
303 let mut new_extra = Box::new_slice_uninit(grow)?;
304
305 bug_on!(new_extra.len() != grow);
307
308 let len_initialized_extra = self.len.saturating_sub(N);
309
310 unsafe {
312 Self::move_from_slice_to_uninit(
313 &mut new_extra[..len_initialized_extra],
314 &self.extra[..len_initialized_extra],
315 );
316 }
317
318 self.extra = new_extra;
320 Ok(())
321 }
322
323 pub fn reserve_total_capacity(&mut self, total_capacity: usize) -> Result<()> {
329 if self.capacity() >= total_capacity {
331 return Ok(());
332 }
333
334 let new_out_of_line_cap = total_capacity - N;
336 let mut new_extra = Box::new_slice_uninit(new_out_of_line_cap)?;
337
338 bug_on!(new_extra.len() != new_out_of_line_cap);
340
341 let curr_out_of_line_size = self.len.saturating_sub(N);
342 unsafe {
344 Self::move_from_slice_to_uninit(
345 &mut new_extra[..curr_out_of_line_size],
346 &self.extra[..curr_out_of_line_size],
347 );
348 }
349
350 self.extra = new_extra;
352 Ok(())
353 }
354
355 pub fn new_init(length: usize, value: T) -> Result<Self>
362 where
363 T: Clone,
364 {
365 let mut vec = Self::new();
366
367 if length <= N {
369 for i in 0..length {
371 vec.data[i].write(value.clone());
372 vec.len = i + 1;
375 }
376 } else {
377 let extra_len = length - N;
381 vec.extra = Box::new_slice_uninit(extra_len)?;
382
383 for elem in &mut vec.data {
384 elem.write(value.clone());
385 vec.len += 1;
386 }
387
388 for i in 0..extra_len {
389 vec.extra[i].write(value.clone());
390 vec.len += 1;
391 }
392 }
393
394 vec.len = length;
395 Ok(vec)
396 }
397
398 pub fn push(&mut self, value: T) -> Result<()> {
404 if self.len < N {
406 self.data[self.len].write(value);
408 self.len += 1;
409 Ok(())
410 } else {
411 let len_extra = self.extra.len();
412
413 if self.len < N + len_extra {
415 self.extra[self.len - N].write(value);
417 self.len += 1;
418 Ok(())
419 } else {
420 let grow = (len_extra + 1) * 2;
422 let mut new_extra = Box::new_slice_uninit(grow)?;
423
424 bug_on!(new_extra.len() != grow);
425
426 let len_initialized_extra = self.len - N;
427
428 unsafe {
430 Self::move_from_slice_to_uninit(
431 &mut new_extra[..len_initialized_extra],
432 &self.extra[..len_initialized_extra],
433 );
434 }
435
436 self.extra = new_extra;
438 self.extra[len_extra].write(value);
439 self.len += 1;
440 Ok(())
441 }
442 }
443 }
444
445 pub fn pop(&mut self) -> Option<T> {
449 if self.len == 0 {
450 return None;
451 }
452 self.remove(self.len - 1)
453 }
454
455 pub fn remove(&mut self, index: usize) -> Option<T> {
461 if index >= self.len {
463 return None;
464 }
465
466 let value = unsafe { self.at_mut_unchecked(index).read() };
468
469 if index < N {
471 let end = core::cmp::min(self.len, N);
473
474 unsafe {
476 Self::move_within_to_uninit(&mut self.data, index + 1, index, end - index - 1);
477 }
478
479 if self.len() > N {
481 let value = unsafe { self.extra[0].as_ptr().read() };
482 self.data[end - 1].write(value);
483 }
484
485 if self.len() > N {
487 unsafe {
488 Self::move_within_to_uninit(&mut self.extra, 1, 0, self.len - N - 1);
489 }
490 }
491 } else {
492 let index = index - N;
495 let end = self.len - N;
496
497 unsafe {
499 Self::move_within_to_uninit(&mut self.extra, index + 1, index, end - index - 1);
500 }
501 }
502
503 self.len -= 1;
504 Some(value)
505 }
506
507 pub fn len(&self) -> usize {
511 self.len
512 }
513
514 pub fn at(&self, index: usize) -> Option<&T> {
520 if index >= self.len {
522 return None;
523 }
524
525 if index < N {
526 unsafe { Some(self.data[index].assume_init_ref()) }
528 } else {
529 let index = index - N;
530 unsafe { Some(self.extra[index].assume_init_ref()) }
532 }
533 }
534
535 pub fn at_mut(&mut self, index: usize) -> Option<&mut T> {
541 if index >= self.len {
543 return None;
544 }
545
546 if index < N {
547 unsafe { Some(self.data[index].assume_init_mut()) }
549 } else {
550 let index = index - N;
551 unsafe { Some(self.extra[index].assume_init_mut()) }
553 }
554 }
555
556 fn at_mut_unchecked(&mut self, index: usize) -> *mut T {
557 if index < N {
558 self.data[index].as_mut_ptr()
561 } else {
562 let index = index - N;
563 self.extra[index].as_mut_ptr()
566 }
567 }
568
569 pub fn at2_mut(&mut self, index1: usize, index2: usize) -> (Option<&mut T>, Option<&mut T>) {
576 if index1 == index2 {
577 debug_assert!(false, "at2_mut called with identical indices");
578 return (None, None);
579 }
580
581 let in1 = index1 < self.len;
582 let in2 = index2 < self.len;
583 let ptr1 = if in1 {
584 Some(self.at_mut_unchecked(index1))
585 } else {
586 None
587 };
588 let ptr2 = if in2 {
589 Some(self.at_mut_unchecked(index2))
590 } else {
591 None
592 };
593
594 unsafe { (ptr1.map(|p| &mut *p), ptr2.map(|p| &mut *p)) }
598 }
599
600 pub fn at3_mut(
608 &mut self,
609 index1: usize,
610 index2: usize,
611 index3: usize,
612 ) -> (Option<&mut T>, Option<&mut T>, Option<&mut T>) {
613 if index1 == index2 || index1 == index3 || index2 == index3 {
614 debug_assert!(false, "at3_mut called with identical indices");
615 return (None, None, None);
616 }
617
618 let in1 = index1 < self.len;
619 let in2 = index2 < self.len;
620 let in3 = index3 < self.len;
621 let ptr1 = if in1 {
622 Some(self.at_mut_unchecked(index1))
623 } else {
624 None
625 };
626 let ptr2 = if in2 {
627 Some(self.at_mut_unchecked(index2))
628 } else {
629 None
630 };
631 let ptr3 = if in3 {
632 Some(self.at_mut_unchecked(index3))
633 } else {
634 None
635 };
636
637 unsafe {
641 (
642 ptr1.map(|p| &mut *p),
643 ptr2.map(|p| &mut *p),
644 ptr3.map(|p| &mut *p),
645 )
646 }
647 }
648
649 pub fn swap(&mut self, a: usize, b: usize) {
654 if a >= self.len || b >= self.len {
656 return;
657 }
658
659 if a < N && b < N {
660 self.data.swap(a, b);
662 } else if a >= N && b >= N {
663 self.extra.swap(a - N, b - N);
665 } else if a >= N {
666 core::mem::swap(&mut self.extra[a - N], &mut self.data[b]);
668 } else {
669 core::mem::swap(&mut self.data[a], &mut self.extra[b - N]);
671 }
672 }
673
674 pub fn is_empty(&self) -> bool {
678 self.len == 0
679 }
680
681 pub fn capacity(&self) -> usize {
685 N + self.extra.len()
686 }
687}
688
689impl<T, const N: usize> Vec<T, N> {
690 pub fn clear(&mut self) {
692 let min = core::cmp::min(self.len, N);
693
694 for elem in &mut self.data[0..min] {
696 unsafe {
698 elem.assume_init_drop();
699 }
700 }
701
702 for elem in &mut (*self.extra)[0..self.len - min] {
704 unsafe {
706 elem.assume_init_drop();
707 }
708 }
709
710 self.len = 0;
711 }
712}
713
714impl<T, const N: usize> Drop for Vec<T, N> {
715 fn drop(&mut self) {
716 self.clear();
717 }
718}
719
720impl<T, const N: usize> Clone for Vec<T, N>
721where
722 T: Clone,
723{
724 fn clone(&self) -> Self {
725 let mut new_vec = Self::new();
726 let min = core::cmp::min(self.len, N);
727
728 bug_on!(new_vec.reserve_total_capacity(self.len).is_err());
729
730 for i in 0..min {
732 let value = unsafe { self.data[i].assume_init_ref() };
734 new_vec.data[i].write(value.clone());
735 }
736
737 for i in 0..self.len - min {
739 let value = unsafe { self.extra[i].assume_init_ref() };
741 new_vec.extra[i].write(value.clone());
742 }
743
744 new_vec.len = self.len;
745 new_vec
746 }
747}
748
749impl<T, const N: usize> Index<usize> for Vec<T, N> {
750 type Output = T;
751
752 fn index(&self, index: usize) -> &Self::Output {
753 self.at(index).unwrap()
754 }
755}
756
757impl<T, const N: usize> IndexMut<usize> for Vec<T, N> {
758 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
759 self.at_mut(index).unwrap()
760 }
761}
762
763impl<T, const N: usize> Get<usize> for Vec<T, N> {
764 type Output = T;
765
766 fn get<Q: Borrow<usize>>(&self, index: Q) -> Option<&Self::Output> {
767 self.at(*index.borrow())
768 }
769}
770
771impl<T, const N: usize> GetMut<usize> for Vec<T, N> {
772 fn get_mut<Q: Borrow<usize>>(&mut self, index: Q) -> Option<&mut Self::Output> {
773 self.at_mut(*index.borrow())
774 }
775
776 fn get2_mut<Q: Borrow<usize>>(
777 &mut self,
778 index1: Q,
779 index2: Q,
780 ) -> (Option<&mut Self::Output>, Option<&mut Self::Output>) {
781 self.at2_mut(*index1.borrow(), *index2.borrow())
782 }
783
784 fn get3_mut<Q: Borrow<usize>>(
785 &mut self,
786 index1: Q,
787 index2: Q,
788 index3: Q,
789 ) -> (
790 Option<&mut Self::Output>,
791 Option<&mut Self::Output>,
792 Option<&mut Self::Output>,
793 ) {
794 self.at3_mut(*index1.borrow(), *index2.borrow(), *index3.borrow())
795 }
796}
797
798pub struct BitReclaimMap<K: ?Sized + ToIndex, V, const N: usize> {
802 map: IndexMap<K, V, N>,
803 free: BitAlloc<N>,
804}
805
806impl<K: ?Sized + ToIndex, V, const N: usize> BitReclaimMap<K, V, N> {
807 pub const fn new() -> Self {
808 Self {
809 map: IndexMap::new(),
810 free: BitAlloc::from_array([!0usize; N]),
811 }
812 }
813
814 #[allow(dead_code)]
815 pub fn insert(&mut self, value: V) -> Result<usize> {
816 let idx = self.free.alloc(1).ok_or(kerr!(ENOMEM))?;
817 if let Err(e) = self.map.raw_insert(idx, value) {
818 self.free.free(idx, 1);
821 return Err(e);
822 }
823 Ok(idx)
824 }
825
826 pub fn remove(&mut self, idx: &K) -> Option<V> {
827 self.map.remove(idx).inspect(|_| {
828 self.free.free(K::to_index(Some(idx)), 1);
829 })
830 }
831}
832
833impl<K: ?Sized + ToIndex, V, const N: usize> BitReclaimMap<K, V, N> {
834 pub fn for_each<F: FnMut(usize, &V)>(&self, mut f: F) {
836 for slot in 0..N {
837 if let Some(v) = self.map.raw_at(slot) {
838 f(slot, v);
839 }
840 }
841 }
842}
843
844impl<K: Copy + ToIndex, V, const N: usize> BitReclaimMap<K, V, N> {
845 pub fn insert_with(&mut self, f: impl FnOnce(usize) -> Result<(K, V)>) -> Result<K> {
846 let idx = self.free.alloc(1).ok_or(kerr!(ENOMEM))?;
847 let (key, value) = match f(idx) {
850 Ok(kv) => kv,
851 Err(e) => {
852 self.free.free(idx, 1);
853 return Err(e);
854 }
855 };
856 if let Err(e) = self.map.raw_insert(idx, value) {
857 self.free.free(idx, 1);
858 return Err(e);
859 }
860 Ok(key)
861 }
862}
863
864impl<K: Copy + ToIndex, V, const N: usize> Index<K> for BitReclaimMap<K, V, N> {
865 type Output = V;
866
867 fn index(&self, index: K) -> &Self::Output {
868 self.get::<K>(index).unwrap()
869 }
870}
871
872impl<K: Copy + ToIndex, V, const N: usize> IndexMut<K> for BitReclaimMap<K, V, N> {
873 fn index_mut(&mut self, index: K) -> &mut Self::Output {
874 self.get_mut::<K>(index).unwrap()
875 }
876}
877
878impl<K: ?Sized + ToIndex, V, const N: usize> Get<K> for BitReclaimMap<K, V, N> {
879 type Output = V;
880
881 fn get<Q: Borrow<K>>(&self, index: Q) -> Option<&Self::Output> {
882 self.map.get(index)
883 }
884}
885
886impl<K: ?Sized + ToIndex, V, const N: usize> GetMut<K> for BitReclaimMap<K, V, N> {
887 fn get_mut<Q: Borrow<K>>(&mut self, index: Q) -> Option<&mut Self::Output> {
888 self.map.get_mut(index)
889 }
890
891 fn get2_mut<Q: Borrow<K>>(
892 &mut self,
893 index1: Q,
894 index2: Q,
895 ) -> (Option<&mut Self::Output>, Option<&mut Self::Output>) {
896 self.map.get2_mut(index1, index2)
897 }
898
899 fn get3_mut<Q: Borrow<K>>(
900 &mut self,
901 index1: Q,
902 index2: Q,
903 index3: Q,
904 ) -> (
905 Option<&mut Self::Output>,
906 Option<&mut Self::Output>,
907 Option<&mut Self::Output>,
908 ) {
909 self.map.get3_mut(index1, index2, index3)
910 }
911}
912
913#[cfg(test)]
914mod tests {
915 use super::Vec;
916 use crate::hal::mem::PhysAddr;
917 use crate::mem::GLOBAL_ALLOCATOR;
918 use core::ops::Range;
919 use core::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
920
921 fn alloc_range(length: usize) -> Range<PhysAddr> {
922 let alloc_range = std::alloc::Layout::from_size_align(length, align_of::<u128>()).unwrap();
923 let ptr = unsafe { std::alloc::alloc(alloc_range) };
924 PhysAddr::new(ptr as usize)..PhysAddr::new(ptr as usize + length)
925 }
926
927 fn setup_memory(mem_size: usize) {
928 unsafe {
929 GLOBAL_ALLOCATOR
930 .lock()
931 .add_range(&alloc_range(mem_size))
932 .unwrap()
933 };
934 }
935
936 #[derive(Debug)]
937 struct Tracker<'a> {
938 id: usize,
939 drops: &'a AtomicUsize,
940 drop_mask: &'a AtomicU64,
941 }
942
943 impl<'a> Tracker<'a> {
944 fn new(id: usize, drops: &'a AtomicUsize, drop_mask: &'a AtomicU64) -> Self {
945 Self {
946 id,
947 drops,
948 drop_mask,
949 }
950 }
951 }
952
953 impl Drop for Tracker<'_> {
954 fn drop(&mut self) {
955 let bit = 1u64 << self.id;
956 let old_mask = self.drop_mask.fetch_or(bit, Ordering::SeqCst);
957 assert_eq!(old_mask & bit, 0, "value {} was dropped twice", self.id);
958 self.drops.fetch_add(1, Ordering::SeqCst);
959 }
960 }
961
962 #[derive(Debug, Eq, PartialEq)]
963 struct NonCopy {
964 value: usize,
965 }
966
967 impl Clone for NonCopy {
968 fn clone(&self) -> Self {
969 Self { value: self.value }
970 }
971 }
972
973 #[test]
974 fn no_length_underflow() {
975 let vec = Vec::<usize, 8>::new();
976 assert!(vec.len() == 0);
977 assert_eq!(vec.at(0), None);
978 }
979
980 #[test]
981 fn reserve_works() {
982 let mut vec = Vec::<usize, 8>::new();
983 for i in 0..7usize {
984 vec.push(i).unwrap();
985 }
986 assert_eq!(vec.len(), 7);
987
988 let _ = vec.reserve(2);
989 }
990
991 #[test]
992 fn drop_underflow() {
993 let mut vec = Vec::<usize, 8>::new();
994 for i in 0..7usize {
995 vec.push(i).unwrap();
996 }
997 drop(vec);
998 }
999
1000 #[test]
1001 fn push_and_index_non_copy_inline() {
1002 let mut vec = Vec::<NonCopy, 4>::new();
1003
1004 for i in 0..4 {
1005 vec.push(NonCopy { value: i }).unwrap();
1006 }
1007
1008 assert_eq!(vec.len(), 4);
1009 for i in 0..4 {
1010 assert_eq!(vec[i].value, i);
1011 }
1012 }
1013
1014 #[test]
1015 fn push_grows_and_keeps_non_copy_values() {
1016 setup_memory(4096);
1017 let mut vec = Vec::<NonCopy, 2>::new();
1018
1019 for i in 0..8 {
1020 vec.push(NonCopy { value: i }).unwrap();
1021 }
1022
1023 assert_eq!(vec.len(), 8);
1024 assert!(vec.capacity() >= 8);
1025 for i in 0..8 {
1026 assert_eq!(vec.at(i).unwrap().value, i);
1027 }
1028 }
1029
1030 #[test]
1031 fn reserve_moves_only_live_extra_values() {
1032 setup_memory(4096);
1033 let drops = AtomicUsize::new(0);
1034 let drop_mask = AtomicU64::new(0);
1035 let mut vec = Vec::<Tracker<'_>, 2>::new();
1036
1037 for i in 0..4 {
1038 vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1039 }
1040
1041 vec.reserve(10).unwrap();
1042
1043 assert_eq!(drops.load(Ordering::SeqCst), 0);
1044 assert_eq!(vec.len(), 4);
1045 for i in 0..4 {
1046 assert_eq!(vec.at(i).unwrap().id, i);
1047 }
1048
1049 drop(vec);
1050 assert_eq!(drops.load(Ordering::SeqCst), 4);
1051 assert_eq!(drop_mask.load(Ordering::SeqCst), 0b1111);
1052 }
1053
1054 #[test]
1055 fn reserve_total_capacity_moves_non_copy_values() {
1056 setup_memory(4096);
1057 let mut vec = Vec::<NonCopy, 2>::new();
1058
1059 for i in 0..5 {
1060 vec.push(NonCopy { value: i }).unwrap();
1061 }
1062
1063 vec.reserve_total_capacity(16).unwrap();
1064
1065 assert!(vec.capacity() >= 16);
1066 assert_eq!(vec.len(), 5);
1067 for i in 0..5 {
1068 assert_eq!(vec.at(i).unwrap().value, i);
1069 }
1070 }
1071
1072 #[test]
1073 fn remove_from_inline_shifts_inline_values() {
1074 let mut vec = Vec::<NonCopy, 5>::new();
1075 for i in 0..5 {
1076 vec.push(NonCopy { value: i }).unwrap();
1077 }
1078
1079 let removed = vec.remove(1).unwrap();
1080
1081 assert_eq!(removed.value, 1);
1082 assert_eq!(vec.len(), 4);
1083 assert_eq!(vec.at(0).unwrap().value, 0);
1084 assert_eq!(vec.at(1).unwrap().value, 2);
1085 assert_eq!(vec.at(2).unwrap().value, 3);
1086 assert_eq!(vec.at(3).unwrap().value, 4);
1087 }
1088
1089 #[test]
1090 fn remove_from_inline_pulls_first_extra_value_inline() {
1091 setup_memory(4096);
1092 let mut vec = Vec::<NonCopy, 3>::new();
1093 for i in 0..7 {
1094 vec.push(NonCopy { value: i }).unwrap();
1095 }
1096
1097 let removed = vec.remove(1).unwrap();
1098
1099 assert_eq!(removed.value, 1);
1100 assert_eq!(vec.len(), 6);
1101 for (idx, expected) in [0, 2, 3, 4, 5, 6].iter().copied().enumerate() {
1102 assert_eq!(vec.at(idx).unwrap().value, expected);
1103 }
1104 }
1105
1106 #[test]
1107 fn remove_from_extra_shifts_extra_values() {
1108 setup_memory(4096);
1109 let mut vec = Vec::<NonCopy, 3>::new();
1110 for i in 0..8 {
1111 vec.push(NonCopy { value: i }).unwrap();
1112 }
1113
1114 let removed = vec.remove(5).unwrap();
1115
1116 assert_eq!(removed.value, 5);
1117 assert_eq!(vec.len(), 7);
1118 for (idx, expected) in [0, 1, 2, 3, 4, 6, 7].iter().copied().enumerate() {
1119 assert_eq!(vec.at(idx).unwrap().value, expected);
1120 }
1121 }
1122
1123 #[test]
1124 fn remove_last_extra_does_not_shift_or_drop_extra_values() {
1125 setup_memory(4096);
1126 let drops = AtomicUsize::new(0);
1127 let drop_mask = AtomicU64::new(0);
1128 let mut vec = Vec::<Tracker<'_>, 2>::new();
1129
1130 for i in 0..5 {
1131 vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1132 }
1133
1134 let removed = vec.remove(4).unwrap();
1135
1136 assert_eq!(removed.id, 4);
1137 assert_eq!(vec.len(), 4);
1138 assert_eq!(drops.load(Ordering::SeqCst), 0);
1139 drop(removed);
1140 assert_eq!(drops.load(Ordering::SeqCst), 1);
1141 drop(vec);
1142 assert_eq!(drops.load(Ordering::SeqCst), 5);
1143 assert_eq!(drop_mask.load(Ordering::SeqCst), 0b1_1111);
1144 }
1145
1146 #[test]
1147 fn pop_moves_value_out_without_copy() {
1148 let drops = AtomicUsize::new(0);
1149 let drop_mask = AtomicU64::new(0);
1150 let mut vec = Vec::<Tracker<'_>, 4>::new();
1151
1152 for i in 0..3 {
1153 vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1154 }
1155
1156 let popped = vec.pop().unwrap();
1157
1158 assert_eq!(popped.id, 2);
1159 assert_eq!(vec.len(), 2);
1160 assert_eq!(drops.load(Ordering::SeqCst), 0);
1161 drop(popped);
1162 assert_eq!(drops.load(Ordering::SeqCst), 1);
1163 drop(vec);
1164 assert_eq!(drops.load(Ordering::SeqCst), 3);
1165 assert_eq!(drop_mask.load(Ordering::SeqCst), 0b111);
1166 }
1167
1168 #[test]
1169 fn clear_drops_each_live_value_once() {
1170 setup_memory(4096);
1171 let drops = AtomicUsize::new(0);
1172 let drop_mask = AtomicU64::new(0);
1173 let mut vec = Vec::<Tracker<'_>, 2>::new();
1174
1175 for i in 0..6 {
1176 vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1177 }
1178
1179 vec.clear();
1180
1181 assert_eq!(vec.len(), 0);
1182 assert_eq!(drops.load(Ordering::SeqCst), 6);
1183 assert_eq!(drop_mask.load(Ordering::SeqCst), 0b11_1111);
1184 drop(vec);
1185 assert_eq!(drops.load(Ordering::SeqCst), 6);
1186 }
1187
1188 #[test]
1189 fn remove_then_drop_drops_every_value_once() {
1190 setup_memory(4096);
1191 let drops = AtomicUsize::new(0);
1192 let drop_mask = AtomicU64::new(0);
1193 let mut vec = Vec::<Tracker<'_>, 3>::new();
1194
1195 for i in 0..7 {
1196 vec.push(Tracker::new(i, &drops, &drop_mask)).unwrap();
1197 }
1198
1199 let removed_inline = vec.remove(1).unwrap();
1200 let removed_extra = vec.remove(4).unwrap();
1201
1202 assert_eq!(removed_inline.id, 1);
1203 assert_eq!(removed_extra.id, 5);
1204 assert_eq!(drops.load(Ordering::SeqCst), 0);
1205
1206 drop(removed_inline);
1207 drop(removed_extra);
1208 assert_eq!(drops.load(Ordering::SeqCst), 2);
1209
1210 drop(vec);
1211 assert_eq!(drops.load(Ordering::SeqCst), 7);
1212 assert_eq!(drop_mask.load(Ordering::SeqCst), 0b111_1111);
1213 }
1214
1215 #[test]
1216 fn clone_works_for_non_copy_values() {
1217 setup_memory(4096);
1218 let mut vec = Vec::<NonCopy, 2>::new();
1219 for i in 0..5 {
1220 vec.push(NonCopy { value: i }).unwrap();
1221 }
1222
1223 let clone = vec.clone();
1224
1225 assert_eq!(clone.len(), 5);
1226 for i in 0..5 {
1227 assert_eq!(clone.at(i).unwrap().value, i);
1228 assert_eq!(vec.at(i).unwrap().value, i);
1229 }
1230 }
1231
1232 #[test]
1233 fn new_init_sets_length_and_initializes_values() {
1234 setup_memory(4096);
1235 let vec = Vec::<NonCopy, 2>::new_init(5, NonCopy { value: 42 }).unwrap();
1236
1237 assert_eq!(vec.len(), 5);
1238 for i in 0..5 {
1239 assert_eq!(vec.at(i).unwrap().value, 42);
1240 }
1241 }
1242
1243 #[test]
1244 fn new_init_oom_does_not_leak() {
1245 struct Counted<'a> {
1246 drops: &'a AtomicUsize,
1247 clones: &'a AtomicUsize,
1248 }
1249 impl Clone for Counted<'_> {
1250 fn clone(&self) -> Self {
1251 self.clones.fetch_add(1, Ordering::SeqCst);
1252 Counted {
1253 drops: self.drops,
1254 clones: self.clones,
1255 }
1256 }
1257 }
1258 impl Drop for Counted<'_> {
1259 fn drop(&mut self) {
1260 self.drops.fetch_add(1, Ordering::SeqCst);
1261 }
1262 }
1263
1264 setup_memory(4096);
1265 let drops = AtomicUsize::new(0);
1266 let clones = AtomicUsize::new(0);
1267 let r = Vec::<Counted, 2>::new_init(
1268 1_000_000_000,
1269 Counted {
1270 drops: &drops,
1271 clones: &clones,
1272 },
1273 );
1274 assert!(r.is_err());
1275 let n_clones = clones.load(Ordering::SeqCst);
1276 let n_drops = drops.load(Ordering::SeqCst);
1277 assert_eq!(
1278 n_drops,
1279 n_clones + 1,
1280 "leaked clones (clones={}, drops={})",
1281 n_clones,
1282 n_drops,
1283 );
1284 }
1285
1286 #[test]
1287 fn at2_mut_out_of_bounds_returns_none() {
1288 let mut vec = Vec::<usize, 4>::new();
1289 vec.push(7).unwrap();
1290 let (a, b) = vec.at2_mut(0, 2);
1291 assert!(a.is_some(), "index 0 is in-bounds");
1292 assert!(
1293 b.is_none(),
1294 "index 2 should be out-of-bounds (len=1) and return None, but got {:?}",
1295 b
1296 );
1297 }
1298
1299 #[test]
1300 fn at3_mut_out_of_bounds_returns_none() {
1301 let mut vec = Vec::<usize, 4>::new();
1302 vec.push(7).unwrap();
1303 vec.push(8).unwrap();
1304 let (a, b, c) = vec.at3_mut(0, 1, 3);
1305 assert!(a.is_some());
1306 assert!(b.is_some());
1307 assert!(
1308 c.is_none(),
1309 "index 3 should be out-of-bounds (len=2) and return None, but got {:?}",
1310 c
1311 );
1312 }
1313
1314 use super::IndexMap;
1315 use crate::types::traits::GetMut;
1316
1317 #[test]
1318 fn indexmap_get2_mut_out_of_bounds_returns_none() {
1319 let mut m: IndexMap<usize, u32, 4> = IndexMap::new();
1320 m.raw_insert(0, 10).unwrap();
1321 let (a, b) = m.get2_mut(0usize, 10usize);
1322 assert!(a.is_some());
1323 assert!(b.is_none());
1324 }
1325
1326 #[test]
1327 fn indexmap_get3_mut_out_of_bounds_returns_none() {
1328 let mut m: IndexMap<usize, u32, 4> = IndexMap::new();
1329 m.raw_insert(0, 10).unwrap();
1330 let (a, b, c) = m.get3_mut(0usize, 10usize, 11usize);
1331 assert!(a.is_some());
1332 assert!(b.is_none());
1333 assert!(c.is_none());
1334 }
1335
1336 use super::BitReclaimMap;
1337
1338 #[test]
1339 fn bitreclaim_insert_failure_does_not_leak() {
1340 let mut m: BitReclaimMap<usize, u32, 2> = BitReclaimMap::new();
1341 m.insert(10).unwrap();
1342 m.insert(20).unwrap();
1343 assert!(m.insert(30).is_err());
1345 let next_free = m.free.alloc(1);
1347 assert_eq!(
1348 next_free,
1349 Some(2),
1350 "expected bit 2 to be free after failed insert, but BitAlloc returned {:?}",
1351 next_free
1352 );
1353 }
1354
1355 #[test]
1356 fn bitreclaim_insert_with_failed_closure_does_not_leak() {
1357 use crate::error::Result as KResult;
1358 let mut m: BitReclaimMap<usize, u32, 2> = BitReclaimMap::new();
1359 for _ in 0..10 {
1360 let r: KResult<usize> =
1361 m.insert_with(|_idx| -> KResult<(usize, u32)> { Err(kerr!(ENOMEM)) });
1362 assert!(r.is_err());
1363 }
1364 let id0 = m.insert(10).unwrap();
1365 let id1 = m.insert(20).unwrap();
1366 assert!(id0 < 2);
1367 assert!(id1 < 2);
1368 assert_ne!(id0, id1);
1369 }
1370}