diff --git a/src/impls/storage.rs b/src/impls/storage.rs index c89d947..0a1b5b7 100644 --- a/src/impls/storage.rs +++ b/src/impls/storage.rs @@ -191,7 +191,10 @@ impl Storage for Doubling { #[inline] fn heap_size(&self, mut callback: F) { let size_of_usize = std::mem::size_of::(); - callback(self.offsets.len() * size_of_usize, self.offsets.capacity() * size_of_usize); + callback( + self.offsets.len() * size_of_usize, + self.offsets.capacity() * size_of_usize, + ); let size_of_t = std::mem::size_of::(); for inner in &self.inner { callback(inner.len() * size_of_t, inner.capacity() * size_of_t); diff --git a/src/lib.rs b/src/lib.rs index fbd7bbc..411d0c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,7 @@ pub use impls::option::OptionRegion; pub use impls::result::ResultRegion; pub use impls::slice::SliceRegion; pub use impls::slice_copy::OwnedRegion; +pub use impls::storage::Storage; pub use impls::string::StringRegion; /// An index into a region. Automatically implemented for relevant types. @@ -145,51 +146,47 @@ impl<'a, T: ToOwned + ?Sized> IntoOwned<'a> for &'a T { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde", - serde( - bound = "R: Serialize + for<'a> Deserialize<'a>, R::Index: Serialize + for<'a> Deserialize<'a>" - ) + serde(bound = " + R: Serialize + for<'a> Deserialize<'a>, + R::Index: Serialize + for<'a> Deserialize<'a>, + S: Serialize + for<'a> Deserialize<'a>, + ") )] -pub struct FlatStack { +pub struct FlatStack = Vec<::Index>> { /// The indices, which we use to lookup items in the region. - indices: Vec, + indices: S, /// A region to index into. region: R, } -impl Default for FlatStack { +impl::Index>> Default for FlatStack { #[inline] fn default() -> Self { Self { - indices: Vec::default(), + indices: S::default(), region: R::default(), } } } -impl Debug for FlatStack +impl::Index>> Debug for FlatStack where for<'a> R::ReadItem<'a>: Debug, + for<'a> &'a S: IntoIterator, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_list().entries(self.iter()).finish() } } -impl FlatStack { - /// Default implementation based on the preference of type `T`. - #[inline] - #[must_use] - pub fn default_impl>() -> Self { - Self::default() - } - +impl::Index>> FlatStack { /// Returns a flat stack that can absorb `capacity` indices without reallocation. /// /// Prefer [`Self::merge_capacity`] over this function to also pre-size the regions. #[must_use] pub fn with_capacity(capacity: usize) -> Self { Self { - indices: Vec::with_capacity(capacity), + indices: S::with_capacity(capacity), region: R::default(), } } @@ -198,10 +195,10 @@ impl FlatStack { #[must_use] pub fn merge_capacity<'a, I: Iterator + Clone + 'a>(stacks: I) -> Self where - R: 'a, + Self: 'a, { Self { - indices: Vec::with_capacity(stacks.clone().map(|s| s.indices.len()).sum()), + indices: S::merge_regions(stacks.clone().map(|s| &s.indices)), region: R::merge_regions(stacks.map(|r| &r.region)), } } @@ -213,14 +210,14 @@ impl FlatStack { R: Push, { let index = self.region.push(item); - self.indices.push(index); + self.indices.extend_from_slice(&[index]); } /// Returns the element at the `offset` position. #[inline] #[must_use] pub fn get(&self, offset: usize) -> R::ReadItem<'_> { - self.region.index(self.indices[offset]) + self.region.index(self.indices.index(offset, offset + 1)[0]) } /// Returns the number of indices in the stack. @@ -237,12 +234,6 @@ impl FlatStack { self.indices.is_empty() } - /// Returns the total number of indices the stack can hold without reallocation. - #[must_use] - pub fn capacity(&self) -> usize { - self.indices.capacity() - } - /// Reserves space to hold `additional` indices. #[inline] pub fn reserve(&mut self, additional: usize) { @@ -274,18 +265,41 @@ impl FlatStack { self.region.reserve_regions(regions); } + /// Heap size, size - capacity + #[inline] + pub fn heap_size(&self, mut callback: F) { + self.region.heap_size(&mut callback); + self.indices.heap_size(callback); + } +} + +impl FlatStack +where + R: Region, + S: Storage<::Index>, +{ /// Iterate the items in this stack. #[inline] - pub fn iter(&self) -> Iter<'_, R> { + pub fn iter<'a>(&'a self) -> Iter<'a, R, <&'a S as IntoIterator>::IntoIter> + where + &'a S: IntoIterator, + { self.into_iter() } +} - /// Heap size, size - capacity +impl FlatStack { + /// Default implementation based on the preference of type `T`. #[inline] - pub fn heap_size(&self, mut callback: F) { - use crate::impls::offsets::OffsetContainer; - self.region.heap_size(&mut callback); - self.indices.heap_size(callback); + #[must_use] + pub fn default_impl>() -> Self { + Self::default() + } + + /// Returns the total number of indices the stack can hold without reallocation. + #[must_use] + pub fn capacity(&self) -> usize { + self.indices.capacity() } } @@ -299,13 +313,16 @@ impl> Extend for FlatStack { } } -impl<'a, R: Region> IntoIterator for &'a FlatStack { +impl<'a, R: Region, S: Storage<::Index>> IntoIterator for &'a FlatStack +where + &'a S: IntoIterator::Index>, +{ type Item = R::ReadItem<'a>; - type IntoIter = Iter<'a, R>; + type IntoIter = Iter<'a, R, <&'a S as IntoIterator>::IntoIter>; fn into_iter(self) -> Self::IntoIter { Iter { - inner: self.indices.iter(), + inner: self.indices.into_iter(), region: &self.region, } } @@ -313,14 +330,22 @@ impl<'a, R: Region> IntoIterator for &'a FlatStack { /// An iterator over [`FlatStack`]. The iterator yields [`Region::ReadItem`] elements, which /// it obtains by looking up indices. -pub struct Iter<'a, R: Region> { +pub struct Iter<'a, R, S> +where + R: Region, + S: Iterator::Index>, +{ /// Iterator over indices. - inner: std::slice::Iter<'a, R::Index>, + inner: S, /// Region to map indices to read items. region: &'a R, } -impl<'a, R: Region> Iterator for Iter<'a, R> { +impl<'a, R, S> Iterator for Iter<'a, R, S> +where + R: Region, + S: Iterator::Index>, +{ type Item = R::ReadItem<'a>; fn next(&mut self) -> Option { @@ -332,9 +357,18 @@ impl<'a, R: Region> Iterator for Iter<'a, R> { } } -impl ExactSizeIterator for Iter<'_, R> {} +impl<'a, R, S> ExactSizeIterator for Iter<'a, R, S> +where + R: Region, + S: ExactSizeIterator::Index>, +{ +} -impl Clone for Iter<'_, R> { +impl<'a, R, S> Clone for Iter<'a, R, S> +where + R: Region, + S: Iterator::Index> + Clone, +{ fn clone(&self) -> Self { Self { inner: self.inner.clone(),