From 884a6fb8ce58945622996ef5f8e399d825f70570 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 26 Sep 2018 16:39:52 +0200 Subject: [PATCH 1/6] Derive `Debug` for iterator structs and deny missing debug impls --- CHANGELOG.md | 1 + src/lib.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4b5b72..7cb95a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `StableVec::insert_into_hole()` - `StableVec::grow()` - `StableVec::clear()` +- `Debug` implementations for `Iter`, `IterMut` and `Keys` ### Changed - The `Drop` impl now uses the `mem::needs_drop()` optimization hint to avoid diff --git a/src/lib.rs b/src/lib.rs index fc44266..ebb0a68 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,8 @@ //! use stable_vec::StableVec; //! ``` +#![deny(missing_debug_implementations)] + extern crate bit_vec; #[cfg(test)] #[macro_use] @@ -1005,6 +1007,7 @@ impl<'a, T> IntoIterator for &'a mut StableVec { /// Use the method [`StableVec::iter()`](struct.StableVec.html#method.iter) or /// the `IntoIterator` implementation of `&StableVec` to obtain an iterator /// of this kind. +#[derive(Debug)] pub struct Iter<'a, T: 'a> { sv: &'a StableVec, pos: usize, @@ -1023,6 +1026,7 @@ impl<'a, T: 'a> Iterator for Iter<'a, T> { /// Use the method [`StableVec::iter_mut()`](struct.StableVec.html#method.iter_mut) /// or the `IntoIterator` implementation of `&mut StableVec` to obtain an /// iterator of this kind. +#[derive(Debug)] pub struct IterMut<'a, T: 'a> { deleted: &'a mut BitVec, used_count: &'a mut usize, @@ -1072,6 +1076,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { /// /// Use the method [`StableVec::keys()`](struct.StableVec.html#method.keys) to /// obtain an iterator of this kind. +#[derive(Debug)] pub struct Keys<'a> { deleted: &'a BitVec, pos: usize, From 5d0dc4a9a2fc6c78401a2270a6c6086da5a421c4 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 26 Sep 2018 16:49:32 +0200 Subject: [PATCH 2/6] Add `StableVec::from_vec` --- CHANGELOG.md | 1 + src/lib.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb95a0..c9be293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `StableVec::insert_into_hole()` - `StableVec::grow()` - `StableVec::clear()` +- `StableVec::from_vec()` - `Debug` implementations for `Iter`, `IterMut` and `Keys` ### Changed diff --git a/src/lib.rs b/src/lib.rs index ebb0a68..a2a0cc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -194,6 +194,33 @@ impl StableVec { } } + /// Creates a `StableVec` from the given `Vec`. The elements are not + /// copied and the indices of the vector are preserved. + /// + /// Note that this function will still allocate memory to store meta data. + /// + /// # Example + /// + /// ``` + /// # use stable_vec::StableVec; + /// let mut sv = StableVec::from_vec(vec!['★', '♥']); + /// + /// assert_eq!(sv.get(0), Some(&'★')); + /// assert_eq!(sv.get(1), Some(&'♥')); + /// assert_eq!(sv.num_elements(), 2); + /// assert!(sv.is_compact()); + /// + /// sv.remove(0); + /// assert_eq!(sv.get(1), Some(&'♥')); + /// ``` + pub fn from_vec(vec: Vec) -> Self { + Self { + used_count: vec.len(), + deleted: BitVec::from_elem(vec.len(), false), + data: vec, + } + } + /// Reserves capacity for at least `additional` more elements to be /// inserted. pub fn reserve(&mut self, additional: usize) { From 7ef9559dbeb5a1085fd8a23b7b8ccb13c4c5db3b Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 26 Sep 2018 16:49:54 +0200 Subject: [PATCH 3/6] Update quickcheck --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8c6a25c..3ea7932 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,4 +22,4 @@ maintenance = { status = "actively-developed" } bit-vec = "0.5.0" [dev-dependencies] -quickcheck = "0.6.2" +quickcheck = "0.7" From 66bf10b509c4719109aa609b3519f6a88c4fcce9 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 26 Sep 2018 16:59:25 +0200 Subject: [PATCH 4/6] Add `StableVec::extend_from_slice` --- CHANGELOG.md | 1 + src/lib.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9be293..fd2587d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `StableVec::grow()` - `StableVec::clear()` - `StableVec::from_vec()` +- `StableVec::extend_from_slice()` - `Debug` implementations for `Iter`, `IterMut` and `Keys` ### Changed diff --git a/src/lib.rs b/src/lib.rs index a2a0cc1..0575f18 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -905,6 +905,18 @@ impl StableVec { } } } + + /// Appends all elements in `new_elements` to this `StableVec`. This is + /// equivalent to calling [`push()`][StableVec::push] for each element. + pub fn extend_from_slice(&mut self, new_elements: &[T]) + where + T: Clone, + { + // This could be improved for `Copy` elements via specialization. + for elem in new_elements { + self.push(elem.clone()); + } + } } impl Drop for StableVec { From beddfdfea3324e78d2848658a4732a65134b6275 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 26 Sep 2018 17:00:12 +0200 Subject: [PATCH 5/6] Add `Write` impl for `StableVec` --- CHANGELOG.md | 1 + src/lib.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd2587d..ce0a4ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `StableVec::from_vec()` - `StableVec::extend_from_slice()` - `Debug` implementations for `Iter`, `IterMut` and `Keys` +- `Write` implementation for `StableVec` ### Changed - The `Drop` impl now uses the `mem::needs_drop()` optimization hint to avoid diff --git a/src/lib.rs b/src/lib.rs index 0575f18..be65db8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ use bit_vec::BitVec; use std::fmt; use std::iter::FromIterator; use std::mem; +use std::io; use std::ops::{Index, IndexMut}; use std::ptr; @@ -1025,6 +1026,22 @@ impl Extend for StableVec { } } +/// Write into `StableVec` by appending `u8` elements. This is equivalent +/// to calling `push` for each byte. +impl io::Write for StableVec { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.extend_from_slice(buf); + Ok(buf.len()) + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.extend_from_slice(buf); + Ok(()) + } + + fn flush(&mut self) -> io::Result<()> { Ok(()) } +} + impl<'a, T> IntoIterator for &'a StableVec { type Item = &'a T; type IntoIter = Iter<'a, T>; From de7a40b6c0c716d483f960d03c681a9878f68687 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Wed, 26 Sep 2018 17:03:03 +0200 Subject: [PATCH 6/6] Improve docs --- src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index be65db8..76f5cdc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -660,8 +660,9 @@ impl StableVec { /// Removes all elements from this collection. /// - /// After calling this, `num_elements()` will return 0. However, no memory - /// is deallocated, so the capacity stays as it was before. + /// After calling this, `num_elements()` will return 0. All indices are + /// invalidated. However, no memory is deallocated, so the capacity stays + /// as it was before. /// /// # Example ///