diff --git a/flake.nix b/flake.nix index 4ace4c3..141d0f0 100644 --- a/flake.nix +++ b/flake.nix @@ -22,7 +22,15 @@ inherit system; overlays = [ (import rust-overlay) ]; }; - rust = pkgs.rust-bin.stable.latest.default.override { extensions = [ "rust-src" ]; }; + rust = pkgs.rust-bin.selectLatestNightlyWith ( + toolchain: + toolchain.default.override { + extensions = [ + "rust-src" + "miri" + ]; + } + ); naersk' = pkgs.callPackage naersk { cargo = rust; rustc = rust; diff --git a/src/tinyvec.rs b/src/tinyvec.rs index 7f07253..ea272cb 100644 --- a/src/tinyvec.rs +++ b/src/tinyvec.rs @@ -63,6 +63,37 @@ impl TinyVec { Layout::from_size_align(127 * size_of::(), 1).unwrap() } + pub fn insert_at(&mut self, at: usize, v: T) { + if at > self.len() { + panic!("Out of bound access") + } + + if at == self.len() { + return self.push(v); + } + + let ptr = match self.is_stack() { + true => { + let new_stack_len = (self.len() + 1) * size_of::(); + if new_stack_len > STACK_LEN { + self.spill(); + self.insert_at(at, v); + return; + } else { + unsafe { self.inner.stack.data.as_mut_ptr() } + } + } + false => unsafe { self.inner.heap.data }, + }; + + unsafe { + let place = ptr.cast::().add(at); + place.add(1).copy_from(place, self.len() - at); + place.write(v); + self.inner.len.len += 1 + } + } + pub fn extend_from_slice(&mut self, slice: &[T]) { let old_len = self.len(); let new_len = old_len + slice.len(); @@ -134,6 +165,12 @@ impl TinyVec { } } +impl std::fmt::Debug for TinyVec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_list().entries(self).finish() + } +} + impl std::ops::Deref for TinyVec { type Target = [T]; @@ -327,6 +364,41 @@ mod test { assert_eq!(&*a, values); } + #[test] + pub fn insert_stack() { + let mut a = TinyVec::<[u8; 2]>::new(); + a.push([1, 2]); + a.push([3, 4]); + a.insert_at(1, [5, 6]); + assert_eq!(&*a, &[[1, 2], [5, 6], [3, 4]]); + } + + #[test] + pub fn insert_heap() { + let mut values = vec![[0, 0]; 16]; + + let mut a = TinyVec::<[u8; 2]>::new(); + a.extend_from_slice(&values); + + values.insert(1, [5, 6]); + a.insert_at(1, [5, 6]); + + assert_eq!(&*a, &values); + } + + #[test] + pub fn insert_spill() { + let mut values = vec![[0, 0]; 7]; + + let mut a = TinyVec::<[u8; 2]>::new(); + a.extend_from_slice(&values); + + values.insert(1, [5, 6]); + a.insert_at(1, [5, 6]); + + assert_eq!(&*a, &values); + } + #[test] pub fn push_spill() { let values = (0..STACK_LEN as u8 + 1).collect_vec();