1 
2 use std::mem::size_of;
3 use std::marker::PhantomData;
4 
5 /// Slice (contiguous data) iterator.
6 ///
7 /// Iterator element type is `T` (by value).
8 /// This iterator exists mainly to have the constructor from a pair
9 /// of raw pointers available, which the libcore slice iterator does not allow.
10 ///
11 /// Implementation note: Aliasing/optimization issues disappear if we use
12 /// non-pointer iterator element type, so we use `T`. (The libcore slice
13 /// iterator has `assume` and other tools available to combat it).
14 ///
15 /// `T` must not be a zero sized type.
16 #[derive(Debug)]
17 pub struct SliceCopyIter<'a, T: 'a> {
18     ptr: *const T,
19     end: *const T,
20     ty: PhantomData<&'a T>,
21 }
22 
23 impl<'a, T> Copy for SliceCopyIter<'a, T> { }
24 impl<'a, T> Clone for SliceCopyIter<'a, T> {
clone(&self) -> Self25     fn clone(&self) -> Self { *self }
26 }
27 
28 impl<'a, T> SliceCopyIter<'a, T>
29     where T: Copy
30 {
31     #[inline]
new(ptr: *const T, end: *const T) -> Self32     pub unsafe fn new(ptr: *const T, end: *const T) -> Self {
33         assert!(size_of::<T>() != 0);
34         SliceCopyIter {
35             ptr: ptr,
36             end: end,
37             ty: PhantomData,
38         }
39     }
40 
41     /// Return the start, end pointer of the iterator
into_raw(self) -> (*const T, *const T)42     pub fn into_raw(self) -> (*const T, *const T) {
43         (self.ptr, self.end)
44     }
45 }
46 
47 impl<'a, T> Iterator for SliceCopyIter<'a, T>
48     where T: Copy,
49 {
50     type Item = T;
51     #[inline]
next(&mut self) -> Option<Self::Item>52     fn next(&mut self) -> Option<Self::Item> {
53         if self.ptr != self.end {
54             unsafe {
55                 let elt = Some(*self.ptr);
56                 self.ptr = self.ptr.offset(1);
57                 elt
58             }
59         } else {
60             None
61         }
62     }
63 
size_hint(&self) -> (usize, Option<usize>)64     fn size_hint(&self) -> (usize, Option<usize>) {
65         let len = (self.end as usize - self.ptr as usize) / size_of::<T>();
66         (len, Some(len))
67     }
68 
count(self) -> usize69     fn count(self) -> usize {
70         self.len()
71     }
72 
last(mut self) -> Option<Self::Item>73     fn last(mut self) -> Option<Self::Item> {
74         self.next_back()
75     }
76 }
77 
78 impl<'a, T> DoubleEndedIterator for SliceCopyIter<'a, T>
79     where T: Copy
80 {
81     #[inline]
next_back(&mut self) -> Option<Self::Item>82     fn next_back(&mut self) -> Option<Self::Item> {
83         if self.ptr != self.end {
84             unsafe {
85                 self.end = self.end.offset(-1);
86                 let elt = Some(*self.end);
87                 elt
88             }
89         } else {
90             None
91         }
92     }
93 }
94 
95 impl<'a, T> ExactSizeIterator for SliceCopyIter<'a, T> where T: Copy { }
96 
97 impl<'a, T> From<&'a [T]> for SliceCopyIter<'a, T>
98     where T: Copy
99 {
from(slice: &'a [T]) -> Self100     fn from(slice: &'a [T]) -> Self {
101         assert!(size_of::<T>() != 0);
102         unsafe {
103             let ptr = slice.as_ptr();
104             let end = ptr.offset(slice.len() as isize);
105             SliceCopyIter::new(ptr, end)
106         }
107     }
108 }
109 
110 impl<'a, T> Default for SliceCopyIter<'a, T>
111     where T: Copy
112 {
113     /// Create an empty `SliceCopyIter`.
default() -> Self114     fn default() -> Self {
115         unsafe {
116             SliceCopyIter::new(0x1 as *const T, 0x1 as *const T)
117         }
118     }
119 }
120