Skip to content

Commit ce44094

Browse files
committed
Add [mut_]shift_ref/[mut_]pop_ref functions, which return a pointer to the first/last item in the slice and modify the slice to exclude the returned item. Useful when writing iterators over mutable references.
1 parent 4043951 commit ce44094

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

src/libstd/vec.rs

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,40 @@ pub trait ImmutableVector<'self, T> {
975975
* foreign interop.
976976
*/
977977
fn as_imm_buf<U>(&self, f: |*T, uint| -> U) -> U;
978+
979+
/**
980+
* Returns a mutable reference to the first element in this slice
981+
* and adjusts the slice in place so that it no longer contains
982+
* that element. O(1).
983+
*
984+
* Equivalent to:
985+
*
986+
* ```
987+
* let head = &self[0];
988+
* *self = self.slice_from(1);
989+
* head
990+
* ```
991+
*
992+
* Fails if slice is empty.
993+
*/
994+
fn shift_ref(&mut self) -> &'self T;
995+
996+
/**
997+
* Returns a mutable reference to the last element in this slice
998+
* and adjusts the slice in place so that it no longer contains
999+
* that element. O(1).
1000+
*
1001+
* Equivalent to:
1002+
*
1003+
* ```
1004+
* let tail = &self[self.len() - 1];
1005+
* *self = self.slice_to(self.len() - 1);
1006+
* tail
1007+
* ```
1008+
*
1009+
* Fails if slice is empty.
1010+
*/
1011+
fn pop_ref(&mut self) -> &'self T;
9781012
}
9791013

9801014
impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
@@ -1141,6 +1175,20 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
11411175
let s = self.repr();
11421176
f(s.data, s.len)
11431177
}
1178+
1179+
fn shift_ref(&mut self) -> &'self T {
1180+
unsafe {
1181+
let s: &mut Slice<T> = cast::transmute(self);
1182+
&*raw::shift_ptr(s)
1183+
}
1184+
}
1185+
1186+
fn pop_ref(&mut self) -> &'self T {
1187+
unsafe {
1188+
let s: &mut Slice<T> = cast::transmute(self);
1189+
&*raw::pop_ptr(s)
1190+
}
1191+
}
11441192
}
11451193

11461194
/// Extension methods for vectors contain `Eq` elements.
@@ -1859,23 +1907,61 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
18591907
pub trait MutableVector<'self, T> {
18601908
/// Return a slice that points into another slice.
18611909
fn mut_slice(self, start: uint, end: uint) -> &'self mut [T];
1910+
18621911
/**
18631912
* Returns a slice of self from `start` to the end of the vec.
18641913
*
18651914
* Fails when `start` points outside the bounds of self.
18661915
*/
18671916
fn mut_slice_from(self, start: uint) -> &'self mut [T];
1917+
18681918
/**
18691919
* Returns a slice of self from the start of the vec to `end`.
18701920
*
18711921
* Fails when `end` points outside the bounds of self.
18721922
*/
18731923
fn mut_slice_to(self, end: uint) -> &'self mut [T];
1924+
18741925
/// Returns an iterator that allows modifying each value
18751926
fn mut_iter(self) -> VecMutIterator<'self, T>;
1927+
18761928
/// Returns a reversed iterator that allows modifying each value
18771929
fn mut_rev_iter(self) -> MutRevIterator<'self, T>;
18781930

1931+
/**
1932+
* Returns a mutable reference to the first element in this slice
1933+
* and adjusts the slice in place so that it no longer contains
1934+
* that element. O(1).
1935+
*
1936+
* Equivalent to:
1937+
*
1938+
* ```
1939+
* let head = &mut self[0];
1940+
* *self = self.mut_slice_from(1);
1941+
* head
1942+
* ```
1943+
*
1944+
* Fails if slice is empty.
1945+
*/
1946+
fn mut_shift_ref(&mut self) -> &'self mut T;
1947+
1948+
/**
1949+
* Returns a mutable reference to the last element in this slice
1950+
* and adjusts the slice in place so that it no longer contains
1951+
* that element. O(1).
1952+
*
1953+
* Equivalent to:
1954+
*
1955+
* ```
1956+
* let tail = &mut self[self.len() - 1];
1957+
* *self = self.mut_slice_to(self.len() - 1);
1958+
* tail
1959+
* ```
1960+
*
1961+
* Fails if slice is empty.
1962+
*/
1963+
fn mut_pop_ref(&mut self) -> &'self mut T;
1964+
18791965
/**
18801966
* Swaps two elements in a vector
18811967
*
@@ -1978,6 +2064,20 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
19782064
self.mut_iter().invert()
19792065
}
19802066

2067+
fn mut_shift_ref(&mut self) -> &'self mut T {
2068+
unsafe {
2069+
let s: &mut Slice<T> = cast::transmute(self);
2070+
cast::transmute_mut(&*raw::shift_ptr(s))
2071+
}
2072+
}
2073+
2074+
fn mut_pop_ref(&mut self) -> &'self mut T {
2075+
unsafe {
2076+
let s: &mut Slice<T> = cast::transmute(self);
2077+
cast::transmute_mut(&*raw::pop_ptr(s))
2078+
}
2079+
}
2080+
19812081
fn swap(self, a: uint, b: uint) {
19822082
unsafe {
19832083
// Can't take two mutable loans from one vector, so instead just cast
@@ -2189,6 +2289,31 @@ pub mod raw {
21892289
}
21902290
}
21912291
}
2292+
2293+
/**
2294+
* Returns a pointer to first element in slice and adjusts
2295+
* slice so it no longer contains that element. Fails if
2296+
* slice is empty. O(1).
2297+
*/
2298+
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> *T {
2299+
if slice.len == 0 { fail!("shift on empty slice"); }
2300+
let head: *T = slice.data;
2301+
slice.data = ptr::offset(slice.data, 1);
2302+
slice.len -= 1;
2303+
head
2304+
}
2305+
2306+
/**
2307+
* Returns a pointer to last element in slice and adjusts
2308+
* slice so it no longer contains that element. Fails if
2309+
* slice is empty. O(1).
2310+
*/
2311+
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> *T {
2312+
if slice.len == 0 { fail!("pop on empty slice"); }
2313+
let tail: *T = ptr::offset(slice.data, (slice.len - 1) as int);
2314+
slice.len -= 1;
2315+
tail
2316+
}
21922317
}
21932318

21942319
/// Operations on `[u8]`
@@ -3822,6 +3947,75 @@ mod tests {
38223947
assert!(!empty.ends_with(bytes!("foo")));
38233948
assert!(bytes!("foobar").ends_with(empty));
38243949
}
3950+
3951+
#[test]
3952+
fn test_shift_ref() {
3953+
let mut x: &[int] = [1, 2, 3, 4, 5];
3954+
let h = x.shift_ref();
3955+
assert_eq!(*h, 1);
3956+
assert_eq!(x.len(), 4);
3957+
assert_eq!(x[0], 2);
3958+
assert_eq!(x[3], 5);
3959+
}
3960+
3961+
#[test]
3962+
#[should_fail]
3963+
fn test_shift_ref_empty() {
3964+
let mut x: &[int] = [];
3965+
x.shift_ref();
3966+
}
3967+
3968+
#[test]
3969+
fn test_pop_ref() {
3970+
let mut x: &[int] = [1, 2, 3, 4, 5];
3971+
let h = x.pop_ref();
3972+
assert_eq!(*h, 5);
3973+
assert_eq!(x.len(), 4);
3974+
assert_eq!(x[0], 1);
3975+
assert_eq!(x[3], 4);
3976+
}
3977+
3978+
#[test]
3979+
#[should_fail]
3980+
fn test_pop_ref_empty() {
3981+
let mut x: &[int] = [];
3982+
x.pop_ref();
3983+
}
3984+
3985+
3986+
#[test]
3987+
fn test_mut_shift_ref() {
3988+
let mut x: &mut [int] = [1, 2, 3, 4, 5];
3989+
let h = x.mut_shift_ref();
3990+
assert_eq!(*h, 1);
3991+
assert_eq!(x.len(), 4);
3992+
assert_eq!(x[0], 2);
3993+
assert_eq!(x[3], 5);
3994+
}
3995+
3996+
#[test]
3997+
#[should_fail]
3998+
fn test_mut_shift_ref_empty() {
3999+
let mut x: &mut [int] = [];
4000+
x.mut_shift_ref();
4001+
}
4002+
4003+
#[test]
4004+
fn test_mut_pop_ref() {
4005+
let mut x: &mut [int] = [1, 2, 3, 4, 5];
4006+
let h = x.mut_pop_ref();
4007+
assert_eq!(*h, 5);
4008+
assert_eq!(x.len(), 4);
4009+
assert_eq!(x[0], 1);
4010+
assert_eq!(x[3], 4);
4011+
}
4012+
4013+
#[test]
4014+
#[should_fail]
4015+
fn test_mut_pop_ref_empty() {
4016+
let mut x: &mut [int] = [];
4017+
x.mut_pop_ref();
4018+
}
38254019
}
38264020

38274021
#[cfg(test)]

0 commit comments

Comments
 (0)