diff --git a/src/impls/mod.rs b/src/impls/mod.rs new file mode 100644 index 0000000..1400593 --- /dev/null +++ b/src/impls/mod.rs @@ -0,0 +1,2 @@ +pub mod slice; +mod vec; diff --git a/src/impls.rs b/src/impls/slice.rs similarity index 75% rename from src/impls.rs rename to src/impls/slice.rs index bc2f5b8..7b65c04 100644 --- a/src/impls.rs +++ b/src/impls/slice.rs @@ -1,11 +1,27 @@ use std::{mem, raw}; -use {IntrusiveIterator, FromIntrusiveIterator}; +use {IntrusiveIterator}; -impl<'a, T> IntrusiveIterator<&'a T> for &'a [T] { +pub trait SliceIntrusiveIter for Sized? { + fn intrusive_iter(&self) -> Items; + fn intrusive_iter_mut(&mut self) -> ItemsMut; +} + +pub struct Items<'a, T: 'a>(&'a [T]); +pub struct ItemsMut<'a, T: 'a>(&'a mut [T]); + +impl SliceIntrusiveIter for [T] { + #[inline] + fn intrusive_iter(&self) -> Items { Items(self) } + + #[inline] + fn intrusive_iter_mut(&mut self) -> ItemsMut { ItemsMut(self) } +} + +impl<'a, T> IntrusiveIterator<&'a T> for Items<'a, T> { #[inline] fn traverse bool>(self, mut f: F) { unsafe { - let slice = mem::transmute::<&'a [T], raw::Slice>(self); + let slice = mem::transmute::<&'a [T], raw::Slice>(self.0); let is_zero_size = mem::size_of::() == 0; @@ -26,11 +42,11 @@ impl<'a, T> IntrusiveIterator<&'a T> for &'a [T] { } } -impl<'a, T> IntrusiveIterator<&'a mut T> for &'a mut [T] { +impl<'a, T> IntrusiveIterator<&'a mut T> for ItemsMut<'a, T> { #[inline] fn traverse bool>(self, mut f: F) { unsafe { - let slice = mem::transmute::<&'a mut [T], raw::Slice>(self); + let slice = mem::transmute::<&'a mut [T], raw::Slice>(self.0); let is_zero_size = mem::size_of::() == 0; @@ -51,14 +67,6 @@ impl<'a, T> IntrusiveIterator<&'a mut T> for &'a mut [T] { } } -impl FromIntrusiveIterator for Vec { - fn collect>(iter: I) -> Vec { - let mut vec = Vec::new(); - iter.iterate(|&mut: elem| vec.push(elem)); - vec - } -} - #[cfg(test)] mod test { pub use super::*; @@ -67,13 +75,13 @@ mod test { describe! intrusive_slice_iter { it "should yield all elements of a slice in order" { let data = [1u, 2, 5, 4, 6, 7]; - let intrusive: Vec = data.as_slice().map(|&x| x).collect(); + let intrusive: Vec = data.intrusive_iter().map(|&x| x).collect(); assert_eq!(&*intrusive, data.as_slice()); } it "should work with zero-sized types" { let data = [(), (), ()]; - let intrusive: Vec<()> = data.as_slice().map(|&x| x).collect(); + let intrusive: Vec<()> = data.intrusive_iter().map(|&x| x).collect(); assert_eq!(&*intrusive, data.as_slice()); } @@ -82,7 +90,7 @@ mod test { let data = Vec::from_fn(10000, |_| random::()); bench.iter(|| { - data.as_slice().iterate(|&: x| ::test::black_box(x)); + data.intrusive_iter().iterate(|&: x| ::test::black_box(x)); }); } diff --git a/src/impls/vec.rs b/src/impls/vec.rs new file mode 100644 index 0000000..b430f66 --- /dev/null +++ b/src/impls/vec.rs @@ -0,0 +1,10 @@ +use {IntrusiveIterator, FromIntrusiveIterator}; + +impl FromIntrusiveIterator for Vec { + fn collect>(iter: I) -> Vec { + let mut vec = Vec::new(); + iter.iterate(|&mut: elem| vec.push(elem)); + vec + } +} + diff --git a/src/lib.rs b/src/lib.rs index a981eb3..b920d01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,9 @@ extern crate stainless; #[cfg(test)] extern crate test; +pub use self::impls::slice; +pub mod utils; + /// Intrusive Iterators. pub trait IntrusiveIterator { /// Run this Iterator using the provided closure. @@ -180,4 +183,4 @@ pub struct Cloned { mod ext; mod impls; -pub mod utils; +