mirror of
https://github.com/rust-lang/rust.git
synced 2026-06-01 22:18:23 +03:00
rollup merge of #16993 : dschatzberg/items-bounds
This commit is contained in:
@@ -46,12 +46,12 @@ struct AbsEntries<T> {
|
||||
}
|
||||
|
||||
/// An iterator over a BTreeMap's entries.
|
||||
pub struct Entries<'a, K, V> {
|
||||
pub struct Entries<'a, K: 'a, V: 'a> {
|
||||
inner: AbsEntries<Traversal<'a, K, V>>
|
||||
}
|
||||
|
||||
/// A mutable iterator over a BTreeMap's entries.
|
||||
pub struct MutEntries<'a, K, V> {
|
||||
pub struct MutEntries<'a, K: 'a, V: 'a> {
|
||||
inner: AbsEntries<MutTraversal<'a, K, V>>
|
||||
}
|
||||
|
||||
|
||||
+77
-15
@@ -791,11 +791,16 @@ pub fn move_iter(self) -> MoveItems<T> {
|
||||
#[inline]
|
||||
pub fn into_iter(self) -> MoveItems<T> {
|
||||
unsafe {
|
||||
let iter = mem::transmute(self.as_slice().iter());
|
||||
let ptr = self.ptr;
|
||||
let cap = self.cap;
|
||||
let begin = self.ptr as *const T;
|
||||
let end = if mem::size_of::<T>() == 0 {
|
||||
(ptr as uint + self.len()) as *const T
|
||||
} else {
|
||||
ptr.offset(self.len() as int) as *const T
|
||||
};
|
||||
mem::forget(self);
|
||||
MoveItems { allocation: ptr, cap: cap, iter: iter }
|
||||
MoveItems { allocation: ptr, cap: cap, ptr: begin, end: end }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1719,7 +1724,8 @@ fn pop(&mut self) -> Option<T> {
|
||||
pub struct MoveItems<T> {
|
||||
allocation: *mut T, // the block of memory allocated for the vector
|
||||
cap: uint, // the capacity of the vector
|
||||
iter: Items<'static, T>
|
||||
ptr: *const T,
|
||||
end: *const T
|
||||
}
|
||||
|
||||
impl<T> MoveItems<T> {
|
||||
@@ -1728,7 +1734,7 @@ impl<T> MoveItems<T> {
|
||||
pub fn unwrap(mut self) -> Vec<T> {
|
||||
unsafe {
|
||||
for _x in self { }
|
||||
let MoveItems { allocation, cap, iter: _iter } = self;
|
||||
let MoveItems { allocation, cap, ptr: _ptr, end: _end } = self;
|
||||
mem::forget(self);
|
||||
Vec { ptr: allocation, cap: cap, len: 0 }
|
||||
}
|
||||
@@ -1739,17 +1745,33 @@ impl<T> Iterator<T> for MoveItems<T> {
|
||||
#[inline]
|
||||
fn next<'a>(&'a mut self) -> Option<T> {
|
||||
unsafe {
|
||||
// Unsafely transmute from Items<'static, T> to Items<'a,
|
||||
// T> because otherwise the type checker requires that T
|
||||
// be bounded by 'static.
|
||||
let iter: &mut Items<'a, T> = mem::transmute(&mut self.iter);
|
||||
iter.next().map(|x| ptr::read(x))
|
||||
if self.ptr == self.end {
|
||||
None
|
||||
} else {
|
||||
if mem::size_of::<T>() == 0 {
|
||||
// purposefully don't use 'ptr.offset' because for
|
||||
// vectors with 0-size elements this would return the
|
||||
// same pointer.
|
||||
self.ptr = mem::transmute(self.ptr as uint + 1);
|
||||
|
||||
// Use a non-null pointer value
|
||||
Some(ptr::read(mem::transmute(1u)))
|
||||
} else {
|
||||
let old = self.ptr;
|
||||
self.ptr = self.ptr.offset(1);
|
||||
|
||||
Some(ptr::read(old))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
self.iter.size_hint()
|
||||
let diff = (self.end as uint) - (self.ptr as uint);
|
||||
let size = mem::size_of::<T>();
|
||||
let exact = diff / (if size == 0 {1} else {size});
|
||||
(exact, Some(exact))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1757,11 +1779,21 @@ impl<T> DoubleEndedIterator<T> for MoveItems<T> {
|
||||
#[inline]
|
||||
fn next_back<'a>(&'a mut self) -> Option<T> {
|
||||
unsafe {
|
||||
// Unsafely transmute from Items<'static, T> to Items<'a,
|
||||
// T> because otherwise the type checker requires that T
|
||||
// be bounded by 'static.
|
||||
let iter: &mut Items<'a, T> = mem::transmute(&mut self.iter);
|
||||
iter.next_back().map(|x| ptr::read(x))
|
||||
if self.end == self.ptr {
|
||||
None
|
||||
} else {
|
||||
if mem::size_of::<T>() == 0 {
|
||||
// See above for why 'ptr.offset' isn't used
|
||||
self.end = mem::transmute(self.end as uint - 1);
|
||||
|
||||
// Use a non-null pointer value
|
||||
Some(ptr::read(mem::transmute(1u)))
|
||||
} else {
|
||||
self.end = self.end.offset(-1);
|
||||
|
||||
Some(ptr::read(mem::transmute(self.end)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2473,6 +2505,36 @@ fn test_map_in_place_zero_sized() {
|
||||
assert_eq!(v.map_in_place(|_| ZeroSized).as_slice(), [ZeroSized, ZeroSized].as_slice());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_move_items() {
|
||||
let mut vec = vec!(1i, 2, 3);
|
||||
let mut vec2 : Vec<int> = vec!();
|
||||
for i in vec.into_iter() {
|
||||
vec2.push(i);
|
||||
}
|
||||
assert!(vec2 == vec!(1i, 2, 3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_move_items_reverse() {
|
||||
let mut vec = vec!(1i, 2, 3);
|
||||
let mut vec2 : Vec<int> = vec!();
|
||||
for i in vec.into_iter().rev() {
|
||||
vec2.push(i);
|
||||
}
|
||||
assert!(vec2 == vec!(3i, 2, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_move_items_zero_sized() {
|
||||
let mut vec = vec!((), (), ());
|
||||
let mut vec2 : Vec<()> = vec!();
|
||||
for i in vec.into_iter() {
|
||||
vec2.push(i);
|
||||
}
|
||||
assert!(vec2 == vec!((), (), ()));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_new(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
|
||||
@@ -1218,7 +1218,7 @@ fn next_back(&mut self) -> Option<$elem> {
|
||||
|
||||
/// Immutable slice iterator
|
||||
#[experimental = "needs review"]
|
||||
pub struct Items<'a, T> {
|
||||
pub struct Items<'a, T: 'a> {
|
||||
ptr: *const T,
|
||||
end: *const T,
|
||||
marker: marker::ContravariantLifetime<'a>
|
||||
@@ -1261,7 +1261,7 @@ fn idx(&mut self, index: uint) -> Option<&'a T> {
|
||||
|
||||
/// Mutable slice iterator.
|
||||
#[experimental = "needs review"]
|
||||
pub struct MutItems<'a, T> {
|
||||
pub struct MutItems<'a, T: 'a> {
|
||||
ptr: *mut T,
|
||||
end: *mut T,
|
||||
marker: marker::ContravariantLifetime<'a>,
|
||||
|
||||
Reference in New Issue
Block a user