2014-01-25 01:37:51 -06:00
|
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
2013-06-18 20:22:48 -05:00
|
|
|
|
/*!
|
|
|
|
|
|
2013-12-24 10:08:28 -06:00
|
|
|
|
Utilities for vector manipulation
|
2013-09-17 21:42:07 -05:00
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
The `vec` module contains useful code to help work with vector values.
|
|
|
|
|
Vectors are Rust's list type. Vectors contain zero or more values of
|
|
|
|
|
homogeneous types:
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```rust
|
2013-06-18 20:22:48 -05:00
|
|
|
|
let int_vector = [1,2,3];
|
|
|
|
|
let str_vector = ["one", "two", "three"];
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
|
|
|
|
This is a big module, but for a high-level overview:
|
|
|
|
|
|
|
|
|
|
## Structs
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
Several structs that are useful for vectors, such as `Items`, which
|
2013-06-18 20:22:48 -05:00
|
|
|
|
represents iteration over a vector.
|
|
|
|
|
|
|
|
|
|
## Traits
|
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
A number of traits add methods that allow you to accomplish tasks with vectors.
|
|
|
|
|
|
|
|
|
|
Traits defined for the `&[T]` type (a vector slice), have methods that can be
|
|
|
|
|
called on either owned vectors, denoted `~[T]`, or on vector slices themselves.
|
|
|
|
|
These traits include `ImmutableVector`, and `MutableVector` for the `&mut [T]`
|
|
|
|
|
case.
|
|
|
|
|
|
|
|
|
|
An example is the method `.slice(a, b)` that returns an immutable "view" into
|
|
|
|
|
a vector or a vector slice from the index interval `[a, b)`:
|
|
|
|
|
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```rust
|
2013-09-09 11:32:35 -05:00
|
|
|
|
let numbers = [0, 1, 2];
|
|
|
|
|
let last_numbers = numbers.slice(1, 3);
|
|
|
|
|
// last_numbers is now &[1, 2]
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```
|
2013-09-09 11:32:35 -05:00
|
|
|
|
|
|
|
|
|
Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
|
|
|
|
|
on such vectors. These methods deal with adding elements or otherwise changing
|
|
|
|
|
the allocation of the vector.
|
|
|
|
|
|
|
|
|
|
An example is the method `.push(element)` that will add an element at the end
|
|
|
|
|
of the vector:
|
|
|
|
|
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```rust
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut numbers = vec![0, 1, 2];
|
2013-09-09 11:32:35 -05:00
|
|
|
|
numbers.push(7);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
// numbers is now vec![0, 1, 2, 7];
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
|
|
|
|
## Implementations of other traits
|
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
Vectors are a very useful type, and so there's several implementations of
|
|
|
|
|
traits from other modules. Some notable examples:
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
|
|
|
|
* `Clone`
|
2013-09-09 11:32:35 -05:00
|
|
|
|
* `Eq`, `Ord`, `TotalEq`, `TotalOrd` -- vectors can be compared,
|
|
|
|
|
if the element type defines the corresponding trait.
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
## Iteration
|
|
|
|
|
|
|
|
|
|
The method `iter()` returns an iteration value for a vector or a vector slice.
|
2014-01-07 20:49:13 -06:00
|
|
|
|
The iterator yields references to the vector's elements, so if the element
|
2013-09-09 11:32:35 -05:00
|
|
|
|
type of the vector is `int`, the element type of the iterator is `&int`.
|
|
|
|
|
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```rust
|
2013-09-09 11:32:35 -05:00
|
|
|
|
let numbers = [0, 1, 2];
|
|
|
|
|
for &x in numbers.iter() {
|
|
|
|
|
println!("{} is a number!", x);
|
|
|
|
|
}
|
2013-09-23 19:20:36 -05:00
|
|
|
|
```
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
* `.mut_iter()` returns an iterator that allows modifying each value.
|
|
|
|
|
* `.move_iter()` converts an owned vector into an iterator that
|
|
|
|
|
moves out a value from the vector each iteration.
|
|
|
|
|
* Further iterators exist that split, chunk or permute the vector.
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
## Function definitions
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
There are a number of free functions that create or take vectors, for example:
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
2013-09-09 11:32:35 -05:00
|
|
|
|
* Creating a vector, like `from_elem` and `from_fn`
|
|
|
|
|
* Creating a vector with a given size: `with_capacity`
|
|
|
|
|
* Modifying a vector and returning it, like `append`
|
|
|
|
|
* Operations on paired elements, like `unzip`.
|
2013-06-18 20:22:48 -05:00
|
|
|
|
|
|
|
|
|
*/
|
2012-03-15 20:58:14 -05:00
|
|
|
|
|
2012-12-23 16:41:37 -06:00
|
|
|
|
use cast;
|
2014-02-14 17:42:01 -06:00
|
|
|
|
use cast::transmute;
|
2013-12-16 04:26:25 -06:00
|
|
|
|
use ops::Drop;
|
2014-03-05 00:19:14 -06:00
|
|
|
|
use clone::Clone;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use container::Container;
|
2013-07-17 14:32:49 -05:00
|
|
|
|
use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
|
2013-07-02 14:47:32 -05:00
|
|
|
|
use cmp;
|
2013-09-09 21:32:56 -05:00
|
|
|
|
use default::Default;
|
2014-02-14 12:03:53 -06:00
|
|
|
|
use fmt;
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use num::{CheckedAdd, Saturating, div_rem};
|
|
|
|
|
use num::CheckedMul;
|
2013-01-08 21:37:25 -06:00
|
|
|
|
use option::{None, Option, Some};
|
2012-12-23 16:41:37 -06:00
|
|
|
|
use ptr;
|
2013-06-03 12:50:29 -05:00
|
|
|
|
use ptr::RawPtr;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use rt::global_heap::{malloc_raw, exchange_free};
|
2014-02-14 12:03:53 -06:00
|
|
|
|
use result::{Ok, Err};
|
2013-10-16 20:34:01 -05:00
|
|
|
|
use mem;
|
|
|
|
|
use mem::size_of;
|
2014-01-22 13:03:02 -06:00
|
|
|
|
use kinds::marker;
|
2014-02-07 05:33:11 -06:00
|
|
|
|
use unstable::finally::try_finally;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use raw::{Repr, Slice};
|
|
|
|
|
use RawVec = raw::Vec;
|
|
|
|
|
use vec::Vec;
|
2012-07-17 18:31:19 -05:00
|
|
|
|
|
2014-01-15 13:39:08 -06:00
|
|
|
|
/**
|
|
|
|
|
* Converts a pointer to A into a slice of length 1 (without copying).
|
|
|
|
|
*/
|
|
|
|
|
pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
|
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute(Slice { data: s, len: 1 })
|
2014-01-15 13:39:08 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts a pointer to A into a slice of length 1 (without copying).
|
|
|
|
|
*/
|
|
|
|
|
pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
|
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
let ptr: *A = transmute(s);
|
|
|
|
|
transmute(Slice { data: ptr, len: 1 })
|
2014-01-15 13:39:08 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-02 23:54:11 -05:00
|
|
|
|
/// An iterator over the slices of a vector separated by elements that
|
|
|
|
|
/// match a predicate function.
|
2014-01-14 21:32:24 -06:00
|
|
|
|
pub struct Splits<'a, T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
v: &'a [T],
|
2014-04-07 15:30:48 -05:00
|
|
|
|
pred: |t: &T|: 'a -> bool,
|
2014-03-27 17:09:47 -05:00
|
|
|
|
finished: bool
|
2013-07-02 23:54:11 -05:00
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
if self.finished { return None; }
|
2013-01-29 00:44:59 -06:00
|
|
|
|
|
2013-07-04 21:13:26 -05:00
|
|
|
|
match self.v.iter().position(|x| (self.pred)(x)) {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
None => {
|
|
|
|
|
self.finished = true;
|
|
|
|
|
Some(self.v)
|
|
|
|
|
}
|
|
|
|
|
Some(idx) => {
|
|
|
|
|
let ret = Some(self.v.slice(0, idx));
|
|
|
|
|
self.v = self.v.slice(idx + 1, self.v.len());
|
|
|
|
|
ret
|
2012-09-26 19:33:34 -05:00
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-08-05 21:20:37 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
|
if self.finished {
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
(0, Some(0))
|
|
|
|
|
} else {
|
|
|
|
|
(1, Some(self.v.len() + 1))
|
2013-08-05 21:20:37 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
|
}
|
|
|
|
|
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
impl<'a, T> DoubleEndedIterator<&'a [T]> for Splits<'a, T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
fn next_back(&mut self) -> Option<&'a [T]> {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
if self.finished { return None; }
|
2012-01-26 20:13:43 -06:00
|
|
|
|
|
2014-04-22 01:25:18 -05:00
|
|
|
|
match self.v.iter().rposition(|x| (self.pred)(x)) {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
None => {
|
|
|
|
|
self.finished = true;
|
|
|
|
|
Some(self.v)
|
|
|
|
|
}
|
|
|
|
|
Some(idx) => {
|
|
|
|
|
let ret = Some(self.v.slice(idx + 1, self.v.len()));
|
|
|
|
|
self.v = self.v.slice(0, idx);
|
|
|
|
|
ret
|
2012-09-26 19:33:34 -05:00
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
}
|
2013-08-05 21:20:37 -05:00
|
|
|
|
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
/// An iterator over the slices of a vector separated by elements that
|
|
|
|
|
/// match a predicate function, splitting at most a fixed number of times.
|
|
|
|
|
pub struct SplitsN<'a, T> {
|
|
|
|
|
iter: Splits<'a, T>,
|
|
|
|
|
count: uint,
|
|
|
|
|
invert: bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T> Iterator<&'a [T]> for SplitsN<'a, T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
|
|
|
|
if self.count == 0 {
|
|
|
|
|
if self.iter.finished {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
self.iter.finished = true;
|
|
|
|
|
Some(self.iter.v)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
self.count -= 1;
|
|
|
|
|
if self.invert { self.iter.next_back() } else { self.iter.next() }
|
2013-08-05 21:20:37 -05:00
|
|
|
|
}
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
|
if self.iter.finished {
|
|
|
|
|
(0, Some(0))
|
|
|
|
|
} else {
|
|
|
|
|
(1, Some(cmp::min(self.count, self.iter.v.len()) + 1))
|
2013-08-05 21:20:37 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-01-26 20:13:43 -06:00
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
|
|
|
|
|
// Functional utilities
|
|
|
|
|
|
2013-06-02 22:19:37 -05:00
|
|
|
|
#[allow(missing_doc)]
|
|
|
|
|
pub trait VectorVector<T> {
|
2013-06-14 21:56:41 -05:00
|
|
|
|
// FIXME #5898: calling these .concat and .connect conflicts with
|
|
|
|
|
// StrVector::con{cat,nect}, since they have generic contents.
|
2013-09-27 21:15:40 -05:00
|
|
|
|
/// Flattens a vector of vectors of T into a single vector of T.
|
2013-08-09 03:25:24 -05:00
|
|
|
|
fn concat_vec(&self) -> ~[T];
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
|
|
|
|
/// Concatenate a vector of vectors, placing a given separator between each.
|
2013-09-27 21:15:40 -05:00
|
|
|
|
fn connect_vec(&self, sep: &T) -> ~[T];
|
2013-06-02 22:19:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
|
2013-08-09 03:25:24 -05:00
|
|
|
|
fn concat_vec(&self) -> ~[T] {
|
2013-09-27 21:15:40 -05:00
|
|
|
|
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut result = Vec::with_capacity(size);
|
2013-09-27 21:15:40 -05:00
|
|
|
|
for v in self.iter() {
|
|
|
|
|
result.push_all(v.as_slice())
|
|
|
|
|
}
|
2014-04-17 17:28:14 -05:00
|
|
|
|
result.move_iter().collect()
|
2013-06-02 22:19:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-09 03:25:24 -05:00
|
|
|
|
fn connect_vec(&self, sep: &T) -> ~[T] {
|
2013-09-27 21:15:40 -05:00
|
|
|
|
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut result = Vec::with_capacity(size + self.len());
|
2013-06-02 22:19:37 -05:00
|
|
|
|
let mut first = true;
|
2013-09-27 21:15:40 -05:00
|
|
|
|
for v in self.iter() {
|
|
|
|
|
if first { first = false } else { result.push(sep.clone()) }
|
|
|
|
|
result.push_all(v.as_slice())
|
2013-06-02 22:19:37 -05:00
|
|
|
|
}
|
2014-04-17 17:28:14 -05:00
|
|
|
|
result.move_iter().collect()
|
2012-01-28 17:41:53 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
|
/**
|
2013-09-08 21:46:32 -05:00
|
|
|
|
* Convert an iterator of pairs into a pair of vectors.
|
2012-07-04 16:53:12 -05:00
|
|
|
|
*
|
2012-08-23 19:51:34 -05:00
|
|
|
|
* Returns a tuple containing two vectors where the i-th element of the first
|
2013-09-08 21:46:32 -05:00
|
|
|
|
* vector contains the first element of the i-th tuple of the input iterator,
|
2012-08-23 19:51:34 -05:00
|
|
|
|
* and the i-th element of the second vector contains the second element
|
2013-09-08 21:46:32 -05:00
|
|
|
|
* of the i-th tuple of the input iterator.
|
2012-08-23 19:51:34 -05:00
|
|
|
|
*/
|
2013-09-08 21:46:32 -05:00
|
|
|
|
pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (~[T], ~[U]) {
|
|
|
|
|
let (lo, _) = iter.size_hint();
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut ts = Vec::with_capacity(lo);
|
|
|
|
|
let mut us = Vec::with_capacity(lo);
|
2013-09-08 21:46:32 -05:00
|
|
|
|
for (t, u) in iter {
|
2013-04-08 15:50:34 -05:00
|
|
|
|
ts.push(t);
|
|
|
|
|
us.push(u);
|
2012-08-23 19:51:34 -05:00
|
|
|
|
}
|
2014-04-17 17:28:14 -05:00
|
|
|
|
(ts.move_iter().collect(), us.move_iter().collect())
|
2012-08-23 19:51:34 -05:00
|
|
|
|
}
|
|
|
|
|
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
/// An Iterator that yields the element swaps needed to produce
|
|
|
|
|
/// a sequence of all possible permutations for an indexed sequence of
|
|
|
|
|
/// elements. Each permutation is only a single swap apart.
|
|
|
|
|
///
|
|
|
|
|
/// The Steinhaus–Johnson–Trotter algorithm is used.
|
|
|
|
|
///
|
2013-12-14 23:26:09 -06:00
|
|
|
|
/// Generates even and odd permutations alternately.
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
///
|
|
|
|
|
/// The last generated swap is always (0, 1), and it returns the
|
|
|
|
|
/// sequence to its initial order.
|
|
|
|
|
pub struct ElementSwaps {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
sdir: ~[SizeDirection],
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
/// If true, emit the last swap that returns the sequence to initial state
|
2014-03-27 17:09:47 -05:00
|
|
|
|
emit_reset: bool,
|
2014-04-25 15:19:53 -05:00
|
|
|
|
swaps_made : uint,
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ElementSwaps {
|
|
|
|
|
/// Create an `ElementSwaps` iterator for a sequence of `length` elements
|
|
|
|
|
pub fn new(length: uint) -> ElementSwaps {
|
|
|
|
|
// Initialize `sdir` with a direction that position should move in
|
|
|
|
|
// (all negative at the beginning) and the `size` of the
|
|
|
|
|
// element (equal to the original index).
|
|
|
|
|
ElementSwaps{
|
|
|
|
|
emit_reset: true,
|
|
|
|
|
sdir: range(0, length)
|
|
|
|
|
.map(|i| SizeDirection{ size: i, dir: Neg })
|
2014-04-25 15:19:53 -05:00
|
|
|
|
.collect::<~[_]>(),
|
|
|
|
|
swaps_made: 0
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum Direction { Pos, Neg }
|
|
|
|
|
|
|
|
|
|
/// An Index and Direction together
|
|
|
|
|
struct SizeDirection {
|
|
|
|
|
size: uint,
|
|
|
|
|
dir: Direction,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Iterator<(uint, uint)> for ElementSwaps {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn next(&mut self) -> Option<(uint, uint)> {
|
|
|
|
|
fn new_pos(i: uint, s: Direction) -> uint {
|
|
|
|
|
i + match s { Pos => 1, Neg => -1 }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find the index of the largest mobile element:
|
|
|
|
|
// The direction should point into the vector, and the
|
|
|
|
|
// swap should be with a smaller `size` element.
|
|
|
|
|
let max = self.sdir.iter().map(|&x| x).enumerate()
|
|
|
|
|
.filter(|&(i, sd)|
|
|
|
|
|
new_pos(i, sd.dir) < self.sdir.len() &&
|
|
|
|
|
self.sdir[new_pos(i, sd.dir)].size < sd.size)
|
|
|
|
|
.max_by(|&(_, sd)| sd.size);
|
|
|
|
|
match max {
|
|
|
|
|
Some((i, sd)) => {
|
|
|
|
|
let j = new_pos(i, sd.dir);
|
|
|
|
|
self.sdir.swap(i, j);
|
|
|
|
|
|
|
|
|
|
// Swap the direction of each larger SizeDirection
|
|
|
|
|
for x in self.sdir.mut_iter() {
|
|
|
|
|
if x.size > sd.size {
|
|
|
|
|
x.dir = match x.dir { Pos => Neg, Neg => Pos };
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-25 15:19:53 -05:00
|
|
|
|
self.swaps_made += 1;
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
Some((i, j))
|
|
|
|
|
},
|
2014-04-25 15:19:53 -05:00
|
|
|
|
None => if self.emit_reset {
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
self.emit_reset = false;
|
2014-04-25 15:19:53 -05:00
|
|
|
|
if self.sdir.len() > 1 {
|
|
|
|
|
// The last swap
|
|
|
|
|
self.swaps_made += 1;
|
|
|
|
|
Some((0, 1))
|
|
|
|
|
} else {
|
|
|
|
|
// Vector is of the form [] or [x], and the only permutation is itself
|
|
|
|
|
self.swaps_made += 1;
|
|
|
|
|
Some((0,0))
|
|
|
|
|
}
|
|
|
|
|
} else { None }
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-25 15:19:53 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
|
// For a vector of size n, there are exactly n! permutations.
|
|
|
|
|
let n = range(2, self.sdir.len() + 1).product();
|
|
|
|
|
(n - self.swaps_made, Some(n - self.swaps_made))
|
|
|
|
|
}
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An Iterator that uses `ElementSwaps` to iterate through
|
|
|
|
|
/// all possible permutations of a vector.
|
|
|
|
|
///
|
|
|
|
|
/// The first iteration yields a clone of the vector as it is,
|
|
|
|
|
/// then each successive element is the vector with one
|
|
|
|
|
/// swap applied.
|
|
|
|
|
///
|
2013-12-14 23:26:09 -06:00
|
|
|
|
/// Generates even and odd permutations alternately.
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
pub struct Permutations<T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
swaps: ElementSwaps,
|
|
|
|
|
v: ~[T],
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T: Clone> Iterator<~[T]> for Permutations<T> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn next(&mut self) -> Option<~[T]> {
|
|
|
|
|
match self.swaps.next() {
|
|
|
|
|
None => None,
|
2014-04-25 15:19:53 -05:00
|
|
|
|
Some((0,0)) => Some(self.v.clone()),
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
Some((a, b)) => {
|
|
|
|
|
let elt = self.v.clone();
|
|
|
|
|
self.v.swap(a, b);
|
|
|
|
|
Some(elt)
|
|
|
|
|
}
|
2012-06-27 17:21:50 -05:00
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
}
|
2014-04-25 15:19:53 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
|
self.swaps.size_hint()
|
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-03 00:47:58 -05:00
|
|
|
|
/// An iterator over the (overlapping) slices of length `size` within
|
|
|
|
|
/// a vector.
|
2013-08-03 12:40:20 -05:00
|
|
|
|
#[deriving(Clone)]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
pub struct Windows<'a, T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
v: &'a [T],
|
|
|
|
|
size: uint
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
if self.size > self.v.len() {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
let ret = Some(self.v.slice(0, self.size));
|
|
|
|
|
self.v = self.v.slice(1, self.v.len());
|
|
|
|
|
ret
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-08-05 21:20:37 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
|
if self.size > self.v.len() {
|
|
|
|
|
(0, Some(0))
|
|
|
|
|
} else {
|
|
|
|
|
let x = self.v.len() - self.size;
|
|
|
|
|
(x.saturating_add(1), x.checked_add(&1u))
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// An iterator over a vector in (non-overlapping) chunks (`size`
|
|
|
|
|
/// elements at a time).
|
2013-08-03 12:40:20 -05:00
|
|
|
|
///
|
|
|
|
|
/// When the vector len is not evenly divided by the chunk size,
|
2013-08-16 00:41:28 -05:00
|
|
|
|
/// the last slice of the iteration will be the remainder.
|
2013-08-03 12:40:20 -05:00
|
|
|
|
#[deriving(Clone)]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
pub struct Chunks<'a, T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
v: &'a [T],
|
|
|
|
|
size: uint
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> Iterator<&'a [T]> for Chunks<'a, T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
2013-08-03 12:40:20 -05:00
|
|
|
|
if self.v.len() == 0 {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
None
|
|
|
|
|
} else {
|
2013-08-03 12:40:20 -05:00
|
|
|
|
let chunksz = cmp::min(self.v.len(), self.size);
|
|
|
|
|
let (fst, snd) = (self.v.slice_to(chunksz),
|
|
|
|
|
self.v.slice_from(chunksz));
|
|
|
|
|
self.v = snd;
|
|
|
|
|
Some(fst)
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-08-05 21:20:37 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
|
(0, Some(0))
|
|
|
|
|
} else {
|
2014-02-16 14:20:01 -06:00
|
|
|
|
let (n, rem) = div_rem(self.v.len(), self.size);
|
2013-08-05 21:20:37 -05:00
|
|
|
|
let n = if rem > 0 { n+1 } else { n };
|
|
|
|
|
(n, Some(n))
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-08-03 12:40:20 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> DoubleEndedIterator<&'a [T]> for Chunks<'a, T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next_back(&mut self) -> Option<&'a [T]> {
|
2013-08-03 12:40:20 -05:00
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
let remainder = self.v.len() % self.size;
|
|
|
|
|
let chunksz = if remainder != 0 { remainder } else { self.size };
|
|
|
|
|
let (fst, snd) = (self.v.slice_to(self.v.len() - chunksz),
|
|
|
|
|
self.v.slice_from(self.v.len() - chunksz));
|
|
|
|
|
self.v = fst;
|
|
|
|
|
Some(snd)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> {
|
2013-08-03 12:40:20 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn indexable(&self) -> uint {
|
|
|
|
|
self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2014-04-22 00:15:42 -05:00
|
|
|
|
fn idx(&mut self, index: uint) -> Option<&'a [T]> {
|
2013-08-03 12:40:20 -05:00
|
|
|
|
if index < self.indexable() {
|
|
|
|
|
let lo = index * self.size;
|
2013-08-04 15:46:26 -05:00
|
|
|
|
let mut hi = lo + self.size;
|
|
|
|
|
if hi < lo || hi > self.v.len() { hi = self.v.len(); }
|
|
|
|
|
|
|
|
|
|
Some(self.v.slice(lo, hi))
|
2013-08-03 12:40:20 -05:00
|
|
|
|
} else {
|
|
|
|
|
None
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
2013-05-03 15:33:33 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-01-23 04:41:40 -06:00
|
|
|
|
|
2012-08-27 19:15:54 -05:00
|
|
|
|
// Equality
|
|
|
|
|
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[cfg(not(test))]
|
2013-10-12 21:02:46 -05:00
|
|
|
|
#[allow(missing_doc)]
|
2013-07-02 21:13:00 -05:00
|
|
|
|
pub mod traits {
|
2013-08-08 22:49:49 -05:00
|
|
|
|
use super::*;
|
2013-07-02 14:47:32 -05:00
|
|
|
|
|
2014-01-06 18:48:51 -06:00
|
|
|
|
use container::Container;
|
2013-07-02 14:47:32 -05:00
|
|
|
|
use clone::Clone;
|
2013-08-08 15:07:21 -05:00
|
|
|
|
use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equiv};
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use iter::{order, Iterator};
|
2013-07-02 21:13:00 -05:00
|
|
|
|
use ops::Add;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use vec::Vec;
|
2013-07-02 21:13:00 -05:00
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T:Eq> Eq for &'a [T] {
|
|
|
|
|
fn eq(&self, other: & &'a [T]) -> bool {
|
2013-07-02 21:13:00 -05:00
|
|
|
|
self.len() == other.len() &&
|
2013-08-08 15:07:21 -05:00
|
|
|
|
order::eq(self.iter(), other.iter())
|
|
|
|
|
}
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn ne(&self, other: & &'a [T]) -> bool {
|
2013-08-08 16:07:24 -05:00
|
|
|
|
self.len() != other.len() ||
|
2013-08-08 15:07:21 -05:00
|
|
|
|
order::ne(self.iter(), other.iter())
|
2013-07-02 21:13:00 -05:00
|
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-02 21:13:00 -05:00
|
|
|
|
impl<T:Eq> Eq for ~[T] {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
|
2013-03-27 14:20:44 -05:00
|
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
|
2014-03-23 06:54:42 -05:00
|
|
|
|
impl<'a,T:TotalEq> TotalEq for &'a [T] {}
|
2013-03-27 14:20:44 -05:00
|
|
|
|
|
2014-03-23 06:54:42 -05:00
|
|
|
|
impl<T:TotalEq> TotalEq for ~[T] {}
|
2013-03-27 14:20:44 -05:00
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T:Eq, V: Vector<T>> Equiv<V> for &'a [T] {
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
|
|
|
|
|
}
|
2013-03-04 21:43:14 -06:00
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T:Eq, V: Vector<T>> Equiv<V> for ~[T] {
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
|
|
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T:TotalOrd> TotalOrd for &'a [T] {
|
|
|
|
|
fn cmp(&self, other: & &'a [T]) -> Ordering {
|
2013-08-08 15:07:21 -05:00
|
|
|
|
order::cmp(self.iter(), other.iter())
|
2013-03-01 21:07:12 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-02 21:13:00 -05:00
|
|
|
|
impl<T: TotalOrd> TotalOrd for ~[T] {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
|
|
|
|
|
}
|
2013-03-01 21:07:12 -06:00
|
|
|
|
|
2014-02-24 07:11:00 -06:00
|
|
|
|
impl<'a, T: Ord> Ord for &'a [T] {
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn lt(&self, other: & &'a [T]) -> bool {
|
2013-08-08 15:07:21 -05:00
|
|
|
|
order::lt(self.iter(), other.iter())
|
2013-07-02 21:13:00 -05:00
|
|
|
|
}
|
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn le(&self, other: & &'a [T]) -> bool {
|
2013-08-08 15:07:21 -05:00
|
|
|
|
order::le(self.iter(), other.iter())
|
|
|
|
|
}
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn ge(&self, other: & &'a [T]) -> bool {
|
2013-08-08 15:07:21 -05:00
|
|
|
|
order::ge(self.iter(), other.iter())
|
|
|
|
|
}
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn gt(&self, other: & &'a [T]) -> bool {
|
2013-08-08 15:07:21 -05:00
|
|
|
|
order::gt(self.iter(), other.iter())
|
|
|
|
|
}
|
2013-07-02 21:13:00 -05:00
|
|
|
|
}
|
2013-03-01 21:07:12 -06:00
|
|
|
|
|
2014-02-24 07:11:00 -06:00
|
|
|
|
impl<T: Ord> Ord for ~[T] {
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() }
|
|
|
|
|
#[inline]
|
|
|
|
|
fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() }
|
|
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T:Clone, V: Vector<T>> Add<V, ~[T]> for &'a [T] {
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn add(&self, rhs: &V) -> ~[T] {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
|
2013-08-08 22:49:49 -05:00
|
|
|
|
res.push_all(*self);
|
2013-07-02 21:13:00 -05:00
|
|
|
|
res.push_all(rhs.as_slice());
|
2014-04-17 17:28:14 -05:00
|
|
|
|
res.move_iter().collect()
|
2013-07-02 21:13:00 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-08-08 22:49:49 -05:00
|
|
|
|
|
2013-07-02 14:47:32 -05:00
|
|
|
|
impl<T:Clone, V: Vector<T>> Add<V, ~[T]> for ~[T] {
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn add(&self, rhs: &V) -> ~[T] {
|
2013-08-08 22:49:49 -05:00
|
|
|
|
self.as_slice() + rhs.as_slice()
|
2013-07-02 21:13:00 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-27 19:15:54 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[cfg(test)]
|
|
|
|
|
pub mod traits {}
|
2012-08-29 21:23:15 -05:00
|
|
|
|
|
2013-07-02 21:13:00 -05:00
|
|
|
|
/// Any vector that can be represented as a slice.
|
|
|
|
|
pub trait Vector<T> {
|
|
|
|
|
/// Work with `self` as a slice.
|
|
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T];
|
2012-10-19 08:01:01 -05:00
|
|
|
|
}
|
2013-08-10 21:21:31 -05:00
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T> Vector<T> for &'a [T] {
|
2013-07-02 21:13:00 -05:00
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T] { *self }
|
2012-09-19 20:00:26 -05:00
|
|
|
|
}
|
2013-08-10 21:21:31 -05:00
|
|
|
|
|
2013-07-02 21:13:00 -05:00
|
|
|
|
impl<T> Vector<T> for ~[T] {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
|
2012-09-19 20:00:26 -05:00
|
|
|
|
}
|
2013-08-10 21:21:31 -05:00
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a, T> Container for &'a [T] {
|
2012-07-04 16:53:12 -05:00
|
|
|
|
/// Returns the length of a vector
|
2012-06-02 21:03:28 -05:00
|
|
|
|
#[inline]
|
2013-06-15 01:20:06 -05:00
|
|
|
|
fn len(&self) -> uint {
|
2013-12-17 08:49:31 -06:00
|
|
|
|
self.repr().len
|
2013-06-08 20:38:47 -05:00
|
|
|
|
}
|
2013-06-15 01:20:06 -05:00
|
|
|
|
}
|
2013-06-08 20:38:47 -05:00
|
|
|
|
|
2013-06-15 01:20:06 -05:00
|
|
|
|
impl<T> Container for ~[T] {
|
|
|
|
|
/// Returns the length of a vector
|
|
|
|
|
#[inline]
|
|
|
|
|
fn len(&self) -> uint {
|
2014-01-14 15:33:08 -06:00
|
|
|
|
self.as_slice().len()
|
2013-06-15 01:20:06 -05:00
|
|
|
|
}
|
2012-06-02 21:03:28 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-28 12:40:38 -06:00
|
|
|
|
/// Extension methods for vector slices with cloneable elements
|
|
|
|
|
pub trait CloneableVector<T> {
|
2013-08-10 21:21:31 -05:00
|
|
|
|
/// Copy `self` into a new owned vector
|
2013-03-21 23:20:48 -05:00
|
|
|
|
fn to_owned(&self) -> ~[T];
|
2013-08-10 21:21:31 -05:00
|
|
|
|
|
2014-01-30 12:29:35 -06:00
|
|
|
|
/// Convert `self` into an owned vector, not making a copy if possible.
|
2013-08-10 21:21:31 -05:00
|
|
|
|
fn into_owned(self) -> ~[T];
|
2012-07-11 14:45:54 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-10 21:21:31 -05:00
|
|
|
|
/// Extension methods for vector slices
|
2014-01-28 12:40:38 -06:00
|
|
|
|
impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
|
2013-06-13 21:06:47 -05:00
|
|
|
|
/// Returns a copy of `v`.
|
2012-06-02 21:03:28 -05:00
|
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
|
fn to_owned(&self) -> ~[T] {
|
2014-04-15 18:35:18 -05:00
|
|
|
|
let len = self.len();
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut result = Vec::with_capacity(len);
|
2014-04-15 21:29:36 -05:00
|
|
|
|
// Unsafe code so this can be optimised to a memcpy (or something
|
|
|
|
|
// similarly fast) when T is Copy. LLVM is easily confused, so any
|
|
|
|
|
// extra operations during the loop can prevent this optimisation
|
2014-04-15 18:35:18 -05:00
|
|
|
|
unsafe {
|
|
|
|
|
let mut i = 0;
|
2014-04-15 21:29:36 -05:00
|
|
|
|
let p = result.as_mut_ptr();
|
|
|
|
|
// Use try_finally here otherwise the write to length
|
|
|
|
|
// inside the loop stops LLVM from optimising this.
|
|
|
|
|
try_finally(
|
|
|
|
|
&mut i, (),
|
|
|
|
|
|i, ()| while *i < len {
|
|
|
|
|
mem::move_val_init(
|
|
|
|
|
&mut(*p.offset(*i as int)),
|
|
|
|
|
self.unsafe_ref(*i).clone());
|
|
|
|
|
*i += 1;
|
|
|
|
|
},
|
|
|
|
|
|i| result.set_len(*i));
|
2013-03-16 13:11:31 -05:00
|
|
|
|
}
|
2014-04-17 17:28:14 -05:00
|
|
|
|
result.move_iter().collect()
|
2013-01-07 21:46:45 -06:00
|
|
|
|
}
|
2013-08-10 21:21:31 -05:00
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn into_owned(self) -> ~[T] { self.to_owned() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Extension methods for owned vectors
|
2014-01-28 12:40:38 -06:00
|
|
|
|
impl<T: Clone> CloneableVector<T> for ~[T] {
|
2013-08-10 21:21:31 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn to_owned(&self) -> ~[T] { self.clone() }
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn into_owned(self) -> ~[T] { self }
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Extension methods for vectors
|
2013-12-10 01:16:18 -06:00
|
|
|
|
pub trait ImmutableVector<'a, T> {
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/**
|
|
|
|
|
* Returns a slice of self between `start` and `end`.
|
|
|
|
|
*
|
|
|
|
|
* Fails when `start` or `end` point outside the bounds of self,
|
|
|
|
|
* or when `start` > `end`.
|
|
|
|
|
*/
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn slice(&self, start: uint, end: uint) -> &'a [T];
|
2013-10-14 06:21:47 -05:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a slice of self from `start` to the end of the vec.
|
|
|
|
|
*
|
|
|
|
|
* Fails when `start` points outside the bounds of self.
|
|
|
|
|
*/
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn slice_from(&self, start: uint) -> &'a [T];
|
2013-10-14 06:21:47 -05:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a slice of self from the start of the vec to `end`.
|
|
|
|
|
*
|
|
|
|
|
* Fails when `end` points outside the bounds of self.
|
|
|
|
|
*/
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn slice_to(&self, end: uint) -> &'a [T];
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns an iterator over the vector
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn iter(self) -> Items<'a, T>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns a reversed iterator over a vector
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .iter().rev()"]
|
|
|
|
|
fn rev_iter(self) -> Rev<Items<'a, T>>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns an iterator over the subslices of the vector which are
|
2013-12-01 11:50:34 -06:00
|
|
|
|
/// separated by elements that match `pred`. The matched element
|
|
|
|
|
/// is not contained in the subslices.
|
2014-04-07 15:30:48 -05:00
|
|
|
|
fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns an iterator over the subslices of the vector which are
|
|
|
|
|
/// separated by elements that match `pred`, limited to splitting
|
2013-12-01 11:50:34 -06:00
|
|
|
|
/// at most `n` times. The matched element is not contained in
|
|
|
|
|
/// the subslices.
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<'a, T>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns an iterator over the subslices of the vector which are
|
|
|
|
|
/// separated by elements that match `pred`. This starts at the
|
2013-12-01 11:50:34 -06:00
|
|
|
|
/// end of the vector and works backwards. The matched element is
|
|
|
|
|
/// not contained in the subslices.
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .split(pred).rev()"]
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
fn rsplit(self, pred: |&T|: 'a -> bool) -> Rev<Splits<'a, T>>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns an iterator over the subslices of the vector which are
|
|
|
|
|
/// separated by elements that match `pred` limited to splitting
|
|
|
|
|
/// at most `n` times. This starts at the end of the vector and
|
2013-12-01 11:50:34 -06:00
|
|
|
|
/// works backwards. The matched element is not contained in the
|
|
|
|
|
/// subslices.
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<'a, T>;
|
2013-07-02 23:54:11 -05:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/**
|
|
|
|
|
* Returns an iterator over all contiguous windows of length
|
|
|
|
|
* `size`. The windows overlap. If the vector is shorter than
|
|
|
|
|
* `size`, the iterator returns no values.
|
|
|
|
|
*
|
|
|
|
|
* # Failure
|
|
|
|
|
*
|
|
|
|
|
* Fails if `size` is 0.
|
|
|
|
|
*
|
|
|
|
|
* # Example
|
|
|
|
|
*
|
|
|
|
|
* Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`,
|
|
|
|
|
* `[3,4]`):
|
|
|
|
|
*
|
|
|
|
|
* ```rust
|
|
|
|
|
* let v = &[1,2,3,4];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
* for win in v.windows(2) {
|
2013-10-14 06:21:47 -05:00
|
|
|
|
* println!("{:?}", win);
|
|
|
|
|
* }
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
*/
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn windows(self, size: uint) -> Windows<'a, T>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* Returns an iterator over `size` elements of the vector at a
|
|
|
|
|
* time. The chunks do not overlap. If `size` does not divide the
|
|
|
|
|
* length of the vector, then the last chunk will not have length
|
|
|
|
|
* `size`.
|
|
|
|
|
*
|
|
|
|
|
* # Failure
|
|
|
|
|
*
|
|
|
|
|
* Fails if `size` is 0.
|
|
|
|
|
*
|
|
|
|
|
* # Example
|
|
|
|
|
*
|
|
|
|
|
* Print the vector two elements at a time (i.e. `[1,2]`,
|
|
|
|
|
* `[3,4]`, `[5]`):
|
|
|
|
|
*
|
|
|
|
|
* ```rust
|
|
|
|
|
* let v = &[1,2,3,4,5];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
* for win in v.chunks(2) {
|
2013-10-14 06:21:47 -05:00
|
|
|
|
* println!("{:?}", win);
|
|
|
|
|
* }
|
|
|
|
|
* ```
|
|
|
|
|
*
|
|
|
|
|
*/
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn chunks(self, size: uint) -> Chunks<'a, T>;
|
2013-07-03 00:47:58 -05:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns the element of a vector at the given index, or `None` if the
|
|
|
|
|
/// index is out of bounds
|
2013-12-23 07:38:02 -06:00
|
|
|
|
fn get(&self, index: uint) -> Option<&'a T>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns the first element of a vector, or `None` if it is empty
|
2013-12-23 07:46:54 -06:00
|
|
|
|
fn head(&self) -> Option<&'a T>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns all but the first element of a vector
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn tail(&self) -> &'a [T];
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns all but the first `n' elements of a vector
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn tailn(&self, n: uint) -> &'a [T];
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns all but the last element of a vector
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn init(&self) -> &'a [T];
|
2013-12-14 23:26:09 -06:00
|
|
|
|
/// Returns all but the last `n' elements of a vector
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn initn(&self, n: uint) -> &'a [T];
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns the last element of a vector, or `None` if it is empty.
|
2013-12-23 08:08:23 -06:00
|
|
|
|
fn last(&self) -> Option<&'a T>;
|
2014-03-28 14:42:34 -05:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns a pointer to the element at the given index, without doing
|
|
|
|
|
/// bounds checking.
|
2014-01-21 08:34:42 -06:00
|
|
|
|
unsafe fn unsafe_ref(self, index: uint) -> &'a T;
|
2013-06-28 22:35:25 -05:00
|
|
|
|
|
2013-12-15 06:35:12 -06:00
|
|
|
|
/**
|
|
|
|
|
* Returns an unsafe pointer to the vector's buffer
|
|
|
|
|
*
|
|
|
|
|
* The caller must ensure that the vector outlives the pointer this
|
|
|
|
|
* function returns, or else it will end up pointing to garbage.
|
|
|
|
|
*
|
|
|
|
|
* Modifying the vector may cause its buffer to be reallocated, which
|
|
|
|
|
* would also make any pointers to it invalid.
|
|
|
|
|
*/
|
|
|
|
|
fn as_ptr(&self) -> *T;
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/**
|
|
|
|
|
* Binary search a sorted vector with a comparator function.
|
|
|
|
|
*
|
2013-12-14 23:26:09 -06:00
|
|
|
|
* The comparator function should implement an order consistent
|
|
|
|
|
* with the sort order of the underlying vector, returning an
|
|
|
|
|
* order code that indicates whether its argument is `Less`,
|
|
|
|
|
* `Equal` or `Greater` the desired target.
|
2013-10-14 06:21:47 -05:00
|
|
|
|
*
|
|
|
|
|
* Returns the index where the comparator returned `Equal`, or `None` if
|
|
|
|
|
* not found.
|
|
|
|
|
*/
|
2013-11-18 23:15:42 -06:00
|
|
|
|
fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint>;
|
2013-06-29 00:05:50 -05:00
|
|
|
|
|
2013-11-16 16:29:19 -06:00
|
|
|
|
/**
|
|
|
|
|
* Returns a mutable reference to the first element in this slice
|
|
|
|
|
* and adjusts the slice in place so that it no longer contains
|
|
|
|
|
* that element. O(1).
|
|
|
|
|
*
|
|
|
|
|
* Equivalent to:
|
|
|
|
|
*
|
2014-02-15 01:44:22 -06:00
|
|
|
|
* ```ignore
|
2014-01-25 11:00:46 -06:00
|
|
|
|
* if self.len() == 0 { return None }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* let head = &self[0];
|
|
|
|
|
* *self = self.slice_from(1);
|
2014-01-25 11:00:46 -06:00
|
|
|
|
* Some(head)
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* ```
|
|
|
|
|
*
|
2014-01-25 11:00:46 -06:00
|
|
|
|
* Returns `None` if vector is empty
|
2013-11-16 16:29:19 -06:00
|
|
|
|
*/
|
2014-01-25 11:00:46 -06:00
|
|
|
|
fn shift_ref(&mut self) -> Option<&'a T>;
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a mutable reference to the last element in this slice
|
|
|
|
|
* and adjusts the slice in place so that it no longer contains
|
|
|
|
|
* that element. O(1).
|
|
|
|
|
*
|
|
|
|
|
* Equivalent to:
|
|
|
|
|
*
|
2014-02-15 01:44:22 -06:00
|
|
|
|
* ```ignore
|
2014-01-25 14:33:31 -06:00
|
|
|
|
* if self.len() == 0 { return None; }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* let tail = &self[self.len() - 1];
|
|
|
|
|
* *self = self.slice_to(self.len() - 1);
|
2014-01-25 14:33:31 -06:00
|
|
|
|
* Some(tail)
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* ```
|
|
|
|
|
*
|
2014-01-25 14:33:31 -06:00
|
|
|
|
* Returns `None` if slice is empty.
|
2013-11-16 16:29:19 -06:00
|
|
|
|
*/
|
2014-01-25 14:33:31 -06:00
|
|
|
|
fn pop_ref(&mut self) -> Option<&'a T>;
|
2013-04-10 15:11:35 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
|
2013-04-10 15:11:35 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn slice(&self, start: uint, end: uint) -> &'a [T] {
|
2013-10-14 23:37:32 -05:00
|
|
|
|
assert!(start <= end);
|
|
|
|
|
assert!(end <= self.len());
|
2013-12-17 08:49:31 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute(Slice {
|
2013-12-17 08:49:31 -06:00
|
|
|
|
data: self.as_ptr().offset(start as int),
|
2013-10-14 23:37:32 -05:00
|
|
|
|
len: (end - start)
|
|
|
|
|
})
|
2013-12-17 08:49:31 -06:00
|
|
|
|
}
|
2013-10-14 23:37:32 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-21 08:39:01 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn slice_from(&self, start: uint) -> &'a [T] {
|
2013-07-21 08:39:01 -05:00
|
|
|
|
self.slice(start, self.len())
|
|
|
|
|
}
|
2013-10-14 23:37:32 -05:00
|
|
|
|
|
2013-07-21 08:39:01 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn slice_to(&self, end: uint) -> &'a [T] {
|
2013-07-21 08:39:01 -05:00
|
|
|
|
self.slice(0, end)
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-17 18:34:53 -05:00
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn iter(self) -> Items<'a, T> {
|
2013-04-17 18:34:53 -05:00
|
|
|
|
unsafe {
|
2013-12-15 06:35:12 -06:00
|
|
|
|
let p = self.as_ptr();
|
2013-10-16 20:34:01 -05:00
|
|
|
|
if mem::size_of::<T>() == 0 {
|
2014-01-14 21:32:24 -06:00
|
|
|
|
Items{ptr: p,
|
2014-01-22 13:03:02 -06:00
|
|
|
|
end: (p as uint + self.len()) as *T,
|
|
|
|
|
marker: marker::ContravariantLifetime::<'a>}
|
2013-08-06 16:15:43 -05:00
|
|
|
|
} else {
|
2014-01-14 21:32:24 -06:00
|
|
|
|
Items{ptr: p,
|
2014-01-22 13:03:02 -06:00
|
|
|
|
end: p.offset(self.len() as int),
|
|
|
|
|
marker: marker::ContravariantLifetime::<'a>}
|
2013-08-06 16:15:43 -05:00
|
|
|
|
}
|
2013-04-17 18:34:53 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-11 20:10:59 -05:00
|
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
|
#[inline]
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .iter().rev()"]
|
|
|
|
|
fn rev_iter(self) -> Rev<Items<'a, T>> {
|
2014-01-23 13:41:57 -06:00
|
|
|
|
self.iter().rev()
|
2013-06-07 21:39:52 -05:00
|
|
|
|
}
|
2013-04-17 18:34:53 -05:00
|
|
|
|
|
2013-07-02 23:54:11 -05:00
|
|
|
|
#[inline]
|
2014-04-07 15:30:48 -05:00
|
|
|
|
fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
|
2014-01-14 21:32:24 -06:00
|
|
|
|
Splits {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
v: self,
|
|
|
|
|
pred: pred,
|
|
|
|
|
finished: false
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-11-23 04:18:51 -06:00
|
|
|
|
|
2013-07-02 23:54:11 -05:00
|
|
|
|
#[inline]
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<'a, T> {
|
|
|
|
|
SplitsN {
|
|
|
|
|
iter: self.split(pred),
|
|
|
|
|
count: n,
|
|
|
|
|
invert: false
|
|
|
|
|
}
|
2013-07-02 23:54:11 -05:00
|
|
|
|
}
|
2013-11-23 04:18:51 -06:00
|
|
|
|
|
2013-07-02 23:54:11 -05:00
|
|
|
|
#[inline]
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .split(pred).rev()"]
|
Provide an implementation of DoubleEndedIterator for the results of &[T]::split and &[T]::rsplit
This makes the splitting functions in std::slice return DoubleEndedIterators. Unfortunately,
splitn and rsplitn cannot provide such an interface and so must return different types. As a
result, the following changes were made:
* RevSplits was removed in favor of explicitly using Rev
* Splits can no longer bound the number of splits done
* Splits now implements DoubleEndedIterator
* SplitsN was added, taking the role of what both Splits and RevSplits used to be
* rsplit returns Rev<Splits<'a, T>> instead of RevSplits<'a, T>
* splitn returns SplitsN<'a, T> instead of Splits<'a, T>
* rsplitn returns SplitsN<'a, T> instead of RevSplits<'a, T>
All functions that were previously implemented on each return value still are, so outside of changing
of type annotations, existing code should work out of the box. In the rare case that code relied
on the return types of split and splitn or of rsplit and rsplitn being the same, the previous
behavior can be emulated by calling splitn or rsplitn with a bount of uint::MAX.
The value of this change comes in multiple parts:
* Consistency. The splitting code in std::str is structured similarly to the new slice splitting code,
having separate CharSplits and CharSplitsN types.
* Smaller API. Although this commit doesn't implement it, using a DoubleEndedIterator for splitting
means that rsplit, path::RevComponents, path::RevStrComponents, Path::rev_components, and
Path::rev_str_components are no longer needed - they can be emulated simply with .rev().
* Power. DoubleEndedIterators are able to traverse the list from both sides at once instead of only
forwards or backwards.
* Efficiency. For the common case of using split instead of splitn, the iterator is slightly smaller
and slightly faster.
[breaking-change]
2014-04-20 21:28:38 -05:00
|
|
|
|
fn rsplit(self, pred: |&T|: 'a -> bool) -> Rev<Splits<'a, T>> {
|
|
|
|
|
self.split(pred).rev()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<'a, T> {
|
|
|
|
|
SplitsN {
|
|
|
|
|
iter: self.split(pred),
|
|
|
|
|
count: n,
|
|
|
|
|
invert: true
|
2013-07-02 23:54:11 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn windows(self, size: uint) -> Windows<'a, T> {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
assert!(size != 0);
|
2014-01-14 21:32:24 -06:00
|
|
|
|
Windows { v: self, size: size }
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn chunks(self, size: uint) -> Chunks<'a, T> {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
assert!(size != 0);
|
2014-01-14 21:32:24 -06:00
|
|
|
|
Chunks { v: self, size: size }
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 10:59:00 -05:00
|
|
|
|
#[inline]
|
2013-12-23 07:38:02 -06:00
|
|
|
|
fn get(&self, index: uint) -> Option<&'a T> {
|
2013-09-29 10:59:00 -05:00
|
|
|
|
if index < self.len() { Some(&self[index]) } else { None }
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-10 15:11:35 -05:00
|
|
|
|
#[inline]
|
2013-12-23 07:46:54 -06:00
|
|
|
|
fn head(&self) -> Option<&'a T> {
|
2013-06-27 07:36:27 -05:00
|
|
|
|
if self.len() == 0 { None } else { Some(&self[0]) }
|
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn tail(&self) -> &'a [T] { self.slice(1, self.len()) }
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn tailn(&self, n: uint) -> &'a [T] { self.slice(n, self.len()) }
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn init(&self) -> &'a [T] {
|
2013-06-27 07:36:27 -05:00
|
|
|
|
self.slice(0, self.len() - 1)
|
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn initn(&self, n: uint) -> &'a [T] {
|
2013-06-27 07:36:27 -05:00
|
|
|
|
self.slice(0, self.len() - n)
|
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2013-12-23 08:08:23 -06:00
|
|
|
|
fn last(&self) -> Option<&'a T> {
|
2013-06-27 07:36:27 -05:00
|
|
|
|
if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
|
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
|
#[inline]
|
2014-01-21 08:34:42 -06:00
|
|
|
|
unsafe fn unsafe_ref(self, index: uint) -> &'a T {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute(self.repr().data.offset(index as int))
|
2013-04-19 17:57:31 -05:00
|
|
|
|
}
|
2013-06-28 22:35:25 -05:00
|
|
|
|
|
2013-12-15 06:35:12 -06:00
|
|
|
|
#[inline]
|
|
|
|
|
fn as_ptr(&self) -> *T {
|
|
|
|
|
self.repr().data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-11-18 23:15:42 -06:00
|
|
|
|
fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint> {
|
2013-06-28 22:35:25 -05:00
|
|
|
|
let mut base : uint = 0;
|
|
|
|
|
let mut lim : uint = self.len();
|
|
|
|
|
|
|
|
|
|
while lim != 0 {
|
|
|
|
|
let ix = base + (lim >> 1);
|
|
|
|
|
match f(&self[ix]) {
|
|
|
|
|
Equal => return Some(ix),
|
|
|
|
|
Less => {
|
|
|
|
|
base = ix + 1;
|
|
|
|
|
lim -= 1;
|
|
|
|
|
}
|
|
|
|
|
Greater => ()
|
|
|
|
|
}
|
|
|
|
|
lim >>= 1;
|
|
|
|
|
}
|
|
|
|
|
return None;
|
|
|
|
|
}
|
2013-06-29 00:05:50 -05:00
|
|
|
|
|
2014-01-25 11:00:46 -06:00
|
|
|
|
fn shift_ref(&mut self) -> Option<&'a T> {
|
|
|
|
|
if self.len() == 0 { return None; }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
let s: &mut Slice<T> = transmute(self);
|
2014-01-25 11:00:46 -06:00
|
|
|
|
Some(&*raw::shift_ptr(s))
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-25 14:33:31 -06:00
|
|
|
|
fn pop_ref(&mut self) -> Option<&'a T> {
|
|
|
|
|
if self.len() == 0 { return None; }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
let s: &mut Slice<T> = transmute(self);
|
2014-01-25 14:33:31 -06:00
|
|
|
|
Some(&*raw::pop_ptr(s))
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-10 15:11:35 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Extension methods for vectors contain `Eq` elements.
|
2013-02-20 19:07:17 -06:00
|
|
|
|
pub trait ImmutableEqVector<T:Eq> {
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Find the first index containing a matching value
|
2013-03-21 23:20:48 -05:00
|
|
|
|
fn position_elem(&self, t: &T) -> Option<uint>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
|
|
|
|
|
/// Find the last index containing a matching value
|
2013-03-21 23:20:48 -05:00
|
|
|
|
fn rposition_elem(&self, t: &T) -> Option<uint>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
|
|
|
|
|
/// Return true if a vector contains an element with the given value
|
2013-06-28 11:08:32 -05:00
|
|
|
|
fn contains(&self, x: &T) -> bool;
|
2013-10-17 00:01:20 -05:00
|
|
|
|
|
|
|
|
|
/// Returns true if `needle` is a prefix of the vector.
|
|
|
|
|
fn starts_with(&self, needle: &[T]) -> bool;
|
|
|
|
|
|
|
|
|
|
/// Returns true if `needle` is a suffix of the vector.
|
|
|
|
|
fn ends_with(&self, needle: &[T]) -> bool;
|
2013-01-07 10:38:24 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T:Eq> ImmutableEqVector<T> for &'a [T] {
|
2012-08-27 18:26:35 -05:00
|
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
|
fn position_elem(&self, x: &T) -> Option<uint> {
|
2013-07-04 21:13:26 -05:00
|
|
|
|
self.iter().position(|y| *x == *y)
|
2012-09-28 00:20:47 -05:00
|
|
|
|
}
|
|
|
|
|
|
2012-08-27 18:26:35 -05:00
|
|
|
|
#[inline]
|
2013-03-21 23:20:48 -05:00
|
|
|
|
fn rposition_elem(&self, t: &T) -> Option<uint> {
|
2013-08-30 13:00:14 -05:00
|
|
|
|
self.iter().rposition(|x| *x == *t)
|
2013-06-28 11:08:32 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-16 23:56:31 -05:00
|
|
|
|
#[inline]
|
2013-06-28 11:08:32 -05:00
|
|
|
|
fn contains(&self, x: &T) -> bool {
|
2013-10-16 23:56:31 -05:00
|
|
|
|
self.iter().any(|elt| *x == *elt)
|
2012-09-28 00:20:47 -05:00
|
|
|
|
}
|
2013-10-17 00:01:20 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn starts_with(&self, needle: &[T]) -> bool {
|
|
|
|
|
let n = needle.len();
|
|
|
|
|
self.len() >= n && needle == self.slice_to(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn ends_with(&self, needle: &[T]) -> bool {
|
|
|
|
|
let (m, n) = (self.len(), needle.len());
|
|
|
|
|
m >= n && needle == self.slice_from(m - n)
|
|
|
|
|
}
|
2012-08-27 18:26:35 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Extension methods for vectors containing `TotalOrd` elements.
|
2013-06-28 22:35:25 -05:00
|
|
|
|
pub trait ImmutableTotalOrdVector<T: TotalOrd> {
|
|
|
|
|
/**
|
|
|
|
|
* Binary search a sorted vector for a given element.
|
|
|
|
|
*
|
|
|
|
|
* Returns the index of the element or None if not found.
|
|
|
|
|
*/
|
2013-10-14 06:21:47 -05:00
|
|
|
|
fn bsearch_elem(&self, x: &T) -> Option<uint>;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a, T: TotalOrd> ImmutableTotalOrdVector<T> for &'a [T] {
|
2013-06-28 22:35:25 -05:00
|
|
|
|
fn bsearch_elem(&self, x: &T) -> Option<uint> {
|
|
|
|
|
self.bsearch(|p| p.cmp(x))
|
2012-09-28 00:20:47 -05:00
|
|
|
|
}
|
2012-08-27 18:26:35 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Extension methods for vectors containing `Clone` elements.
|
2014-01-28 16:42:40 -06:00
|
|
|
|
pub trait ImmutableCloneableVector<T> {
|
2014-02-28 07:07:42 -06:00
|
|
|
|
/// Partitions the vector into two vectors `(A,B)`, where all
|
|
|
|
|
/// elements of `A` satisfy `f` and all elements of `B` do not.
|
2013-11-18 23:15:42 -06:00
|
|
|
|
fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]);
|
2013-10-14 06:21:47 -05:00
|
|
|
|
|
|
|
|
|
/// Create an iterator that yields every possible permutation of the
|
|
|
|
|
/// vector in succession.
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn permutations(self) -> Permutations<T>;
|
2012-07-11 14:45:54 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-28 16:42:40 -06:00
|
|
|
|
impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
|
2013-01-07 10:49:41 -06:00
|
|
|
|
#[inline]
|
2013-11-18 23:15:42 -06:00
|
|
|
|
fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut lefts = Vec::new();
|
|
|
|
|
let mut rights = Vec::new();
|
2013-06-27 09:10:18 -05:00
|
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for elt in self.iter() {
|
2013-06-27 09:10:18 -05:00
|
|
|
|
if f(elt) {
|
2013-07-02 14:47:32 -05:00
|
|
|
|
lefts.push((*elt).clone());
|
2013-06-27 09:10:18 -05:00
|
|
|
|
} else {
|
2013-07-02 14:47:32 -05:00
|
|
|
|
rights.push((*elt).clone());
|
2013-06-27 09:10:18 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
|
(lefts.move_iter().collect(), rights.move_iter().collect())
|
2013-01-07 10:49:41 -06:00
|
|
|
|
}
|
2013-04-17 16:19:25 -05:00
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn permutations(self) -> Permutations<T> {
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
Permutations{
|
|
|
|
|
swaps: ElementSwaps::new(self.len()),
|
|
|
|
|
v: self.to_owned(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-02 21:03:28 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Extension methods for owned vectors.
|
2013-01-07 10:38:24 -06:00
|
|
|
|
pub trait OwnedVector<T> {
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Creates a consuming iterator, that is, one that moves each
|
|
|
|
|
/// value out of the vector (from start to end). The vector cannot
|
|
|
|
|
/// be used after calling this.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2014-04-15 20:17:48 -05:00
|
|
|
|
/// let v = ~["a".to_owned(), "b".to_owned()];
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// for s in v.move_iter() {
|
|
|
|
|
/// // s has type ~str, not &~str
|
2014-01-09 04:06:55 -06:00
|
|
|
|
/// println!("{}", s);
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn move_iter(self) -> MoveItems<T>;
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Creates a consuming iterator that moves out of the vector in
|
2013-12-16 04:26:25 -06:00
|
|
|
|
/// reverse order.
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .move_iter().rev()"]
|
|
|
|
|
fn move_rev_iter(self) -> Rev<MoveItems<T>>;
|
2013-07-01 10:26:44 -05:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/**
|
2014-02-28 07:07:42 -06:00
|
|
|
|
* Partitions the vector into two vectors `(A,B)`, where all
|
|
|
|
|
* elements of `A` satisfy `f` and all elements of `B` do not.
|
2013-10-14 06:21:47 -05:00
|
|
|
|
*/
|
2013-11-18 23:15:42 -06:00
|
|
|
|
fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]);
|
2012-09-26 19:33:34 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-02-14 13:47:00 -06:00
|
|
|
|
impl<T> OwnedVector<T> for ~[T] {
|
2013-12-16 04:26:25 -06:00
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn move_iter(self) -> MoveItems<T> {
|
2013-12-16 04:26:25 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
let iter = transmute(self.iter());
|
|
|
|
|
let ptr = transmute(self);
|
2014-01-14 21:32:24 -06:00
|
|
|
|
MoveItems { allocation: ptr, iter: iter }
|
2013-12-16 04:26:25 -06:00
|
|
|
|
}
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
2013-12-16 04:26:25 -06:00
|
|
|
|
|
|
|
|
|
#[inline]
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .move_iter().rev()"]
|
|
|
|
|
fn move_rev_iter(self) -> Rev<MoveItems<T>> {
|
2014-01-23 13:41:57 -06:00
|
|
|
|
self.move_iter().rev()
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-07 10:49:41 -06:00
|
|
|
|
#[inline]
|
2013-11-18 23:15:42 -06:00
|
|
|
|
fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut lefts = Vec::new();
|
|
|
|
|
let mut rights = Vec::new();
|
2013-06-27 09:10:18 -05:00
|
|
|
|
|
2013-08-07 21:21:36 -05:00
|
|
|
|
for elt in self.move_iter() {
|
2013-06-27 09:10:18 -05:00
|
|
|
|
if f(&elt) {
|
|
|
|
|
lefts.push(elt);
|
|
|
|
|
} else {
|
|
|
|
|
rights.push(elt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
|
(lefts.move_iter().collect(), rights.move_iter().collect())
|
2012-09-28 00:20:47 -05:00
|
|
|
|
}
|
2012-09-26 19:33:34 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-02-04 11:56:13 -06:00
|
|
|
|
fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
|
|
|
|
|
let len = v.len() as int;
|
|
|
|
|
let buf_v = v.as_mut_ptr();
|
|
|
|
|
|
|
|
|
|
// 1 <= i < len;
|
|
|
|
|
for i in range(1, len) {
|
|
|
|
|
// j satisfies: 0 <= j <= i;
|
|
|
|
|
let mut j = i;
|
|
|
|
|
unsafe {
|
|
|
|
|
// `i` is in bounds.
|
|
|
|
|
let read_ptr = buf_v.offset(i) as *T;
|
|
|
|
|
|
|
|
|
|
// find where to insert, we need to do strict <,
|
|
|
|
|
// rather than <=, to maintain stability.
|
|
|
|
|
|
|
|
|
|
// 0 <= j - 1 < len, so .offset(j - 1) is in bounds.
|
|
|
|
|
while j > 0 &&
|
|
|
|
|
compare(&*read_ptr, &*buf_v.offset(j - 1)) == Less {
|
|
|
|
|
j -= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shift everything to the right, to make space to
|
|
|
|
|
// insert this value.
|
|
|
|
|
|
|
|
|
|
// j + 1 could be `len` (for the last `i`), but in
|
|
|
|
|
// that case, `i == j` so we don't copy. The
|
|
|
|
|
// `.offset(j)` is always in bounds.
|
|
|
|
|
|
|
|
|
|
if i != j {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
let tmp = ptr::read(read_ptr);
|
2014-02-04 11:56:13 -06:00
|
|
|
|
ptr::copy_memory(buf_v.offset(j + 1),
|
2014-01-31 16:01:59 -06:00
|
|
|
|
&*buf_v.offset(j),
|
2014-02-04 11:56:13 -06:00
|
|
|
|
(i - j) as uint);
|
|
|
|
|
ptr::copy_nonoverlapping_memory(buf_v.offset(j),
|
|
|
|
|
&tmp as *T,
|
|
|
|
|
1);
|
|
|
|
|
cast::forget(tmp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-19 21:42:00 -06:00
|
|
|
|
fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
|
2013-12-18 16:24:26 -06:00
|
|
|
|
// warning: this wildly uses unsafe.
|
2014-02-04 11:56:13 -06:00
|
|
|
|
static BASE_INSERTION: uint = 32;
|
|
|
|
|
static LARGE_INSERTION: uint = 16;
|
|
|
|
|
|
|
|
|
|
// FIXME #12092: smaller insertion runs seems to make sorting
|
|
|
|
|
// vectors of large elements a little faster on some platforms,
|
|
|
|
|
// but hasn't been tested/tuned extensively
|
|
|
|
|
let insertion = if size_of::<T>() <= 16 {
|
|
|
|
|
BASE_INSERTION
|
|
|
|
|
} else {
|
|
|
|
|
LARGE_INSERTION
|
|
|
|
|
};
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
|
|
let len = v.len();
|
|
|
|
|
|
2014-02-04 11:56:13 -06:00
|
|
|
|
// short vectors get sorted in-place via insertion sort to avoid allocations
|
|
|
|
|
if len <= insertion {
|
|
|
|
|
insertion_sort(v, compare);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-18 16:24:26 -06:00
|
|
|
|
// allocate some memory to use as scratch memory, we keep the
|
|
|
|
|
// length 0 so we can keep shallow copies of the contents of `v`
|
|
|
|
|
// without risking the dtors running on an object twice if
|
2013-12-19 21:42:00 -06:00
|
|
|
|
// `compare` fails.
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut working_space = Vec::with_capacity(2 * len);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
// these both are buffers of length `len`.
|
|
|
|
|
let mut buf_dat = working_space.as_mut_ptr();
|
|
|
|
|
let mut buf_tmp = unsafe {buf_dat.offset(len as int)};
|
|
|
|
|
|
|
|
|
|
// length `len`.
|
|
|
|
|
let buf_v = v.as_ptr();
|
|
|
|
|
|
|
|
|
|
// step 1. sort short runs with insertion sort. This takes the
|
|
|
|
|
// values from `v` and sorts them into `buf_dat`, leaving that
|
|
|
|
|
// with sorted runs of length INSERTION.
|
|
|
|
|
|
|
|
|
|
// We could hardcode the sorting comparisons here, and we could
|
|
|
|
|
// manipulate/step the pointers themselves, rather than repeatedly
|
|
|
|
|
// .offset-ing.
|
2014-02-04 11:56:13 -06:00
|
|
|
|
for start in range_step(0, len, insertion) {
|
|
|
|
|
// start <= i < len;
|
|
|
|
|
for i in range(start, cmp::min(start + insertion, len)) {
|
2013-12-18 16:24:26 -06:00
|
|
|
|
// j satisfies: start <= j <= i;
|
|
|
|
|
let mut j = i as int;
|
|
|
|
|
unsafe {
|
|
|
|
|
// `i` is in bounds.
|
|
|
|
|
let read_ptr = buf_v.offset(i as int);
|
|
|
|
|
|
|
|
|
|
// find where to insert, we need to do strict <,
|
|
|
|
|
// rather than <=, to maintain stability.
|
|
|
|
|
|
|
|
|
|
// start <= j - 1 < len, so .offset(j - 1) is in
|
|
|
|
|
// bounds.
|
2013-12-19 21:42:00 -06:00
|
|
|
|
while j > start as int &&
|
|
|
|
|
compare(&*read_ptr, &*buf_dat.offset(j - 1)) == Less {
|
2013-12-18 16:24:26 -06:00
|
|
|
|
j -= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shift everything to the right, to make space to
|
|
|
|
|
// insert this value.
|
|
|
|
|
|
|
|
|
|
// j + 1 could be `len` (for the last `i`), but in
|
|
|
|
|
// that case, `i == j` so we don't copy. The
|
|
|
|
|
// `.offset(j)` is always in bounds.
|
|
|
|
|
ptr::copy_memory(buf_dat.offset(j + 1),
|
2014-01-31 16:01:59 -06:00
|
|
|
|
&*buf_dat.offset(j),
|
2013-12-18 16:24:26 -06:00
|
|
|
|
i - j as uint);
|
|
|
|
|
ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// step 2. merge the sorted runs.
|
2014-02-04 11:56:13 -06:00
|
|
|
|
let mut width = insertion;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
while width < len {
|
|
|
|
|
// merge the sorted runs of length `width` in `buf_dat` two at
|
|
|
|
|
// a time, placing the result in `buf_tmp`.
|
|
|
|
|
|
|
|
|
|
// 0 <= start <= len.
|
|
|
|
|
for start in range_step(0, len, 2 * width) {
|
|
|
|
|
// manipulate pointers directly for speed (rather than
|
|
|
|
|
// using a `for` loop with `range` and `.offset` inside
|
|
|
|
|
// that loop).
|
|
|
|
|
unsafe {
|
|
|
|
|
// the end of the first run & start of the
|
|
|
|
|
// second. Offset of `len` is defined, since this is
|
|
|
|
|
// precisely one byte past the end of the object.
|
|
|
|
|
let right_start = buf_dat.offset(cmp::min(start + width, len) as int);
|
|
|
|
|
// end of the second. Similar reasoning to the above re safety.
|
|
|
|
|
let right_end_idx = cmp::min(start + 2 * width, len);
|
|
|
|
|
let right_end = buf_dat.offset(right_end_idx as int);
|
|
|
|
|
|
|
|
|
|
// the pointers to the elements under consideration
|
|
|
|
|
// from the two runs.
|
|
|
|
|
|
|
|
|
|
// both of these are in bounds.
|
|
|
|
|
let mut left = buf_dat.offset(start as int);
|
|
|
|
|
let mut right = right_start;
|
|
|
|
|
|
|
|
|
|
// where we're putting the results, it is a run of
|
|
|
|
|
// length `2*width`, so we step it once for each step
|
|
|
|
|
// of either `left` or `right`. `buf_tmp` has length
|
|
|
|
|
// `len`, so these are in bounds.
|
|
|
|
|
let mut out = buf_tmp.offset(start as int);
|
|
|
|
|
let out_end = buf_tmp.offset(right_end_idx as int);
|
|
|
|
|
|
|
|
|
|
while out < out_end {
|
|
|
|
|
// Either the left or the right run are exhausted,
|
|
|
|
|
// so just copy the remainder from the other run
|
|
|
|
|
// and move on; this gives a huge speed-up (order
|
|
|
|
|
// of 25%) for mostly sorted vectors (the best
|
|
|
|
|
// case).
|
|
|
|
|
if left == right_start {
|
|
|
|
|
// the number remaining in this run.
|
|
|
|
|
let elems = (right_end as uint - right as uint) / mem::size_of::<T>();
|
2014-01-31 16:01:59 -06:00
|
|
|
|
ptr::copy_nonoverlapping_memory(out, &*right, elems);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
break;
|
|
|
|
|
} else if right == right_end {
|
|
|
|
|
let elems = (right_start as uint - left as uint) / mem::size_of::<T>();
|
2014-01-31 16:01:59 -06:00
|
|
|
|
ptr::copy_nonoverlapping_memory(out, &*left, elems);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check which side is smaller, and that's the
|
|
|
|
|
// next element for the new run.
|
|
|
|
|
|
|
|
|
|
// `left < right_start` and `right < right_end`,
|
|
|
|
|
// so these are valid.
|
2013-12-19 21:42:00 -06:00
|
|
|
|
let to_copy = if compare(&*left, &*right) == Greater {
|
2013-12-18 16:24:26 -06:00
|
|
|
|
step(&mut right)
|
2013-12-19 21:42:00 -06:00
|
|
|
|
} else {
|
|
|
|
|
step(&mut left)
|
2013-12-18 16:24:26 -06:00
|
|
|
|
};
|
2014-01-31 16:01:59 -06:00
|
|
|
|
ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
step(&mut out);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-31 14:35:36 -06:00
|
|
|
|
mem::swap(&mut buf_dat, &mut buf_tmp);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
|
|
width *= 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// write the result to `v` in one go, so that there are never two copies
|
|
|
|
|
// of the same object in `v`.
|
|
|
|
|
unsafe {
|
2014-01-31 16:01:59 -06:00
|
|
|
|
ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// increment the pointer, returning the old pointer.
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
unsafe fn step<T>(ptr: &mut *mut T) -> *mut T {
|
|
|
|
|
let old = *ptr;
|
|
|
|
|
*ptr = ptr.offset(1);
|
|
|
|
|
old
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Extension methods for vectors such that their elements are
|
|
|
|
|
/// mutable.
|
2013-12-10 01:16:18 -06:00
|
|
|
|
pub trait MutableVector<'a, T> {
|
2013-12-09 16:45:53 -06:00
|
|
|
|
/// Work with `self` as a mut slice.
|
|
|
|
|
/// Primarily intended for getting a &mut [T] from a [T, ..N].
|
|
|
|
|
fn as_mut_slice(self) -> &'a mut [T];
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Return a slice that points into another slice.
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn mut_slice(self, start: uint, end: uint) -> &'a mut [T];
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/**
|
|
|
|
|
* Returns a slice of self from `start` to the end of the vec.
|
|
|
|
|
*
|
|
|
|
|
* Fails when `start` points outside the bounds of self.
|
|
|
|
|
*/
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn mut_slice_from(self, start: uint) -> &'a mut [T];
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/**
|
|
|
|
|
* Returns a slice of self from the start of the vec to `end`.
|
|
|
|
|
*
|
|
|
|
|
* Fails when `end` points outside the bounds of self.
|
|
|
|
|
*/
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn mut_slice_to(self, end: uint) -> &'a mut [T];
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns an iterator that allows modifying each value
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn mut_iter(self) -> MutItems<'a, T>;
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
2014-01-15 13:39:08 -06:00
|
|
|
|
/// Returns a mutable pointer to the last item in the vector.
|
2014-01-26 10:24:34 -06:00
|
|
|
|
fn mut_last(self) -> Option<&'a mut T>;
|
2014-01-15 13:39:08 -06:00
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns a reversed iterator that allows modifying each value
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .mut_iter().rev()"]
|
|
|
|
|
fn mut_rev_iter(self) -> Rev<MutItems<'a, T>>;
|
2013-05-26 20:40:07 -05:00
|
|
|
|
|
2013-12-01 11:50:34 -06:00
|
|
|
|
/// Returns an iterator over the mutable subslices of the vector
|
|
|
|
|
/// which are separated by elements that match `pred`. The
|
|
|
|
|
/// matched element is not contained in the subslices.
|
2014-04-07 15:30:48 -05:00
|
|
|
|
fn mut_split(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
|
2013-12-01 11:50:34 -06:00
|
|
|
|
|
2013-11-30 15:28:42 -06:00
|
|
|
|
/**
|
|
|
|
|
* Returns an iterator over `size` elements of the vector at a time.
|
|
|
|
|
* The chunks are mutable and do not overlap. If `size` does not divide the
|
|
|
|
|
* length of the vector, then the last chunk will not have length
|
|
|
|
|
* `size`.
|
|
|
|
|
*
|
|
|
|
|
* # Failure
|
|
|
|
|
*
|
|
|
|
|
* Fails if `size` is 0.
|
|
|
|
|
*/
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T>;
|
2013-11-30 15:28:42 -06:00
|
|
|
|
|
2013-11-16 16:29:19 -06:00
|
|
|
|
/**
|
|
|
|
|
* Returns a mutable reference to the first element in this slice
|
|
|
|
|
* and adjusts the slice in place so that it no longer contains
|
|
|
|
|
* that element. O(1).
|
|
|
|
|
*
|
|
|
|
|
* Equivalent to:
|
|
|
|
|
*
|
2014-02-15 01:44:22 -06:00
|
|
|
|
* ```ignore
|
2014-01-25 11:00:46 -06:00
|
|
|
|
* if self.len() == 0 { return None; }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* let head = &mut self[0];
|
|
|
|
|
* *self = self.mut_slice_from(1);
|
2014-01-25 11:00:46 -06:00
|
|
|
|
* Some(head)
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* ```
|
|
|
|
|
*
|
2014-01-25 11:00:46 -06:00
|
|
|
|
* Returns `None` if slice is empty
|
2013-11-16 16:29:19 -06:00
|
|
|
|
*/
|
2014-01-25 11:00:46 -06:00
|
|
|
|
fn mut_shift_ref(&mut self) -> Option<&'a mut T>;
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a mutable reference to the last element in this slice
|
|
|
|
|
* and adjusts the slice in place so that it no longer contains
|
|
|
|
|
* that element. O(1).
|
|
|
|
|
*
|
|
|
|
|
* Equivalent to:
|
|
|
|
|
*
|
2014-02-15 01:44:22 -06:00
|
|
|
|
* ```ignore
|
2014-01-25 14:33:31 -06:00
|
|
|
|
* if self.len() == 0 { return None; }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* let tail = &mut self[self.len() - 1];
|
|
|
|
|
* *self = self.mut_slice_to(self.len() - 1);
|
2014-01-25 14:33:31 -06:00
|
|
|
|
* Some(tail)
|
2013-11-16 16:29:19 -06:00
|
|
|
|
* ```
|
|
|
|
|
*
|
2014-01-25 14:33:31 -06:00
|
|
|
|
* Returns `None` if slice is empty.
|
2013-11-16 16:29:19 -06:00
|
|
|
|
*/
|
2014-01-25 14:33:31 -06:00
|
|
|
|
fn mut_pop_ref(&mut self) -> Option<&'a mut T>;
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// Swaps two elements in a vector.
|
|
|
|
|
///
|
|
|
|
|
/// Fails if `a` or `b` are out of bounds.
|
|
|
|
|
///
|
|
|
|
|
/// # Arguments
|
|
|
|
|
///
|
|
|
|
|
/// * a - The index of the first element
|
|
|
|
|
/// * b - The index of the second element
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// let mut v = ["a", "b", "c", "d"];
|
|
|
|
|
/// v.swap(1, 3);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(v == ["a", "d", "c", "b"]);
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// ```
|
2013-06-28 11:54:03 -05:00
|
|
|
|
fn swap(self, a: uint, b: uint);
|
|
|
|
|
|
2013-12-24 15:45:31 -06:00
|
|
|
|
|
|
|
|
|
/// Divides one `&mut` into two at an index.
|
|
|
|
|
///
|
|
|
|
|
/// The first will contain all indices from `[0, mid)` (excluding
|
|
|
|
|
/// the index `mid` itself) and the second will contain all
|
|
|
|
|
/// indices from `[mid, len)` (excluding the index `len` itself).
|
|
|
|
|
///
|
|
|
|
|
/// Fails if `mid > len`.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// let mut v = [1, 2, 3, 4, 5, 6];
|
|
|
|
|
///
|
|
|
|
|
/// // scoped to restrict the lifetime of the borrows
|
|
|
|
|
/// {
|
|
|
|
|
/// let (left, right) = v.mut_split_at(0);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(left == &mut []);
|
|
|
|
|
/// assert!(right == &mut [1, 2, 3, 4, 5, 6]);
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// }
|
|
|
|
|
///
|
|
|
|
|
/// {
|
|
|
|
|
/// let (left, right) = v.mut_split_at(2);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(left == &mut [1, 2]);
|
|
|
|
|
/// assert!(right == &mut [3, 4, 5, 6]);
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// }
|
|
|
|
|
///
|
|
|
|
|
/// {
|
|
|
|
|
/// let (left, right) = v.mut_split_at(6);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(left == &mut [1, 2, 3, 4, 5, 6]);
|
|
|
|
|
/// assert!(right == &mut []);
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2014-02-28 03:23:06 -06:00
|
|
|
|
fn mut_split_at(self, mid: uint) -> (&'a mut [T], &'a mut [T]);
|
2013-07-10 08:50:24 -05:00
|
|
|
|
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// Reverse the order of elements in a vector, in place.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// let mut v = [1, 2, 3];
|
|
|
|
|
/// v.reverse();
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(v == [3, 2, 1]);
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// ```
|
2013-06-28 11:54:03 -05:00
|
|
|
|
fn reverse(self);
|
|
|
|
|
|
2013-12-19 21:42:00 -06:00
|
|
|
|
/// Sort the vector, in place, using `compare` to compare
|
|
|
|
|
/// elements.
|
2013-12-18 16:24:26 -06:00
|
|
|
|
///
|
|
|
|
|
/// This sort is `O(n log n)` worst-case and stable, but allocates
|
|
|
|
|
/// approximately `2 * n`, where `n` is the length of `self`.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2013-12-22 15:31:23 -06:00
|
|
|
|
/// let mut v = [5i, 4, 1, 3, 2];
|
|
|
|
|
/// v.sort_by(|a, b| a.cmp(b));
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(v == [1, 2, 3, 4, 5]);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
///
|
|
|
|
|
/// // reverse sorting
|
2013-12-22 15:31:23 -06:00
|
|
|
|
/// v.sort_by(|a, b| b.cmp(a));
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(v == [5, 4, 3, 2, 1]);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
/// ```
|
2013-12-19 21:42:00 -06:00
|
|
|
|
fn sort_by(self, compare: |&T, &T| -> Ordering);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
|
/**
|
|
|
|
|
* Consumes `src` and moves as many elements as it can into `self`
|
|
|
|
|
* from the range [start,end).
|
|
|
|
|
*
|
|
|
|
|
* Returns the number of elements copied (the shorter of self.len()
|
|
|
|
|
* and end - start).
|
|
|
|
|
*
|
|
|
|
|
* # Arguments
|
|
|
|
|
*
|
|
|
|
|
* * src - A mutable vector of `T`
|
|
|
|
|
* * start - The index into `src` to start copying from
|
|
|
|
|
* * end - The index into `str` to stop copying from
|
|
|
|
|
*/
|
|
|
|
|
fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
|
|
|
|
|
|
2013-10-14 06:21:47 -05:00
|
|
|
|
/// Returns an unsafe mutable pointer to the element in index
|
2014-01-21 08:34:42 -06:00
|
|
|
|
unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T;
|
2013-12-15 06:35:12 -06:00
|
|
|
|
|
|
|
|
|
/// Return an unsafe mutable pointer to the vector's buffer.
|
|
|
|
|
///
|
|
|
|
|
/// The caller must ensure that the vector outlives the pointer this
|
|
|
|
|
/// function returns, or else it will end up pointing to garbage.
|
|
|
|
|
///
|
|
|
|
|
/// Modifying the vector may cause its buffer to be reallocated, which
|
|
|
|
|
/// would also make any pointers to it invalid.
|
|
|
|
|
#[inline]
|
|
|
|
|
fn as_mut_ptr(self) -> *mut T;
|
|
|
|
|
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// Unsafely sets the element in index to the value.
|
|
|
|
|
///
|
|
|
|
|
/// This performs no bounds checks, and it is undefined behaviour
|
|
|
|
|
/// if `index` is larger than the length of `self`. However, it
|
|
|
|
|
/// does run the destructor at `index`. It is equivalent to
|
|
|
|
|
/// `self[index] = val`.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2014-04-15 20:17:48 -05:00
|
|
|
|
/// let mut v = ~["foo".to_owned(), "bar".to_owned(), "baz".to_owned()];
|
2013-12-24 15:45:31 -06:00
|
|
|
|
///
|
|
|
|
|
/// unsafe {
|
2014-04-15 20:17:48 -05:00
|
|
|
|
/// // `"baz".to_owned()` is deallocated.
|
|
|
|
|
/// v.unsafe_set(2, "qux".to_owned());
|
2013-12-24 15:45:31 -06:00
|
|
|
|
///
|
|
|
|
|
/// // Out of bounds: could cause a crash, or overwriting
|
|
|
|
|
/// // other data, or something else.
|
2014-04-15 20:17:48 -05:00
|
|
|
|
/// // v.unsafe_set(10, "oops".to_owned());
|
2013-12-24 15:45:31 -06:00
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2013-07-21 19:20:52 -05:00
|
|
|
|
unsafe fn unsafe_set(self, index: uint, val: T);
|
2013-07-03 01:34:17 -05:00
|
|
|
|
|
2013-12-23 05:57:16 -06:00
|
|
|
|
/// Unchecked vector index assignment. Does not drop the
|
|
|
|
|
/// old value and hence is only suitable when the vector
|
|
|
|
|
/// is newly allocated.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2014-04-15 20:17:48 -05:00
|
|
|
|
/// let mut v = ["foo".to_owned(), "bar".to_owned()];
|
2013-12-23 05:57:16 -06:00
|
|
|
|
///
|
2014-04-15 20:17:48 -05:00
|
|
|
|
/// // memory leak! `"bar".to_owned()` is not deallocated.
|
|
|
|
|
/// unsafe { v.init_elem(1, "baz".to_owned()); }
|
2013-12-23 05:57:16 -06:00
|
|
|
|
/// ```
|
2013-12-16 06:30:56 -06:00
|
|
|
|
unsafe fn init_elem(self, i: uint, val: T);
|
|
|
|
|
|
2013-12-23 05:57:16 -06:00
|
|
|
|
/// Copies raw bytes from `src` to `self`.
|
2013-12-16 06:35:02 -06:00
|
|
|
|
///
|
2013-12-23 05:57:16 -06:00
|
|
|
|
/// This does not run destructors on the overwritten elements, and
|
|
|
|
|
/// ignores move semantics. `self` and `src` must not
|
|
|
|
|
/// overlap. Fails if `self` is shorter than `src`.
|
2013-12-16 06:35:02 -06:00
|
|
|
|
unsafe fn copy_memory(self, src: &[T]);
|
2013-04-17 16:19:25 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
|
2013-05-26 20:40:07 -05:00
|
|
|
|
#[inline]
|
2013-12-09 16:45:53 -06:00
|
|
|
|
fn as_mut_slice(self) -> &'a mut [T] { self }
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn mut_slice(self, start: uint, end: uint) -> &'a mut [T] {
|
2013-10-14 23:37:32 -05:00
|
|
|
|
assert!(start <= end);
|
|
|
|
|
assert!(end <= self.len());
|
2013-12-17 09:13:20 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute(Slice {
|
2013-12-17 09:13:20 -06:00
|
|
|
|
data: self.as_mut_ptr().offset(start as int) as *T,
|
2013-10-14 23:37:32 -05:00
|
|
|
|
len: (end - start)
|
|
|
|
|
})
|
2013-12-17 09:13:20 -06:00
|
|
|
|
}
|
2013-10-14 23:37:32 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-26 19:48:56 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn mut_slice_from(self, start: uint) -> &'a mut [T] {
|
2013-07-26 19:48:56 -05:00
|
|
|
|
let len = self.len();
|
|
|
|
|
self.mut_slice(start, len)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn mut_slice_to(self, end: uint) -> &'a mut [T] {
|
2013-07-26 19:48:56 -05:00
|
|
|
|
self.mut_slice(0, end)
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-10 08:50:24 -05:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn mut_split_at(self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
|
2013-07-10 08:50:24 -05:00
|
|
|
|
unsafe {
|
|
|
|
|
let len = self.len();
|
2013-12-10 01:16:18 -06:00
|
|
|
|
let self2: &'a mut [T] = cast::transmute_copy(&self);
|
2013-07-10 08:50:24 -05:00
|
|
|
|
(self.mut_slice(0, mid), self2.mut_slice(mid, len))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 00:12:39 -05:00
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn mut_iter(self) -> MutItems<'a, T> {
|
2013-06-06 00:12:39 -05:00
|
|
|
|
unsafe {
|
2013-12-15 06:35:12 -06:00
|
|
|
|
let p = self.as_mut_ptr();
|
2013-10-16 20:34:01 -05:00
|
|
|
|
if mem::size_of::<T>() == 0 {
|
2014-01-14 21:32:24 -06:00
|
|
|
|
MutItems{ptr: p,
|
2014-01-22 13:03:02 -06:00
|
|
|
|
end: (p as uint + self.len()) as *mut T,
|
2014-03-04 17:52:26 -06:00
|
|
|
|
marker: marker::ContravariantLifetime::<'a>,
|
2014-03-26 18:01:11 -05:00
|
|
|
|
marker2: marker::NoCopy}
|
2013-08-06 16:15:43 -05:00
|
|
|
|
} else {
|
2014-01-14 21:32:24 -06:00
|
|
|
|
MutItems{ptr: p,
|
2014-01-22 13:03:02 -06:00
|
|
|
|
end: p.offset(self.len() as int),
|
2014-03-04 17:52:26 -06:00
|
|
|
|
marker: marker::ContravariantLifetime::<'a>,
|
2014-03-26 18:01:11 -05:00
|
|
|
|
marker2: marker::NoCopy}
|
2013-08-06 16:15:43 -05:00
|
|
|
|
}
|
2013-06-06 00:12:39 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-15 13:39:08 -06:00
|
|
|
|
#[inline]
|
2014-01-26 10:24:34 -06:00
|
|
|
|
fn mut_last(self) -> Option<&'a mut T> {
|
2014-01-15 13:39:08 -06:00
|
|
|
|
let len = self.len();
|
2014-01-26 10:24:34 -06:00
|
|
|
|
if len == 0 { return None; }
|
|
|
|
|
Some(&mut self[len - 1])
|
2014-01-15 13:39:08 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-10 23:23:59 -05:00
|
|
|
|
#[inline]
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by .mut_iter().rev()"]
|
|
|
|
|
fn mut_rev_iter(self) -> Rev<MutItems<'a, T>> {
|
2014-01-23 13:41:57 -06:00
|
|
|
|
self.mut_iter().rev()
|
2013-06-07 21:39:52 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-01 11:50:34 -06:00
|
|
|
|
#[inline]
|
2014-04-07 15:30:48 -05:00
|
|
|
|
fn mut_split(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
|
2014-01-14 21:32:24 -06:00
|
|
|
|
MutSplits { v: self, pred: pred, finished: false }
|
2013-12-01 11:50:34 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-30 15:28:42 -06:00
|
|
|
|
#[inline]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T> {
|
2013-11-30 15:28:42 -06:00
|
|
|
|
assert!(chunk_size > 0);
|
2014-01-14 21:32:24 -06:00
|
|
|
|
MutChunks { v: self, chunk_size: chunk_size }
|
2013-11-30 15:28:42 -06:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-25 11:00:46 -06:00
|
|
|
|
fn mut_shift_ref(&mut self) -> Option<&'a mut T> {
|
|
|
|
|
if self.len() == 0 { return None; }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
let s: &mut Slice<T> = transmute(self);
|
2014-01-25 11:00:46 -06:00
|
|
|
|
Some(cast::transmute_mut(&*raw::shift_ptr(s)))
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-25 14:33:31 -06:00
|
|
|
|
fn mut_pop_ref(&mut self) -> Option<&'a mut T> {
|
|
|
|
|
if self.len() == 0 { return None; }
|
2013-11-16 16:29:19 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
let s: &mut Slice<T> = transmute(self);
|
2014-01-25 14:33:31 -06:00
|
|
|
|
Some(cast::transmute_mut(&*raw::pop_ptr(s)))
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-28 11:54:03 -05:00
|
|
|
|
fn swap(self, a: uint, b: uint) {
|
|
|
|
|
unsafe {
|
|
|
|
|
// Can't take two mutable loans from one vector, so instead just cast
|
|
|
|
|
// them to their raw pointers to do the swap
|
|
|
|
|
let pa: *mut T = &mut self[a];
|
|
|
|
|
let pb: *mut T = &mut self[b];
|
2014-02-14 17:42:01 -06:00
|
|
|
|
ptr::swap(pa, pb);
|
2013-06-28 11:54:03 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn reverse(self) {
|
|
|
|
|
let mut i: uint = 0;
|
|
|
|
|
let ln = self.len();
|
|
|
|
|
while i < ln / 2 {
|
|
|
|
|
self.swap(i, ln - i - 1);
|
|
|
|
|
i += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-18 16:24:26 -06:00
|
|
|
|
#[inline]
|
2013-12-19 21:42:00 -06:00
|
|
|
|
fn sort_by(self, compare: |&T, &T| -> Ordering) {
|
|
|
|
|
merge_sort(self, compare)
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for (a, b) in self.mut_iter().zip(src.mut_slice(start, end).mut_iter()) {
|
2014-01-31 14:35:36 -06:00
|
|
|
|
mem::swap(a, b);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
}
|
|
|
|
|
cmp::min(self.len(), end-start)
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
|
#[inline]
|
2014-01-21 08:34:42 -06:00
|
|
|
|
unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute((self.repr().data as *mut T).offset(index as int))
|
2013-04-18 17:53:29 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-15 06:35:12 -06:00
|
|
|
|
#[inline]
|
|
|
|
|
fn as_mut_ptr(self) -> *mut T {
|
|
|
|
|
self.repr().data as *mut T
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-18 16:45:18 -05:00
|
|
|
|
#[inline]
|
2013-07-21 19:20:52 -05:00
|
|
|
|
unsafe fn unsafe_set(self, index: uint, val: T) {
|
2013-04-18 17:53:29 -05:00
|
|
|
|
*self.unsafe_mut_ref(index) = val;
|
2013-04-17 16:19:25 -05:00
|
|
|
|
}
|
2013-07-03 01:34:17 -05:00
|
|
|
|
|
2013-12-16 06:30:56 -06:00
|
|
|
|
#[inline]
|
|
|
|
|
unsafe fn init_elem(self, i: uint, val: T) {
|
2014-02-09 00:16:42 -06:00
|
|
|
|
mem::move_val_init(&mut (*self.as_mut_ptr().offset(i as int)), val);
|
2013-12-16 06:30:56 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-16 06:35:02 -06:00
|
|
|
|
#[inline]
|
|
|
|
|
unsafe fn copy_memory(self, src: &[T]) {
|
2013-12-17 09:13:20 -06:00
|
|
|
|
let len_src = src.len();
|
|
|
|
|
assert!(self.len() >= len_src);
|
|
|
|
|
ptr::copy_nonoverlapping_memory(self.as_mut_ptr(), src.as_ptr(), len_src)
|
2013-10-14 23:37:32 -05:00
|
|
|
|
}
|
2013-04-17 16:19:25 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-06 02:20:08 -05:00
|
|
|
|
/// Trait for &[T] where T is Cloneable
|
2013-06-18 01:52:14 -05:00
|
|
|
|
pub trait MutableCloneableVector<T> {
|
2013-12-23 05:57:16 -06:00
|
|
|
|
/// Copies as many elements from `src` as it can into `self` (the
|
|
|
|
|
/// shorter of `self.len()` and `src.len()`). Returns the number
|
|
|
|
|
/// of elements copied.
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
2014-03-08 17:11:52 -06:00
|
|
|
|
/// use std::slice::MutableCloneableVector;
|
2013-12-23 05:57:16 -06:00
|
|
|
|
///
|
|
|
|
|
/// let mut dst = [0, 0, 0];
|
|
|
|
|
/// let src = [1, 2];
|
|
|
|
|
///
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(dst.copy_from(src) == 2);
|
|
|
|
|
/// assert!(dst == [1, 2, 0]);
|
2013-12-23 05:57:16 -06:00
|
|
|
|
///
|
|
|
|
|
/// let src2 = [3, 4, 5, 6];
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(dst.copy_from(src2) == 3);
|
|
|
|
|
/// assert!(dst == [3, 4, 5]);
|
2013-12-23 05:57:16 -06:00
|
|
|
|
/// ```
|
2013-06-18 01:52:14 -05:00
|
|
|
|
fn copy_from(self, &[T]) -> uint;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a, T:Clone> MutableCloneableVector<T> for &'a mut [T] {
|
2013-06-18 01:52:14 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn copy_from(self, src: &[T]) -> uint {
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for (a, b) in self.mut_iter().zip(src.iter()) {
|
2013-11-08 22:10:09 -06:00
|
|
|
|
a.clone_from(b);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
}
|
|
|
|
|
cmp::min(self.len(), src.len())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-19 06:03:11 -06:00
|
|
|
|
/// Methods for mutable vectors with orderable elements, such as
|
|
|
|
|
/// in-place sorting.
|
2013-12-19 21:42:00 -06:00
|
|
|
|
pub trait MutableTotalOrdVector<T> {
|
2013-12-19 06:03:11 -06:00
|
|
|
|
/// Sort the vector, in place.
|
|
|
|
|
///
|
2013-12-23 05:57:16 -06:00
|
|
|
|
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
|
2013-12-19 06:03:11 -06:00
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// let mut v = [-5, 4, 1, -3, 2];
|
|
|
|
|
///
|
|
|
|
|
/// v.sort();
|
2014-02-28 03:23:06 -06:00
|
|
|
|
/// assert!(v == [-5, -3, 1, 2, 4]);
|
2013-12-19 06:03:11 -06:00
|
|
|
|
/// ```
|
|
|
|
|
fn sort(self);
|
|
|
|
|
}
|
2013-12-19 21:42:00 -06:00
|
|
|
|
impl<'a, T: TotalOrd> MutableTotalOrdVector<T> for &'a mut [T] {
|
2013-12-19 06:03:11 -06:00
|
|
|
|
#[inline]
|
|
|
|
|
fn sort(self) {
|
2013-12-19 21:42:00 -06:00
|
|
|
|
self.sort_by(|a,b| a.cmp(b))
|
2013-12-19 06:03:11 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-11 17:37:37 -05:00
|
|
|
|
/**
|
|
|
|
|
* Constructs a vector from an unsafe pointer to a buffer
|
|
|
|
|
*
|
|
|
|
|
* # Arguments
|
|
|
|
|
*
|
|
|
|
|
* * ptr - An unsafe pointer to a buffer of `T`
|
|
|
|
|
* * elts - The number of elements in the buffer
|
|
|
|
|
*/
|
|
|
|
|
// Wrapper for fn in raw: needs to be called by net_tcp::on_tcp_read_cb
|
|
|
|
|
pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
|
|
|
|
|
raw::from_buf_raw(ptr, elts)
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
|
/// Unsafe operations
|
2012-12-14 17:47:11 -06:00
|
|
|
|
pub mod raw {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
use cast::transmute;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use iter::Iterator;
|
2014-02-10 15:50:42 -06:00
|
|
|
|
use ptr::RawPtr;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use ptr;
|
2014-02-16 02:04:33 -06:00
|
|
|
|
use raw::Slice;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use slice::{MutableVector, OwnedVector};
|
|
|
|
|
use vec::Vec;
|
2012-04-25 19:18:06 -05:00
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
|
/**
|
|
|
|
|
* Form a slice from a pointer and length (as a number of units,
|
|
|
|
|
* not bytes).
|
|
|
|
|
*/
|
2013-06-18 16:45:18 -05:00
|
|
|
|
#[inline]
|
2013-11-18 23:15:42 -06:00
|
|
|
|
pub unsafe fn buf_as_slice<T,U>(p: *T, len: uint, f: |v: &[T]| -> U)
|
|
|
|
|
-> U {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
f(transmute(Slice {
|
2013-10-14 23:37:32 -05:00
|
|
|
|
data: p,
|
|
|
|
|
len: len
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Form a slice from a pointer and length (as a number of units,
|
|
|
|
|
* not bytes).
|
|
|
|
|
*/
|
|
|
|
|
#[inline]
|
2013-11-18 23:15:42 -06:00
|
|
|
|
pub unsafe fn mut_buf_as_slice<T,
|
|
|
|
|
U>(
|
|
|
|
|
p: *mut T,
|
|
|
|
|
len: uint,
|
|
|
|
|
f: |v: &mut [T]| -> U)
|
|
|
|
|
-> U {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
f(transmute(Slice {
|
2013-10-14 23:37:32 -05:00
|
|
|
|
data: p as *T,
|
|
|
|
|
len: len
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-11 17:37:37 -05:00
|
|
|
|
/**
|
|
|
|
|
* Constructs a vector from an unsafe pointer to a buffer
|
|
|
|
|
*
|
|
|
|
|
* # Arguments
|
|
|
|
|
*
|
|
|
|
|
* * ptr - An unsafe pointer to a buffer of `T`
|
|
|
|
|
* * elts - The number of elements in the buffer
|
|
|
|
|
*/
|
|
|
|
|
// Was in raw, but needs to be called by net_tcp::on_tcp_read_cb
|
2013-06-18 16:45:18 -05:00
|
|
|
|
#[inline]
|
2012-10-11 17:37:37 -05:00
|
|
|
|
pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut dst = Vec::with_capacity(elts);
|
2013-12-15 06:05:30 -06:00
|
|
|
|
dst.set_len(elts);
|
2013-12-17 09:13:20 -06:00
|
|
|
|
ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
dst.move_iter().collect()
|
2012-10-11 17:37:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-16 16:29:19 -06:00
|
|
|
|
/**
|
|
|
|
|
* Returns a pointer to first element in slice and adjusts
|
|
|
|
|
* slice so it no longer contains that element. Fails if
|
|
|
|
|
* slice is empty. O(1).
|
|
|
|
|
*/
|
|
|
|
|
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> *T {
|
|
|
|
|
if slice.len == 0 { fail!("shift on empty slice"); }
|
|
|
|
|
let head: *T = slice.data;
|
2014-02-10 15:50:42 -06:00
|
|
|
|
slice.data = slice.data.offset(1);
|
2013-11-16 16:29:19 -06:00
|
|
|
|
slice.len -= 1;
|
|
|
|
|
head
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns a pointer to last element in slice and adjusts
|
|
|
|
|
* slice so it no longer contains that element. Fails if
|
|
|
|
|
* slice is empty. O(1).
|
|
|
|
|
*/
|
|
|
|
|
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> *T {
|
|
|
|
|
if slice.len == 0 { fail!("pop on empty slice"); }
|
2014-02-10 15:50:42 -06:00
|
|
|
|
let tail: *T = slice.data.offset((slice.len - 1) as int);
|
2013-11-16 16:29:19 -06:00
|
|
|
|
slice.len -= 1;
|
|
|
|
|
tail
|
|
|
|
|
}
|
2011-12-13 18:25:51 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-15 05:35:08 -06:00
|
|
|
|
/// Operations on `[u8]`.
|
2012-10-01 17:45:34 -05:00
|
|
|
|
pub mod bytes {
|
2013-12-17 09:13:20 -06:00
|
|
|
|
use container::Container;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
use slice::MutableVector;
|
2013-06-18 01:20:53 -05:00
|
|
|
|
use ptr;
|
|
|
|
|
|
2013-12-15 05:35:08 -06:00
|
|
|
|
/// A trait for operations on mutable `[u8]`s.
|
2013-06-18 01:20:53 -05:00
|
|
|
|
pub trait MutableByteVector {
|
|
|
|
|
/// Sets all bytes of the receiver to the given value.
|
2013-08-09 03:25:24 -05:00
|
|
|
|
fn set_memory(self, value: u8);
|
2013-06-18 01:20:53 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a> MutableByteVector for &'a mut [u8] {
|
2013-06-18 01:20:53 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn set_memory(self, value: u8) {
|
2013-12-17 09:13:20 -06:00
|
|
|
|
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
|
2013-06-18 01:20:53 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-01-06 09:36:56 -06:00
|
|
|
|
|
2013-12-16 07:31:59 -06:00
|
|
|
|
/// Copies data from `src` to `dst`
|
2013-12-16 07:06:13 -06:00
|
|
|
|
///
|
2013-12-16 07:31:59 -06:00
|
|
|
|
/// `src` and `dst` must not overlap. Fails if the length of `dst`
|
|
|
|
|
/// is less than the length of `src`.
|
2013-06-18 16:45:18 -05:00
|
|
|
|
#[inline]
|
2013-12-15 05:23:11 -06:00
|
|
|
|
pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
|
2013-12-16 06:35:02 -06:00
|
|
|
|
// Bound checks are done at .copy_memory.
|
|
|
|
|
unsafe { dst.copy_memory(src) }
|
2012-07-20 21:20:13 -05:00
|
|
|
|
}
|
2012-01-06 09:36:56 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-25 22:34:43 -05:00
|
|
|
|
impl<A: Clone> Clone for ~[A] {
|
2013-03-15 17:26:59 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn clone(&self) -> ~[A] {
|
2014-04-15 18:35:18 -05:00
|
|
|
|
// Use the fast to_owned on &[A] for cloning
|
|
|
|
|
self.as_slice().to_owned()
|
2013-03-15 17:26:59 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-12 13:41:34 -06:00
|
|
|
|
impl<'a, T: fmt::Show> fmt::Show for &'a [T] {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2014-04-11 14:45:51 -05:00
|
|
|
|
if f.flags & (1 << (fmt::parse::FlagAlternate as uint)) == 0 {
|
|
|
|
|
try!(write!(f.buf, "["));
|
|
|
|
|
}
|
2014-02-12 13:41:34 -06:00
|
|
|
|
let mut is_first = true;
|
|
|
|
|
for x in self.iter() {
|
|
|
|
|
if is_first {
|
|
|
|
|
is_first = false;
|
|
|
|
|
} else {
|
2014-02-19 12:07:49 -06:00
|
|
|
|
try!(write!(f.buf, ", "));
|
2014-02-12 13:41:34 -06:00
|
|
|
|
}
|
2014-02-19 12:07:49 -06:00
|
|
|
|
try!(write!(f.buf, "{}", *x))
|
2014-02-12 13:41:34 -06:00
|
|
|
|
}
|
2014-04-11 14:45:51 -05:00
|
|
|
|
if f.flags & (1 << (fmt::parse::FlagAlternate as uint)) == 0 {
|
|
|
|
|
try!(write!(f.buf, "]"));
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
2014-02-12 13:41:34 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-22 12:41:02 -05:00
|
|
|
|
impl<'a, T: fmt::Show> fmt::Show for &'a mut [T] {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
self.as_slice().fmt(f)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-12 13:41:34 -06:00
|
|
|
|
impl<T: fmt::Show> fmt::Show for ~[T] {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
self.as_slice().fmt(f)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-09 21:32:56 -05:00
|
|
|
|
// This works because every lifetime is a sub-lifetime of 'static
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a, A> Default for &'a [A] {
|
|
|
|
|
fn default() -> &'a [A] { &'a [] }
|
2013-09-09 21:32:56 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<A> Default for ~[A] {
|
|
|
|
|
fn default() -> ~[A] { ~[] }
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-04 17:52:26 -06:00
|
|
|
|
/// Immutable slice iterator
|
|
|
|
|
pub struct Items<'a, T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
ptr: *T,
|
|
|
|
|
end: *T,
|
|
|
|
|
marker: marker::ContravariantLifetime<'a>
|
2014-03-04 17:52:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Mutable slice iterator
|
|
|
|
|
pub struct MutItems<'a, T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
ptr: *mut T,
|
|
|
|
|
end: *mut T,
|
|
|
|
|
marker: marker::ContravariantLifetime<'a>,
|
|
|
|
|
marker2: marker::NoCopy
|
2014-03-04 17:52:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
|
macro_rules! iterator {
|
|
|
|
|
(struct $name:ident -> $ptr:ty, $elem:ty) => {
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a, T> Iterator<$elem> for $name<'a, T> {
|
2013-06-07 21:39:52 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn next(&mut self) -> Option<$elem> {
|
2013-07-10 23:23:59 -05:00
|
|
|
|
// could be implemented with slices, but this avoids bounds checks
|
2013-06-07 21:39:52 -05:00
|
|
|
|
unsafe {
|
|
|
|
|
if self.ptr == self.end {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
let old = self.ptr;
|
2013-10-16 20:34:01 -05:00
|
|
|
|
self.ptr = if mem::size_of::<T>() == 0 {
|
2013-08-02 08:34:11 -05:00
|
|
|
|
// purposefully don't use 'ptr.offset' because for
|
|
|
|
|
// vectors with 0-size elements this would return the
|
|
|
|
|
// same pointer.
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute(self.ptr as uint + 1)
|
2013-08-02 08:34:11 -05:00
|
|
|
|
} else {
|
2013-08-09 00:22:52 -05:00
|
|
|
|
self.ptr.offset(1)
|
2013-08-02 08:34:11 -05:00
|
|
|
|
};
|
|
|
|
|
|
2014-02-14 17:42:01 -06:00
|
|
|
|
Some(transmute(old))
|
2013-06-07 21:39:52 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-06-21 05:12:01 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
2013-07-02 20:40:46 -05:00
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2013-07-29 17:31:44 -05:00
|
|
|
|
let diff = (self.end as uint) - (self.ptr as uint);
|
2013-10-16 20:34:01 -05:00
|
|
|
|
let exact = diff / mem::nonzero_size_of::<T>();
|
2013-07-02 20:40:46 -05:00
|
|
|
|
(exact, Some(exact))
|
2013-06-21 05:12:01 -05:00
|
|
|
|
}
|
2013-06-07 21:39:52 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
|
impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
|
2013-07-10 23:23:59 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn next_back(&mut self) -> Option<$elem> {
|
|
|
|
|
// could be implemented with slices, but this avoids bounds checks
|
|
|
|
|
unsafe {
|
|
|
|
|
if self.end == self.ptr {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
2013-10-16 20:34:01 -05:00
|
|
|
|
self.end = if mem::size_of::<T>() == 0 {
|
2013-08-02 08:34:11 -05:00
|
|
|
|
// See above for why 'ptr.offset' isn't used
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute(self.end as uint - 1)
|
2013-08-02 08:34:11 -05:00
|
|
|
|
} else {
|
2013-08-09 00:22:52 -05:00
|
|
|
|
self.end.offset(-1)
|
2013-08-02 08:34:11 -05:00
|
|
|
|
};
|
2014-02-14 17:42:01 -06:00
|
|
|
|
Some(transmute(self.end))
|
2013-07-10 23:23:59 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
|
2013-07-29 19:52:01 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
fn indexable(&self) -> uint {
|
|
|
|
|
let (exact, _) = self.size_hint();
|
|
|
|
|
exact
|
|
|
|
|
}
|
2013-07-22 19:11:24 -05:00
|
|
|
|
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
2014-04-22 00:15:42 -05:00
|
|
|
|
fn idx(&mut self, index: uint) -> Option<&'a T> {
|
2013-07-29 19:52:01 -05:00
|
|
|
|
unsafe {
|
|
|
|
|
if index < self.indexable() {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
transmute(self.ptr.offset(index as int))
|
2013-07-29 19:52:01 -05:00
|
|
|
|
} else {
|
|
|
|
|
None
|
2013-07-22 19:11:24 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
iterator!{struct Items -> *T, &'a T}
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by Rev<Items<'a, T>>"]
|
2014-01-23 13:41:57 -06:00
|
|
|
|
pub type RevItems<'a, T> = Rev<Items<'a, T>>;
|
2012-06-02 21:03:28 -05:00
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> ExactSize<&'a T> for Items<'a, T> {}
|
|
|
|
|
impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
|
2013-08-30 12:59:49 -05:00
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> Clone for Items<'a, T> {
|
|
|
|
|
fn clone(&self) -> Items<'a, T> { *self }
|
2013-07-18 10:38:17 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
iterator!{struct MutItems -> *mut T, &'a mut T}
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by Rev<MutItems<'a, T>>"]
|
2014-01-23 13:41:57 -06:00
|
|
|
|
pub type RevMutItems<'a, T> = Rev<MutItems<'a, T>>;
|
2013-06-06 00:12:39 -05:00
|
|
|
|
|
2013-12-01 11:50:34 -06:00
|
|
|
|
/// An iterator over the subslices of the vector which are separated
|
|
|
|
|
/// by elements that match `pred`.
|
2014-01-14 21:32:24 -06:00
|
|
|
|
pub struct MutSplits<'a, T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
v: &'a mut [T],
|
2014-04-07 15:30:48 -05:00
|
|
|
|
pred: |t: &T|: 'a -> bool,
|
2014-03-27 17:09:47 -05:00
|
|
|
|
finished: bool
|
2013-12-01 11:50:34 -06:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next(&mut self) -> Option<&'a mut [T]> {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
if self.finished { return None; }
|
|
|
|
|
|
2014-04-22 01:25:18 -05:00
|
|
|
|
let pred = &mut self.pred;
|
|
|
|
|
match self.v.iter().position(|x| (*pred)(x)) {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
None => {
|
|
|
|
|
self.finished = true;
|
2014-01-31 14:35:36 -06:00
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2013-12-01 11:50:34 -06:00
|
|
|
|
let len = tmp.len();
|
|
|
|
|
let (head, tail) = tmp.mut_split_at(len);
|
|
|
|
|
self.v = tail;
|
|
|
|
|
Some(head)
|
|
|
|
|
}
|
|
|
|
|
Some(idx) => {
|
2014-01-31 14:35:36 -06:00
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2013-12-01 11:50:34 -06:00
|
|
|
|
let (head, tail) = tmp.mut_split_at(idx);
|
|
|
|
|
self.v = tail.mut_slice_from(1);
|
|
|
|
|
Some(head)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2013-12-11 19:51:22 -06:00
|
|
|
|
if self.finished {
|
|
|
|
|
(0, Some(0))
|
|
|
|
|
} else {
|
|
|
|
|
// if the predicate doesn't match anything, we yield one slice
|
|
|
|
|
// if it matches every element, we yield len+1 empty slices.
|
|
|
|
|
(1, Some(self.v.len() + 1))
|
|
|
|
|
}
|
2013-12-01 11:50:34 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next_back(&mut self) -> Option<&'a mut [T]> {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
if self.finished { return None; }
|
|
|
|
|
|
2014-04-22 01:25:18 -05:00
|
|
|
|
let pred = &mut self.pred;
|
|
|
|
|
match self.v.iter().rposition(|x| (*pred)(x)) {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
None => {
|
|
|
|
|
self.finished = true;
|
2014-01-31 14:35:36 -06:00
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2013-12-11 19:51:22 -06:00
|
|
|
|
Some(tmp)
|
2013-12-01 11:50:34 -06:00
|
|
|
|
}
|
|
|
|
|
Some(idx) => {
|
2014-01-31 14:35:36 -06:00
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2013-12-01 11:50:34 -06:00
|
|
|
|
let (head, tail) = tmp.mut_split_at(idx);
|
|
|
|
|
self.v = head;
|
|
|
|
|
Some(tail.mut_slice_from(1))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-30 15:28:42 -06:00
|
|
|
|
/// An iterator over a vector in (non-overlapping) mutable chunks (`size` elements at a time). When
|
|
|
|
|
/// the vector len is not evenly divided by the chunk size, the last slice of the iteration will be
|
|
|
|
|
/// the remainder.
|
2014-01-14 21:32:24 -06:00
|
|
|
|
pub struct MutChunks<'a, T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
v: &'a mut [T],
|
|
|
|
|
chunk_size: uint
|
2013-11-30 15:28:42 -06:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> {
|
2013-11-30 15:28:42 -06:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next(&mut self) -> Option<&'a mut [T]> {
|
2013-12-11 19:40:27 -06:00
|
|
|
|
if self.v.len() == 0 {
|
2013-11-30 15:28:42 -06:00
|
|
|
|
None
|
|
|
|
|
} else {
|
2013-12-11 19:40:27 -06:00
|
|
|
|
let sz = cmp::min(self.v.len(), self.chunk_size);
|
2014-01-31 14:35:36 -06:00
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2013-12-01 11:19:39 -06:00
|
|
|
|
let (head, tail) = tmp.mut_split_at(sz);
|
2013-11-30 15:28:42 -06:00
|
|
|
|
self.v = tail;
|
|
|
|
|
Some(head)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2013-12-11 19:40:27 -06:00
|
|
|
|
if self.v.len() == 0 {
|
2013-11-30 15:28:42 -06:00
|
|
|
|
(0, Some(0))
|
|
|
|
|
} else {
|
2014-02-16 14:20:01 -06:00
|
|
|
|
let (n, rem) = div_rem(self.v.len(), self.chunk_size);
|
2013-11-30 15:28:42 -06:00
|
|
|
|
let n = if rem > 0 { n + 1 } else { n };
|
|
|
|
|
(n, Some(n))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> {
|
2013-11-30 18:54:28 -06:00
|
|
|
|
#[inline]
|
2013-12-10 01:16:18 -06:00
|
|
|
|
fn next_back(&mut self) -> Option<&'a mut [T]> {
|
2013-12-11 19:40:27 -06:00
|
|
|
|
if self.v.len() == 0 {
|
2013-11-30 18:54:28 -06:00
|
|
|
|
None
|
|
|
|
|
} else {
|
2013-12-11 19:40:27 -06:00
|
|
|
|
let remainder = self.v.len() % self.chunk_size;
|
2013-11-30 18:54:28 -06:00
|
|
|
|
let sz = if remainder != 0 { remainder } else { self.chunk_size };
|
2014-01-31 14:35:36 -06:00
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2013-12-11 19:40:27 -06:00
|
|
|
|
let tmp_len = tmp.len();
|
|
|
|
|
let (head, tail) = tmp.mut_split_at(tmp_len - sz);
|
2013-11-30 18:54:28 -06:00
|
|
|
|
self.v = head;
|
|
|
|
|
Some(tail)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 10:26:44 -05:00
|
|
|
|
/// An iterator that moves out of a vector.
|
2014-01-14 21:32:24 -06:00
|
|
|
|
pub struct MoveItems<T> {
|
2014-03-27 17:09:47 -05:00
|
|
|
|
allocation: *mut u8, // the block of memory allocated for the vector
|
|
|
|
|
iter: Items<'static, T>
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<T> Iterator<T> for MoveItems<T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
2013-07-01 10:26:44 -05:00
|
|
|
|
fn next(&mut self) -> Option<T> {
|
2013-12-16 04:26:25 -06:00
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
self.iter.next().map(|x| ptr::read(x))
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-08-05 21:20:37 -05:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2013-12-16 04:26:25 -06:00
|
|
|
|
self.iter.size_hint()
|
2013-08-05 21:20:37 -05:00
|
|
|
|
}
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
|
|
|
|
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<T> DoubleEndedIterator<T> for MoveItems<T> {
|
2013-08-05 21:20:37 -05:00
|
|
|
|
#[inline]
|
2013-12-16 04:26:25 -06:00
|
|
|
|
fn next_back(&mut self) -> Option<T> {
|
|
|
|
|
unsafe {
|
2014-02-14 17:42:01 -06:00
|
|
|
|
self.iter.next_back().map(|x| ptr::read(x))
|
2013-12-16 04:26:25 -06:00
|
|
|
|
}
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
2013-12-16 04:26:25 -06:00
|
|
|
|
}
|
2013-08-05 21:20:37 -05:00
|
|
|
|
|
2013-12-16 04:26:25 -06:00
|
|
|
|
#[unsafe_destructor]
|
2014-01-14 21:32:24 -06:00
|
|
|
|
impl<T> Drop for MoveItems<T> {
|
2014-01-14 01:46:58 -06:00
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
// destroy the remaining elements
|
|
|
|
|
for _x in *self {}
|
|
|
|
|
unsafe {
|
2013-12-12 15:27:26 -06:00
|
|
|
|
exchange_free(self.allocation as *u8)
|
2014-01-14 01:46:58 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-16 04:26:25 -06:00
|
|
|
|
/// An iterator that moves out of a vector in reverse order.
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
#[deprecated = "replaced by Rev<MoveItems<'a, T>>"]
|
2014-01-23 13:41:57 -06:00
|
|
|
|
pub type RevMoveItems<T> = Rev<MoveItems<T>>;
|
2013-12-16 04:26:25 -06:00
|
|
|
|
|
std: Move the iterator param on FromIterator and Extendable to the method.
If they are on the trait then it is extremely annoying to use them as
generic parameters to a function, e.g. with the iterator param on the trait
itself, if one was to pass an Extendable<int> to a function that filled it
either from a Range or a Map<VecIterator>, one needs to write something
like:
fn foo<E: Extendable<int, Range<int>> +
Extendable<int, Map<&'self int, int, VecIterator<int>>>
(e: &mut E, ...) { ... }
since using a generic, i.e. `foo<E: Extendable<int, I>, I: Iterator<int>>`
means that `foo` takes 2 type parameters, and the caller has to specify them
(which doesn't work anyway, as they'll mismatch with the iterators used in
`foo` itself).
This patch changes it to:
fn foo<E: Extendable<int>>(e: &mut E, ...) { ... }
2013-08-13 08:08:14 -05:00
|
|
|
|
impl<A> FromIterator<A> for ~[A] {
|
2014-03-30 23:45:55 -05:00
|
|
|
|
fn from_iter<T: Iterator<A>>(mut iterator: T) -> ~[A] {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut xs: Vec<A> = iterator.collect();
|
2013-06-25 16:07:44 -05:00
|
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
|
// Must shrink so the capacity is the same as the length. The length of
|
|
|
|
|
// the ~[T] vector must exactly match the length of the allocation.
|
|
|
|
|
xs.shrink_to_fit();
|
|
|
|
|
|
|
|
|
|
let len = xs.len();
|
|
|
|
|
assert!(len == xs.capacity());
|
|
|
|
|
let data = xs.as_mut_ptr();
|
|
|
|
|
|
|
|
|
|
let data_size = len.checked_mul(&mem::size_of::<A>());
|
|
|
|
|
let data_size = data_size.expect("overflow in from_iter()");
|
|
|
|
|
let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
|
|
|
|
|
let size = size.expect("overflow in from_iter()");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is some terribly awful code. Note that all of this will go away
|
|
|
|
|
// with DST because creating ~[T] from Vec<T> will just be some pointer
|
|
|
|
|
// swizzling.
|
|
|
|
|
unsafe {
|
|
|
|
|
let ret = malloc_raw(size) as *mut RawVec<()>;
|
|
|
|
|
|
|
|
|
|
(*ret).fill = len * mem::nonzero_size_of::<A>();
|
|
|
|
|
(*ret).alloc = len * mem::nonzero_size_of::<A>();
|
|
|
|
|
ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
|
|
|
|
|
data as *u8,
|
|
|
|
|
data_size);
|
|
|
|
|
xs.set_len(0); // ownership has been transferred
|
|
|
|
|
cast::transmute(ret)
|
2013-07-27 16:41:30 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
2014-01-07 00:33:37 -06:00
|
|
|
|
use prelude::*;
|
2013-10-16 20:34:01 -05:00
|
|
|
|
use mem;
|
2014-03-08 17:11:52 -06:00
|
|
|
|
use slice::*;
|
2013-03-01 21:07:12 -06:00
|
|
|
|
use cmp::*;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
use rand::{Rng, task_rng};
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
2013-03-09 15:41:43 -06:00
|
|
|
|
fn square(n: uint) -> uint { n * n }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
2013-03-21 23:20:48 -05:00
|
|
|
|
fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
|
|
#[test]
|
2012-06-24 22:18:18 -05:00
|
|
|
|
fn test_unsafe_ptrs() {
|
|
|
|
|
unsafe {
|
|
|
|
|
// Test on-stack copy-from-buf.
|
2012-06-29 18:26:56 -05:00
|
|
|
|
let a = ~[1, 2, 3];
|
2013-12-15 06:35:12 -06:00
|
|
|
|
let mut ptr = a.as_ptr();
|
2012-10-11 18:18:36 -05:00
|
|
|
|
let b = from_buf(ptr, 3u);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(b.len(), 3u);
|
|
|
|
|
assert_eq!(b[0], 1);
|
|
|
|
|
assert_eq!(b[1], 2);
|
|
|
|
|
assert_eq!(b[2], 3);
|
2012-06-24 22:18:18 -05:00
|
|
|
|
|
|
|
|
|
// Test on-heap copy-from-buf.
|
2012-06-29 18:26:56 -05:00
|
|
|
|
let c = ~[1, 2, 3, 4, 5];
|
2013-12-15 06:35:12 -06:00
|
|
|
|
ptr = c.as_ptr();
|
2012-10-11 18:18:36 -05:00
|
|
|
|
let d = from_buf(ptr, 5u);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(d.len(), 5u);
|
|
|
|
|
assert_eq!(d[0], 1);
|
|
|
|
|
assert_eq!(d[1], 2);
|
|
|
|
|
assert_eq!(d[2], 3);
|
|
|
|
|
assert_eq!(d[3], 4);
|
|
|
|
|
assert_eq!(d[4], 5);
|
2012-06-24 22:18:18 -05:00
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2012-03-12 17:52:30 -05:00
|
|
|
|
fn test_from_fn() {
|
|
|
|
|
// Test on-stack from_fn.
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::from_fn(3u, square);
|
|
|
|
|
{
|
|
|
|
|
let v = v.as_slice();
|
|
|
|
|
assert_eq!(v.len(), 3u);
|
|
|
|
|
assert_eq!(v[0], 0u);
|
|
|
|
|
assert_eq!(v[1], 1u);
|
|
|
|
|
assert_eq!(v[2], 4u);
|
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
2012-03-12 17:52:30 -05:00
|
|
|
|
// Test on-heap from_fn.
|
2014-04-17 17:28:14 -05:00
|
|
|
|
v = Vec::from_fn(5u, square);
|
|
|
|
|
{
|
|
|
|
|
let v = v.as_slice();
|
|
|
|
|
assert_eq!(v.len(), 5u);
|
|
|
|
|
assert_eq!(v[0], 0u);
|
|
|
|
|
assert_eq!(v[1], 1u);
|
|
|
|
|
assert_eq!(v[2], 4u);
|
|
|
|
|
assert_eq!(v[3], 9u);
|
|
|
|
|
assert_eq!(v[4], 16u);
|
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2012-03-12 17:52:30 -05:00
|
|
|
|
fn test_from_elem() {
|
|
|
|
|
// Test on-stack from_elem.
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::from_elem(2u, 10u);
|
|
|
|
|
{
|
|
|
|
|
let v = v.as_slice();
|
|
|
|
|
assert_eq!(v.len(), 2u);
|
|
|
|
|
assert_eq!(v[0], 10u);
|
|
|
|
|
assert_eq!(v[1], 10u);
|
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
2012-03-12 17:52:30 -05:00
|
|
|
|
// Test on-heap from_elem.
|
2014-04-17 17:28:14 -05:00
|
|
|
|
v = Vec::from_elem(6u, 20u);
|
|
|
|
|
{
|
|
|
|
|
let v = v.as_slice();
|
|
|
|
|
assert_eq!(v[0], 20u);
|
|
|
|
|
assert_eq!(v[1], 20u);
|
|
|
|
|
assert_eq!(v[2], 20u);
|
|
|
|
|
assert_eq!(v[3], 20u);
|
|
|
|
|
assert_eq!(v[4], 20u);
|
|
|
|
|
assert_eq!(v[5], 20u);
|
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_is_empty() {
|
2013-06-08 20:38:47 -05:00
|
|
|
|
let xs: [int, ..0] = [];
|
|
|
|
|
assert!(xs.is_empty());
|
|
|
|
|
assert!(![0].is_empty());
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-08 02:24:43 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_len_divzero() {
|
2013-03-22 20:52:04 -05:00
|
|
|
|
type Z = [i8, ..0];
|
2013-01-08 02:24:43 -06:00
|
|
|
|
let v0 : &[Z] = &[];
|
|
|
|
|
let v1 : &[Z] = &[[]];
|
|
|
|
|
let v2 : &[Z] = &[[], []];
|
2013-10-16 20:34:01 -05:00
|
|
|
|
assert_eq!(mem::size_of::<Z>(), 0);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v0.len(), 0);
|
|
|
|
|
assert_eq!(v1.len(), 1);
|
|
|
|
|
assert_eq!(v2.len(), 2);
|
2013-01-08 02:24:43 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 10:59:00 -05:00
|
|
|
|
#[test]
|
2013-12-23 07:38:02 -06:00
|
|
|
|
fn test_get() {
|
2013-09-29 10:59:00 -05:00
|
|
|
|
let mut a = ~[11];
|
2013-12-23 07:38:02 -06:00
|
|
|
|
assert_eq!(a.get(1), None);
|
2013-09-29 10:59:00 -05:00
|
|
|
|
a = ~[11, 12];
|
2013-12-23 07:38:02 -06:00
|
|
|
|
assert_eq!(a.get(1).unwrap(), &12);
|
2013-09-29 10:59:00 -05:00
|
|
|
|
a = ~[11, 12, 13];
|
2013-12-23 07:38:02 -06:00
|
|
|
|
assert_eq!(a.get(1).unwrap(), &12);
|
2013-09-29 10:59:00 -05:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_head() {
|
2013-03-02 23:49:50 -06:00
|
|
|
|
let mut a = ~[];
|
2013-12-23 07:46:54 -06:00
|
|
|
|
assert_eq!(a.head(), None);
|
2013-03-02 23:49:50 -06:00
|
|
|
|
a = ~[11];
|
2013-12-23 07:46:54 -06:00
|
|
|
|
assert_eq!(a.head().unwrap(), &11);
|
2013-03-02 23:49:50 -06:00
|
|
|
|
a = ~[11, 12];
|
2013-12-23 07:46:54 -06:00
|
|
|
|
assert_eq!(a.head().unwrap(), &11);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_tail() {
|
2012-06-29 18:26:56 -05:00
|
|
|
|
let mut a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.tail(), &[]);
|
2012-06-29 18:26:56 -05:00
|
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.tail(), &[12]);
|
2013-03-03 09:22:40 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_tail_empty() {
|
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
|
a.tail();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_tailn() {
|
|
|
|
|
let mut a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.tailn(0), &[11, 12, 13]);
|
2013-03-03 09:22:40 -06:00
|
|
|
|
a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.tailn(2), &[13]);
|
2013-03-03 09:22:40 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_tailn_empty() {
|
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
|
a.tailn(2);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-03-03 10:06:31 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_init() {
|
|
|
|
|
let mut a = ~[11];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.init(), &[]);
|
2013-03-03 10:06:31 -06:00
|
|
|
|
a = ~[11, 12];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.init(), &[11]);
|
2013-03-03 10:06:31 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-05 21:16:47 -06:00
|
|
|
|
#[test]
|
2013-03-03 10:06:31 -06:00
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_init_empty() {
|
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
|
a.init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_initn() {
|
|
|
|
|
let mut a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.initn(0), &[11, 12, 13]);
|
2013-03-03 10:06:31 -06:00
|
|
|
|
a = ~[11, 12, 13];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(a.initn(2), &[11]);
|
2013-03-03 10:06:31 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-05 21:16:47 -06:00
|
|
|
|
#[test]
|
2013-03-03 10:06:31 -06:00
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_initn_empty() {
|
|
|
|
|
let a: ~[int] = ~[];
|
|
|
|
|
a.initn(2);
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_last() {
|
2013-03-05 21:39:18 -06:00
|
|
|
|
let mut a = ~[];
|
2013-12-23 08:08:23 -06:00
|
|
|
|
assert_eq!(a.last(), None);
|
2013-03-05 21:39:18 -06:00
|
|
|
|
a = ~[11];
|
2013-12-23 08:08:23 -06:00
|
|
|
|
assert_eq!(a.last().unwrap(), &11);
|
2013-03-05 21:39:18 -06:00
|
|
|
|
a = ~[11, 12];
|
2013-12-23 08:08:23 -06:00
|
|
|
|
assert_eq!(a.last().unwrap(), &12);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_slice() {
|
2013-02-08 13:28:20 -06:00
|
|
|
|
// Test fixed length vector.
|
|
|
|
|
let vec_fixed = [1, 2, 3, 4];
|
2013-06-27 04:48:50 -05:00
|
|
|
|
let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v_a.len(), 3u);
|
|
|
|
|
assert_eq!(v_a[0], 2);
|
|
|
|
|
assert_eq!(v_a[1], 3);
|
|
|
|
|
assert_eq!(v_a[2], 4);
|
2013-02-08 13:28:20 -06:00
|
|
|
|
|
|
|
|
|
// Test on stack.
|
|
|
|
|
let vec_stack = &[1, 2, 3];
|
2013-06-27 04:48:50 -05:00
|
|
|
|
let v_b = vec_stack.slice(1u, 3u).to_owned();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v_b.len(), 2u);
|
|
|
|
|
assert_eq!(v_b[0], 2);
|
|
|
|
|
assert_eq!(v_b[1], 3);
|
2013-02-08 13:28:20 -06:00
|
|
|
|
|
|
|
|
|
// Test on exchange heap.
|
|
|
|
|
let vec_unique = ~[1, 2, 3, 4, 5, 6];
|
2013-06-27 04:48:50 -05:00
|
|
|
|
let v_d = vec_unique.slice(1u, 6u).to_owned();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v_d.len(), 5u);
|
|
|
|
|
assert_eq!(v_d[0], 2);
|
|
|
|
|
assert_eq!(v_d[1], 3);
|
|
|
|
|
assert_eq!(v_d[2], 4);
|
|
|
|
|
assert_eq!(v_d[3], 5);
|
|
|
|
|
assert_eq!(v_d[4], 6);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-21 08:39:01 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_slice_from() {
|
|
|
|
|
let vec = &[1, 2, 3, 4];
|
|
|
|
|
assert_eq!(vec.slice_from(0), vec);
|
|
|
|
|
assert_eq!(vec.slice_from(2), &[3, 4]);
|
|
|
|
|
assert_eq!(vec.slice_from(4), &[]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_slice_to() {
|
|
|
|
|
let vec = &[1, 2, 3, 4];
|
|
|
|
|
assert_eq!(vec.slice_to(4), vec);
|
|
|
|
|
assert_eq!(vec.slice_to(2), &[1, 2]);
|
|
|
|
|
assert_eq!(vec.slice_to(0), &[]);
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
2012-08-22 21:09:34 -05:00
|
|
|
|
#[test]
|
2013-12-23 09:20:52 -06:00
|
|
|
|
fn test_pop() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![5];
|
2013-12-23 09:20:52 -06:00
|
|
|
|
let e = v.pop();
|
2013-07-05 13:32:25 -05:00
|
|
|
|
assert_eq!(v.len(), 0);
|
|
|
|
|
assert_eq!(e, Some(5));
|
2013-12-23 09:20:52 -06:00
|
|
|
|
let f = v.pop();
|
2013-07-05 13:32:25 -05:00
|
|
|
|
assert_eq!(f, None);
|
2013-12-23 09:20:52 -06:00
|
|
|
|
let g = v.pop();
|
2013-07-05 13:32:25 -05:00
|
|
|
|
assert_eq!(g, None);
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-19 08:12:56 -06:00
|
|
|
|
#[test]
|
2012-08-22 21:09:34 -05:00
|
|
|
|
fn test_swap_remove() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![1, 2, 3, 4, 5];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
let mut e = v.swap_remove(0);
|
2014-02-22 17:56:38 -06:00
|
|
|
|
assert_eq!(e, Some(1));
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(v, vec![5, 2, 3, 4]);
|
2014-02-22 17:56:38 -06:00
|
|
|
|
e = v.swap_remove(3);
|
|
|
|
|
assert_eq!(e, Some(4));
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(v, vec![5, 2, 3]);
|
2014-02-22 17:56:38 -06:00
|
|
|
|
|
2012-09-28 00:20:47 -05:00
|
|
|
|
e = v.swap_remove(3);
|
2014-02-22 17:56:38 -06:00
|
|
|
|
assert_eq!(e, None);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(v, vec![5, 2, 3]);
|
2012-08-22 21:09:34 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_swap_remove_noncopyable() {
|
|
|
|
|
// Tests that we don't accidentally run destructors twice.
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![::unstable::sync::Exclusive::new(()),
|
|
|
|
|
::unstable::sync::Exclusive::new(()),
|
|
|
|
|
::unstable::sync::Exclusive::new(())];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
let mut _e = v.swap_remove(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 2);
|
2012-09-28 00:20:47 -05:00
|
|
|
|
_e = v.swap_remove(1);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 1);
|
2012-09-28 00:20:47 -05:00
|
|
|
|
_e = v.swap_remove(0);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 0);
|
2012-08-22 21:09:34 -05:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_push() {
|
|
|
|
|
// Test on-stack push().
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![];
|
2012-09-26 19:33:34 -05:00
|
|
|
|
v.push(1);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 1u);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(v.as_slice()[0], 1);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
|
|
// Test on-heap push().
|
2012-09-26 19:33:34 -05:00
|
|
|
|
v.push(2);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 2u);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(v.as_slice()[0], 1);
|
|
|
|
|
assert_eq!(v.as_slice()[1], 2);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_grow() {
|
|
|
|
|
// Test on-stack grow().
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v.grow(2u, &1);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
{
|
|
|
|
|
let v = v.as_slice();
|
|
|
|
|
assert_eq!(v.len(), 2u);
|
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
|
assert_eq!(v[1], 1);
|
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
|
|
|
|
// Test on-heap grow().
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v.grow(3u, &2);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
{
|
|
|
|
|
let v = v.as_slice();
|
|
|
|
|
assert_eq!(v.len(), 5u);
|
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
|
assert_eq!(v[1], 1);
|
|
|
|
|
assert_eq!(v[2], 2);
|
|
|
|
|
assert_eq!(v[3], 2);
|
|
|
|
|
assert_eq!(v[4], 2);
|
|
|
|
|
}
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_grow_fn() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v.grow_fn(3u, square);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let v = v.as_slice();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 3u);
|
|
|
|
|
assert_eq!(v[0], 0u);
|
|
|
|
|
assert_eq!(v[1], 1u);
|
|
|
|
|
assert_eq!(v[2], 4u);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_grow_set() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![1, 2, 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v.grow_set(4u, &4, 5);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let v = v.as_slice();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 5u);
|
|
|
|
|
assert_eq!(v[0], 1);
|
|
|
|
|
assert_eq!(v[1], 2);
|
|
|
|
|
assert_eq!(v[2], 3);
|
|
|
|
|
assert_eq!(v[3], 4);
|
|
|
|
|
assert_eq!(v[4], 5);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-08-29 03:21:49 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_truncate() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![~6,~5,~4];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v.truncate(1);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let v = v.as_slice();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 1);
|
|
|
|
|
assert_eq!(*(v[0]), 6);
|
2012-08-29 03:21:49 -05:00
|
|
|
|
// If the unsafe block didn't drop things properly, we blow up here.
|
|
|
|
|
}
|
2013-01-24 22:08:16 -06:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_clear() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![~6,~5,~4];
|
2013-01-24 22:08:16 -06:00
|
|
|
|
v.clear();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 0);
|
2013-01-24 22:08:16 -06:00
|
|
|
|
// If the unsafe block didn't drop things properly, we blow up here.
|
|
|
|
|
}
|
2012-08-29 03:21:49 -05:00
|
|
|
|
|
2012-09-01 14:11:54 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_dedup() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
fn case(a: Vec<uint>, b: Vec<uint>) {
|
2012-12-12 17:38:50 -06:00
|
|
|
|
let mut v = a;
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v.dedup();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v, b);
|
2012-09-01 14:11:54 -05:00
|
|
|
|
}
|
2014-04-17 17:28:14 -05:00
|
|
|
|
case(vec![], vec![]);
|
|
|
|
|
case(vec![1], vec![1]);
|
|
|
|
|
case(vec![1,1], vec![1]);
|
|
|
|
|
case(vec![1,2,3], vec![1,2,3]);
|
|
|
|
|
case(vec![1,1,2,3], vec![1,2,3]);
|
|
|
|
|
case(vec![1,2,2,3], vec![1,2,3]);
|
|
|
|
|
case(vec![1,2,3,3], vec![1,2,3]);
|
|
|
|
|
case(vec![1,1,2,2,2,3,3], vec![1,2,3]);
|
2012-09-01 14:11:54 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_dedup_unique() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v0 = vec![~1, ~1, ~2, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v0.dedup();
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v1 = vec![~1, ~2, ~2, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v1.dedup();
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v2 = vec![~1, ~2, ~3, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v2.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
|
/*
|
|
|
|
|
* If the ~pointers were leaked or otherwise misused, valgrind and/or
|
|
|
|
|
* rustrt should raise errors.
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_dedup_shared() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v0 = vec![~1, ~1, ~2, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v0.dedup();
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v1 = vec![~1, ~2, ~2, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v1.dedup();
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v2 = vec![~1, ~2, ~3, ~3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
v2.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
|
/*
|
2013-12-21 19:50:54 -06:00
|
|
|
|
* If the pointers were leaked or otherwise misused, valgrind and/or
|
2012-09-01 14:11:54 -05:00
|
|
|
|
* rustrt should raise errors.
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-14 01:10:54 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_retain() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![1, 2, 3, 4, 5];
|
2013-01-14 01:10:54 -06:00
|
|
|
|
v.retain(is_odd);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(v, vec![1, 3, 5]);
|
2013-01-14 01:10:54 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_zip_unzip() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let z1 = vec![(1, 4), (2, 5), (3, 6)];
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
2013-09-08 21:46:32 -05:00
|
|
|
|
let (left, right) = unzip(z1.iter().map(|&x| x));
|
2012-01-17 19:28:21 -06:00
|
|
|
|
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!((1, 4), (left[0], right[0]));
|
|
|
|
|
assert_eq!((2, 5), (left[1], right[1]));
|
|
|
|
|
assert_eq!((3, 6), (left[2], right[2]));
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_element_swaps() {
|
|
|
|
|
let mut v = [1, 2, 3];
|
|
|
|
|
for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
|
|
|
|
|
v.swap(a, b);
|
|
|
|
|
match i {
|
2014-02-28 03:23:06 -06:00
|
|
|
|
0 => assert!(v == [1, 3, 2]),
|
|
|
|
|
1 => assert!(v == [3, 1, 2]),
|
|
|
|
|
2 => assert!(v == [3, 2, 1]),
|
|
|
|
|
3 => assert!(v == [2, 3, 1]),
|
|
|
|
|
4 => assert!(v == [2, 1, 3]),
|
|
|
|
|
5 => assert!(v == [1, 2, 3]),
|
2013-10-21 15:08:31 -05:00
|
|
|
|
_ => fail!(),
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_permutations() {
|
|
|
|
|
{
|
|
|
|
|
let v: [int, ..0] = [];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
let mut it = v.permutations();
|
2014-04-25 15:19:53 -05:00
|
|
|
|
let (min_size, max_opt) = it.size_hint();
|
|
|
|
|
assert_eq!(min_size, 1);
|
|
|
|
|
assert_eq!(max_opt.unwrap(), 1);
|
|
|
|
|
assert_eq!(it.next(), Some(v.as_slice().to_owned()));
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
assert_eq!(it.next(), None);
|
|
|
|
|
}
|
|
|
|
|
{
|
2014-04-15 20:17:48 -05:00
|
|
|
|
let v = ["Hello".to_owned()];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
let mut it = v.permutations();
|
2014-04-25 15:19:53 -05:00
|
|
|
|
let (min_size, max_opt) = it.size_hint();
|
|
|
|
|
assert_eq!(min_size, 1);
|
|
|
|
|
assert_eq!(max_opt.unwrap(), 1);
|
|
|
|
|
assert_eq!(it.next(), Some(v.as_slice().to_owned()));
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
assert_eq!(it.next(), None);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
let v = [1, 2, 3];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
let mut it = v.permutations();
|
2014-04-25 15:19:53 -05:00
|
|
|
|
let (min_size, max_opt) = it.size_hint();
|
|
|
|
|
assert_eq!(min_size, 3*2);
|
|
|
|
|
assert_eq!(max_opt.unwrap(), 3*2);
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
assert_eq!(it.next(), Some(~[1,2,3]));
|
|
|
|
|
assert_eq!(it.next(), Some(~[1,3,2]));
|
|
|
|
|
assert_eq!(it.next(), Some(~[3,1,2]));
|
2014-04-25 15:19:53 -05:00
|
|
|
|
let (min_size, max_opt) = it.size_hint();
|
|
|
|
|
assert_eq!(min_size, 3);
|
|
|
|
|
assert_eq!(max_opt.unwrap(), 3);
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
assert_eq!(it.next(), Some(~[3,2,1]));
|
|
|
|
|
assert_eq!(it.next(), Some(~[2,3,1]));
|
|
|
|
|
assert_eq!(it.next(), Some(~[2,1,3]));
|
|
|
|
|
assert_eq!(it.next(), None);
|
|
|
|
|
}
|
|
|
|
|
{
|
2014-02-19 21:29:58 -06:00
|
|
|
|
// check that we have N! permutations
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
let v = ['A', 'B', 'C', 'D', 'E', 'F'];
|
2014-02-19 21:29:58 -06:00
|
|
|
|
let mut amt = 0;
|
2014-04-25 15:19:53 -05:00
|
|
|
|
let mut it = v.permutations();
|
|
|
|
|
let (min_size, max_opt) = it.size_hint();
|
|
|
|
|
for _perm in it {
|
2014-02-19 21:29:58 -06:00
|
|
|
|
amt += 1;
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
2014-04-25 15:19:53 -05:00
|
|
|
|
assert_eq!(amt, it.swaps.swaps_made);
|
|
|
|
|
assert_eq!(amt, min_size);
|
2014-02-19 21:29:58 -06:00
|
|
|
|
assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
|
2014-04-25 15:19:53 -05:00
|
|
|
|
assert_eq!(amt, max_opt.unwrap());
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[test]
|
2012-03-18 19:14:43 -05:00
|
|
|
|
fn test_position_elem() {
|
2013-06-28 11:08:32 -05:00
|
|
|
|
assert!([].position_elem(&1).is_none());
|
2012-01-26 10:39:45 -06:00
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
|
let v1 = ~[1, 2, 3, 3, 2, 5];
|
2013-06-28 11:08:32 -05:00
|
|
|
|
assert_eq!(v1.position_elem(&1), Some(0u));
|
|
|
|
|
assert_eq!(v1.position_elem(&2), Some(1u));
|
|
|
|
|
assert_eq!(v1.position_elem(&5), Some(5u));
|
|
|
|
|
assert!(v1.position_elem(&4).is_none());
|
2012-01-26 20:14:27 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-04 15:52:18 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_bsearch_elem() {
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([1,2,3,4,5].bsearch_elem(&5), Some(4));
|
|
|
|
|
assert_eq!([1,2,3,4,5].bsearch_elem(&4), Some(3));
|
|
|
|
|
assert_eq!([1,2,3,4,5].bsearch_elem(&3), Some(2));
|
|
|
|
|
assert_eq!([1,2,3,4,5].bsearch_elem(&2), Some(1));
|
|
|
|
|
assert_eq!([1,2,3,4,5].bsearch_elem(&1), Some(0));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([2,4,6,8,10].bsearch_elem(&1), None);
|
|
|
|
|
assert_eq!([2,4,6,8,10].bsearch_elem(&5), None);
|
|
|
|
|
assert_eq!([2,4,6,8,10].bsearch_elem(&4), Some(1));
|
|
|
|
|
assert_eq!([2,4,6,8,10].bsearch_elem(&10), Some(4));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([2,4,6,8].bsearch_elem(&1), None);
|
|
|
|
|
assert_eq!([2,4,6,8].bsearch_elem(&5), None);
|
|
|
|
|
assert_eq!([2,4,6,8].bsearch_elem(&4), Some(1));
|
|
|
|
|
assert_eq!([2,4,6,8].bsearch_elem(&8), Some(3));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([2,4,6].bsearch_elem(&1), None);
|
|
|
|
|
assert_eq!([2,4,6].bsearch_elem(&5), None);
|
|
|
|
|
assert_eq!([2,4,6].bsearch_elem(&4), Some(1));
|
|
|
|
|
assert_eq!([2,4,6].bsearch_elem(&6), Some(2));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([2,4].bsearch_elem(&1), None);
|
|
|
|
|
assert_eq!([2,4].bsearch_elem(&5), None);
|
|
|
|
|
assert_eq!([2,4].bsearch_elem(&2), Some(0));
|
|
|
|
|
assert_eq!([2,4].bsearch_elem(&4), Some(1));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([2].bsearch_elem(&1), None);
|
|
|
|
|
assert_eq!([2].bsearch_elem(&5), None);
|
|
|
|
|
assert_eq!([2].bsearch_elem(&2), Some(0));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([].bsearch_elem(&1), None);
|
|
|
|
|
assert_eq!([].bsearch_elem(&5), None);
|
2013-01-08 10:44:31 -06:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert!([1,1,1,1,1].bsearch_elem(&1) != None);
|
|
|
|
|
assert!([1,1,1,1,2].bsearch_elem(&1) != None);
|
|
|
|
|
assert!([1,1,1,2,2].bsearch_elem(&1) != None);
|
|
|
|
|
assert!([1,1,2,2,2].bsearch_elem(&1) != None);
|
|
|
|
|
assert_eq!([1,2,2,2,2].bsearch_elem(&1), Some(0));
|
2013-01-08 10:44:31 -06:00
|
|
|
|
|
2013-06-28 22:35:25 -05:00
|
|
|
|
assert_eq!([1,2,3,4,5].bsearch_elem(&6), None);
|
|
|
|
|
assert_eq!([1,2,3,4,5].bsearch_elem(&0), None);
|
2013-01-04 15:52:18 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[test]
|
2013-07-01 21:58:23 -05:00
|
|
|
|
fn test_reverse() {
|
2013-02-12 17:34:48 -06:00
|
|
|
|
let mut v: ~[int] = ~[10, 20];
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v[0], 10);
|
|
|
|
|
assert_eq!(v[1], 20);
|
2013-06-28 11:54:03 -05:00
|
|
|
|
v.reverse();
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v[0], 20);
|
|
|
|
|
assert_eq!(v[1], 10);
|
2013-07-01 21:58:23 -05:00
|
|
|
|
|
2013-02-12 17:34:48 -06:00
|
|
|
|
let mut v3: ~[int] = ~[];
|
2013-06-28 11:54:03 -05:00
|
|
|
|
v3.reverse();
|
2013-07-01 21:58:23 -05:00
|
|
|
|
assert!(v3.is_empty());
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-18 16:24:26 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_sort() {
|
2014-03-27 07:00:46 -05:00
|
|
|
|
use realstd::slice::Vector;
|
|
|
|
|
use realstd::clone::Clone;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
for len in range(4u, 25) {
|
|
|
|
|
for _ in range(0, 100) {
|
|
|
|
|
let mut v = task_rng().gen_vec::<uint>(len);
|
2013-12-19 06:03:11 -06:00
|
|
|
|
let mut v1 = v.clone();
|
2013-12-19 21:42:00 -06:00
|
|
|
|
|
2014-03-27 07:00:46 -05:00
|
|
|
|
v.as_mut_slice().sort();
|
|
|
|
|
assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
|
2013-12-19 06:03:11 -06:00
|
|
|
|
|
2014-03-27 07:00:46 -05:00
|
|
|
|
v1.as_mut_slice().sort_by(|a, b| a.cmp(b));
|
|
|
|
|
assert!(v1.as_slice().windows(2).all(|w| w[0] <= w[1]));
|
2013-12-19 06:03:11 -06:00
|
|
|
|
|
2014-03-27 07:00:46 -05:00
|
|
|
|
v1.as_mut_slice().sort_by(|a, b| b.cmp(a));
|
|
|
|
|
assert!(v1.as_slice().windows(2).all(|w| w[0] >= w[1]));
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// shouldn't fail/crash
|
|
|
|
|
let mut v: [uint, .. 0] = [];
|
2013-12-19 21:42:00 -06:00
|
|
|
|
v.sort();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
2014-02-26 14:55:23 -06:00
|
|
|
|
let mut v = [0xDEADBEEFu];
|
2013-12-19 21:42:00 -06:00
|
|
|
|
v.sort();
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(v == [0xDEADBEEF]);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_sort_stability() {
|
|
|
|
|
for len in range(4, 25) {
|
|
|
|
|
for _ in range(0 , 10) {
|
|
|
|
|
let mut counts = [0, .. 10];
|
|
|
|
|
|
|
|
|
|
// create a vector like [(6, 1), (5, 1), (6, 2), ...],
|
|
|
|
|
// where the first item of each tuple is random, but
|
|
|
|
|
// the second item represents which occurrence of that
|
|
|
|
|
// number this element is, i.e. the second elements
|
|
|
|
|
// will occur in sorted order.
|
|
|
|
|
let mut v = range(0, len).map(|_| {
|
|
|
|
|
let n = task_rng().gen::<uint>() % 10;
|
|
|
|
|
counts[n] += 1;
|
|
|
|
|
(n, counts[n])
|
2014-03-22 18:18:37 -05:00
|
|
|
|
}).collect::<~[(uint, int)]>();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
|
|
// only sort on the first element, so an unstable sort
|
|
|
|
|
// may mix up the counts.
|
2013-12-19 21:42:00 -06:00
|
|
|
|
v.sort_by(|&(a,_), &(b,_)| a.cmp(&b));
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
|
|
// this comparison includes the count (the second item
|
|
|
|
|
// of the tuple), so elements with equal first items
|
|
|
|
|
// will need to be ordered with increasing
|
|
|
|
|
// counts... i.e. exactly asserting that this sort is
|
|
|
|
|
// stable.
|
|
|
|
|
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-07 10:49:41 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_partition() {
|
2013-06-27 09:10:18 -05:00
|
|
|
|
assert_eq!((~[]).partition(|x: &int| *x < 3), (~[], ~[]));
|
|
|
|
|
assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
|
|
|
|
|
assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 2), (~[1], ~[2, 3]));
|
|
|
|
|
assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
|
2013-01-07 10:49:41 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_partitioned() {
|
2013-05-23 11:39:17 -05:00
|
|
|
|
assert_eq!(([]).partitioned(|x: &int| *x < 3), (~[], ~[]))
|
|
|
|
|
assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
|
|
|
|
|
assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (~[1], ~[2, 3]));
|
|
|
|
|
assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
|
2013-01-07 10:49:41 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_concat() {
|
2013-09-27 21:37:20 -05:00
|
|
|
|
let v: [~[int], ..0] = [];
|
|
|
|
|
assert_eq!(v.concat_vec(), ~[]);
|
2013-06-14 21:56:41 -05:00
|
|
|
|
assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
2013-06-14 21:56:41 -05:00
|
|
|
|
assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
|
2012-01-17 19:28:21 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-28 17:41:53 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_connect() {
|
2013-09-27 21:37:20 -05:00
|
|
|
|
let v: [~[int], ..0] = [];
|
|
|
|
|
assert_eq!(v.connect_vec(&0), ~[]);
|
2013-06-14 21:56:41 -05:00
|
|
|
|
assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
|
|
|
|
|
assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
2013-09-27 21:37:20 -05:00
|
|
|
|
assert_eq!(v.connect_vec(&0), ~[]);
|
2013-06-14 21:56:41 -05:00
|
|
|
|
assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
|
|
|
|
|
assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
|
2012-01-28 17:41:53 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-05 13:32:25 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_shift() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut x = vec![1, 2, 3];
|
2013-12-23 09:40:42 -06:00
|
|
|
|
assert_eq!(x.shift(), Some(1));
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(&x, &vec![2, 3]);
|
2013-12-23 09:40:42 -06:00
|
|
|
|
assert_eq!(x.shift(), Some(2));
|
|
|
|
|
assert_eq!(x.shift(), Some(3));
|
|
|
|
|
assert_eq!(x.shift(), None);
|
2013-07-05 13:32:25 -05:00
|
|
|
|
assert_eq!(x.len(), 0);
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-22 18:31:57 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_unshift() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut x = vec![1, 2, 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
|
x.unshift(0);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(x, vec![0, 1, 2, 3]);
|
2012-06-22 18:31:57 -05:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-25 07:28:16 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_insert() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut a = vec![1, 2, 4];
|
2012-11-25 07:28:16 -06:00
|
|
|
|
a.insert(2, 3);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![1, 2, 3, 4]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut a = vec![1, 2, 3];
|
2012-11-25 07:28:16 -06:00
|
|
|
|
a.insert(0, 0);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![0, 1, 2, 3]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut a = vec![1, 2, 3];
|
2012-11-25 07:28:16 -06:00
|
|
|
|
a.insert(3, 4);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![1, 2, 3, 4]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut a = vec![];
|
2012-11-25 07:28:16 -06:00
|
|
|
|
a.insert(0, 1);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![1]);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_insert_oob() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut a = vec![1, 2, 3];
|
2012-11-25 07:28:16 -06:00
|
|
|
|
a.insert(4, 5);
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-18 20:56:53 -06:00
|
|
|
|
#[test]
|
2013-12-23 09:53:20 -06:00
|
|
|
|
fn test_remove() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut a = vec![1,2,3,4];
|
2013-12-18 20:56:53 -06:00
|
|
|
|
|
2013-12-23 09:53:20 -06:00
|
|
|
|
assert_eq!(a.remove(2), Some(3));
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![1,2,4]);
|
2013-12-18 20:56:53 -06:00
|
|
|
|
|
2013-12-23 09:53:20 -06:00
|
|
|
|
assert_eq!(a.remove(2), Some(4));
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![1,2]);
|
2013-12-18 20:56:53 -06:00
|
|
|
|
|
2013-12-23 09:53:20 -06:00
|
|
|
|
assert_eq!(a.remove(2), None);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![1,2]);
|
2013-12-18 20:56:53 -06:00
|
|
|
|
|
2013-12-23 09:53:20 -06:00
|
|
|
|
assert_eq!(a.remove(0), Some(1));
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![2]);
|
2013-12-18 20:56:53 -06:00
|
|
|
|
|
2013-12-23 09:53:20 -06:00
|
|
|
|
assert_eq!(a.remove(0), Some(2));
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(a, vec![]);
|
2013-12-18 20:56:53 -06:00
|
|
|
|
|
2013-12-23 09:53:20 -06:00
|
|
|
|
assert_eq!(a.remove(0), None);
|
|
|
|
|
assert_eq!(a.remove(10), None);
|
2012-11-25 07:28:16 -06:00
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 01:10:58 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_capacity() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![0u64];
|
2014-01-31 07:03:20 -06:00
|
|
|
|
v.reserve_exact(10u);
|
2013-06-27 09:40:47 -05:00
|
|
|
|
assert_eq!(v.capacity(), 10u);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![0u32];
|
2014-01-31 07:03:20 -06:00
|
|
|
|
v.reserve_exact(10u);
|
2013-06-27 09:40:47 -05:00
|
|
|
|
assert_eq!(v.capacity(), 10u);
|
2012-03-29 01:10:58 -05:00
|
|
|
|
}
|
2012-05-18 18:55:22 -05:00
|
|
|
|
|
|
|
|
|
#[test]
|
2013-03-21 06:36:21 -05:00
|
|
|
|
fn test_slice_2() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let v = vec![1, 2, 3, 4, 5];
|
2013-03-21 06:36:21 -05:00
|
|
|
|
let v = v.slice(1u, 3u);
|
2013-05-18 21:02:45 -05:00
|
|
|
|
assert_eq!(v.len(), 2u);
|
|
|
|
|
assert_eq!(v[0], 2);
|
|
|
|
|
assert_eq!(v[1], 3);
|
2012-05-18 18:55:22 -05:00
|
|
|
|
}
|
2012-09-27 18:41:38 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_from_fn_fail() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
Vec::from_fn(100, |v| {
|
2013-10-21 15:08:31 -05:00
|
|
|
|
if v == 50 { fail!() }
|
2013-12-21 19:50:54 -06:00
|
|
|
|
~0
|
2013-11-20 16:17:12 -06:00
|
|
|
|
});
|
2012-09-27 18:41:38 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-08-26 20:17:37 -05:00
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_from_elem_fail() {
|
|
|
|
|
use cast;
|
2013-12-21 19:50:54 -06:00
|
|
|
|
use rc::Rc;
|
2013-08-26 20:17:37 -05:00
|
|
|
|
|
|
|
|
|
struct S {
|
|
|
|
|
f: int,
|
2013-12-21 19:50:54 -06:00
|
|
|
|
boxes: (~int, Rc<int>)
|
2013-08-26 20:17:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Clone for S {
|
|
|
|
|
fn clone(&self) -> S {
|
|
|
|
|
let s = unsafe { cast::transmute_mut(self) };
|
|
|
|
|
s.f += 1;
|
2013-10-21 15:08:31 -05:00
|
|
|
|
if s.f == 10 { fail!() }
|
2013-08-26 20:17:37 -05:00
|
|
|
|
S { f: s.f, boxes: s.boxes.clone() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-21 19:50:54 -06:00
|
|
|
|
let s = S { f: 0, boxes: (~0, Rc::new(0)) };
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let _ = Vec::from_elem(100, s);
|
2012-09-27 18:41:38 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_grow_fn_fail() {
|
2013-12-21 19:50:54 -06:00
|
|
|
|
use rc::Rc;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![];
|
2013-11-20 16:17:12 -06:00
|
|
|
|
v.grow_fn(100, |i| {
|
2012-09-27 18:41:38 -05:00
|
|
|
|
if i == 50 {
|
2013-10-21 15:08:31 -05:00
|
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
|
}
|
2013-12-21 19:50:54 -06:00
|
|
|
|
(~0, Rc::new(0))
|
2013-11-20 16:17:12 -06:00
|
|
|
|
})
|
2012-09-27 18:41:38 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_permute_fail() {
|
2013-12-21 19:50:54 -06:00
|
|
|
|
use rc::Rc;
|
|
|
|
|
let v = [(~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0))];
|
2012-09-27 18:41:38 -05:00
|
|
|
|
let mut i = 0;
|
2013-11-23 04:18:51 -06:00
|
|
|
|
for _ in v.permutations() {
|
2012-09-27 18:41:38 -05:00
|
|
|
|
if i == 2 {
|
2013-10-21 15:08:31 -05:00
|
|
|
|
fail!()
|
2012-09-27 18:41:38 -05:00
|
|
|
|
}
|
2013-08-22 23:29:50 -05:00
|
|
|
|
i += 1;
|
std::vec: Replace each_permutation with a new Permutations iterator
Introduce ElementSwaps and Permutations. ElementSwaps is an iterator
that for a given sequence length yields the element swaps needed
to visit each possible permutation of the sequence in turn.
We use an algorithm that generates a sequence such that each permutation
is only one swap apart.
let mut v = [1, 2, 3];
for perm in v.permutations_iter() {
// yields 1 2 3 | 1 3 2 | 3 1 2 | 3 2 1 | 2 3 1 | 2 1 3
}
The `.permutations_iter()` yields clones of the input vector for each
permutation.
If a copyless traversal is needed, it can be constructed with
`ElementSwaps`:
for (a, b) in ElementSwaps::new(3) {
// yields (2, 1), (1, 0), (2, 1) ...
v.swap(a, b);
// ..
}
2013-09-08 18:29:07 -05:00
|
|
|
|
}
|
2012-09-27 18:41:38 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-05 04:52:37 -06:00
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
2013-01-23 13:43:58 -06:00
|
|
|
|
fn test_copy_memory_oob() {
|
|
|
|
|
unsafe {
|
2013-02-12 17:34:48 -06:00
|
|
|
|
let mut a = [1, 2, 3, 4];
|
2013-01-23 13:43:58 -06:00
|
|
|
|
let b = [1, 2, 3, 4, 5];
|
2013-12-16 06:35:02 -06:00
|
|
|
|
a.copy_memory(b);
|
2013-01-23 13:43:58 -06:00
|
|
|
|
}
|
2013-01-05 04:52:37 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-03-01 21:07:12 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_total_ord() {
|
|
|
|
|
[1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
|
|
|
|
|
[1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
|
|
|
|
|
[1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
|
|
|
|
|
[1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
|
|
|
|
|
[2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
|
|
|
|
|
}
|
2013-04-17 18:34:53 -05:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_iterator() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-04-17 18:34:53 -05:00
|
|
|
|
let xs = [1, 2, 5, 10, 11];
|
|
|
|
|
let mut it = xs.iter();
|
2013-07-02 20:40:46 -05:00
|
|
|
|
assert_eq!(it.size_hint(), (5, Some(5)));
|
2013-06-21 05:12:01 -05:00
|
|
|
|
assert_eq!(it.next().unwrap(), &1);
|
2013-07-02 20:40:46 -05:00
|
|
|
|
assert_eq!(it.size_hint(), (4, Some(4)));
|
2013-06-21 05:12:01 -05:00
|
|
|
|
assert_eq!(it.next().unwrap(), &2);
|
2013-07-02 20:40:46 -05:00
|
|
|
|
assert_eq!(it.size_hint(), (3, Some(3)));
|
2013-06-21 05:12:01 -05:00
|
|
|
|
assert_eq!(it.next().unwrap(), &5);
|
2013-07-02 20:40:46 -05:00
|
|
|
|
assert_eq!(it.size_hint(), (2, Some(2)));
|
2013-06-21 05:12:01 -05:00
|
|
|
|
assert_eq!(it.next().unwrap(), &10);
|
2013-07-02 20:40:46 -05:00
|
|
|
|
assert_eq!(it.size_hint(), (1, Some(1)));
|
2013-06-21 05:12:01 -05:00
|
|
|
|
assert_eq!(it.next().unwrap(), &11);
|
2013-07-02 20:40:46 -05:00
|
|
|
|
assert_eq!(it.size_hint(), (0, Some(0)));
|
2013-06-21 05:12:01 -05:00
|
|
|
|
assert!(it.next().is_none());
|
2013-04-17 18:34:53 -05:00
|
|
|
|
}
|
2013-05-11 17:56:08 -05:00
|
|
|
|
|
2013-07-22 19:11:24 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_random_access_iterator() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-07-22 19:11:24 -05:00
|
|
|
|
let xs = [1, 2, 5, 10, 11];
|
|
|
|
|
let mut it = xs.iter();
|
|
|
|
|
|
|
|
|
|
assert_eq!(it.indexable(), 5);
|
|
|
|
|
assert_eq!(it.idx(0).unwrap(), &1);
|
|
|
|
|
assert_eq!(it.idx(2).unwrap(), &5);
|
|
|
|
|
assert_eq!(it.idx(4).unwrap(), &11);
|
|
|
|
|
assert!(it.idx(5).is_none());
|
|
|
|
|
|
|
|
|
|
assert_eq!(it.next().unwrap(), &1);
|
|
|
|
|
assert_eq!(it.indexable(), 4);
|
|
|
|
|
assert_eq!(it.idx(0).unwrap(), &2);
|
|
|
|
|
assert_eq!(it.idx(3).unwrap(), &11);
|
|
|
|
|
assert!(it.idx(4).is_none());
|
|
|
|
|
|
|
|
|
|
assert_eq!(it.next().unwrap(), &2);
|
|
|
|
|
assert_eq!(it.indexable(), 3);
|
|
|
|
|
assert_eq!(it.idx(1).unwrap(), &10);
|
|
|
|
|
assert!(it.idx(3).is_none());
|
|
|
|
|
|
|
|
|
|
assert_eq!(it.next().unwrap(), &5);
|
|
|
|
|
assert_eq!(it.indexable(), 2);
|
|
|
|
|
assert_eq!(it.idx(1).unwrap(), &11);
|
|
|
|
|
|
|
|
|
|
assert_eq!(it.next().unwrap(), &10);
|
|
|
|
|
assert_eq!(it.indexable(), 1);
|
|
|
|
|
assert_eq!(it.idx(0).unwrap(), &11);
|
|
|
|
|
assert!(it.idx(1).is_none());
|
|
|
|
|
|
|
|
|
|
assert_eq!(it.next().unwrap(), &11);
|
|
|
|
|
assert_eq!(it.indexable(), 0);
|
|
|
|
|
assert!(it.idx(0).is_none());
|
|
|
|
|
|
|
|
|
|
assert!(it.next().is_none());
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-03 07:56:26 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_iter_size_hints() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-07-03 07:56:26 -05:00
|
|
|
|
let mut xs = [1, 2, 5, 10, 11];
|
2013-07-02 20:40:46 -05:00
|
|
|
|
assert_eq!(xs.iter().size_hint(), (5, Some(5)));
|
|
|
|
|
assert_eq!(xs.mut_iter().size_hint(), (5, Some(5)));
|
2013-07-03 07:56:26 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-18 10:38:17 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_iter_clone() {
|
|
|
|
|
let xs = [1, 2, 5];
|
|
|
|
|
let mut it = xs.iter();
|
|
|
|
|
it.next();
|
|
|
|
|
let mut jt = it.clone();
|
|
|
|
|
assert_eq!(it.next(), jt.next());
|
|
|
|
|
assert_eq!(it.next(), jt.next());
|
|
|
|
|
assert_eq!(it.next(), jt.next());
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 00:12:39 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_mut_iterator() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-06-06 00:12:39 -05:00
|
|
|
|
let mut xs = [1, 2, 3, 4, 5];
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for x in xs.mut_iter() {
|
2013-06-06 00:12:39 -05:00
|
|
|
|
*x += 1;
|
|
|
|
|
}
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(xs == [2, 3, 4, 5, 6])
|
2013-06-06 00:12:39 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-07 21:39:52 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_rev_iterator() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-06-07 21:39:52 -05:00
|
|
|
|
|
|
|
|
|
let xs = [1, 2, 5, 10, 11];
|
|
|
|
|
let ys = [11, 10, 5, 2, 1];
|
|
|
|
|
let mut i = 0;
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
for &x in xs.iter().rev() {
|
2013-06-07 21:39:52 -05:00
|
|
|
|
assert_eq!(x, ys[i]);
|
|
|
|
|
i += 1;
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(i, 5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_mut_rev_iterator() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-06-07 23:07:55 -05:00
|
|
|
|
let mut xs = [1u, 2, 3, 4, 5];
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
for (i,x) in xs.mut_iter().rev().enumerate() {
|
2013-06-07 21:39:52 -05:00
|
|
|
|
*x += i;
|
|
|
|
|
}
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(xs == [5, 5, 5, 5, 5])
|
2013-06-07 21:39:52 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 10:26:44 -05:00
|
|
|
|
#[test]
|
2013-08-07 21:21:36 -05:00
|
|
|
|
fn test_move_iterator() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-07-01 10:26:44 -05:00
|
|
|
|
let xs = ~[1u,2,3,4,5];
|
2013-08-07 21:21:36 -05:00
|
|
|
|
assert_eq!(xs.move_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345);
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2013-08-07 21:21:36 -05:00
|
|
|
|
fn test_move_rev_iterator() {
|
2013-09-08 10:01:16 -05:00
|
|
|
|
use iter::*;
|
2013-07-01 10:26:44 -05:00
|
|
|
|
let xs = ~[1u,2,3,4,5];
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
assert_eq!(xs.move_iter().rev().fold(0, |a: uint, b: uint| 10*a + b), 54321);
|
2013-07-01 10:26:44 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-02 23:54:11 -05:00
|
|
|
|
#[test]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_splitator() {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
let xs = &[1i,2,3,4,5];
|
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.split(|x| *x % 2 == 0).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[1], &[3], &[5]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 1).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[], &[2,3,4,5]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[1,2,3,4], &[]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 10).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[1,2,3,4,5]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.split(|_| true).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[], &[], &[], &[], &[], &[]]);
|
|
|
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_splitnator() {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
let xs = &[1i,2,3,4,5];
|
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[1,2,3,4,5]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[1], &[3,4,5]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.splitn(3, |_| true).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[], &[], &[], &[4,5]]);
|
|
|
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.splitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_rsplitator() {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
let xs = &[1i,2,3,4,5];
|
|
|
|
|
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[5], &[3], &[1]]);
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 1).rev().collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[2,3,4,5], &[]]);
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 5).rev().collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[], &[1,2,3,4]]);
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 10).rev().collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[1,2,3,4,5]]);
|
|
|
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
assert_eq!(xs.split(|x| *x == 5).rev().collect::<~[&[int]]>(), ~[&[]]);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_rsplitnator() {
|
2013-07-02 23:54:11 -05:00
|
|
|
|
let xs = &[1,2,3,4,5];
|
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[1,2,3,4,5]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[5], &[1,2,3]]);
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.rsplitn(3, |_| true).collect::<~[&[int]]>(),
|
2013-07-02 23:54:11 -05:00
|
|
|
|
~[&[], &[], &[], &[1,2]]);
|
|
|
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-03 00:47:58 -05:00
|
|
|
|
#[test]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_windowsator() {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
let v = &[1i,2,3,4];
|
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(v.windows(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]);
|
|
|
|
|
assert_eq!(v.windows(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]);
|
|
|
|
|
assert!(v.windows(6).next().is_none());
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_windowsator_0() {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
let v = &[1i,2,3,4];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
let _it = v.windows(0);
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_chunksator() {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
let v = &[1i,2,3,4,5];
|
|
|
|
|
|
2013-11-23 04:18:51 -06:00
|
|
|
|
assert_eq!(v.chunks(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
|
|
|
|
|
assert_eq!(v.chunks(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
|
|
|
|
|
assert_eq!(v.chunks(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
|
2013-08-03 12:40:20 -05:00
|
|
|
|
|
2014-01-23 13:41:57 -06:00
|
|
|
|
assert_eq!(v.chunks(2).rev().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
|
2014-04-22 01:25:18 -05:00
|
|
|
|
let mut it = v.chunks(2);
|
2013-08-03 12:40:20 -05:00
|
|
|
|
assert_eq!(it.indexable(), 3);
|
|
|
|
|
assert_eq!(it.idx(0).unwrap(), &[1,2]);
|
|
|
|
|
assert_eq!(it.idx(1).unwrap(), &[3,4]);
|
|
|
|
|
assert_eq!(it.idx(2).unwrap(), &[5]);
|
|
|
|
|
assert_eq!(it.idx(3), None);
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
2013-11-23 04:18:51 -06:00
|
|
|
|
fn test_chunksator_0() {
|
2013-07-03 00:47:58 -05:00
|
|
|
|
let v = &[1i,2,3,4];
|
2013-11-23 04:18:51 -06:00
|
|
|
|
let _it = v.chunks(0);
|
2013-07-03 00:47:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_move_from() {
|
|
|
|
|
let mut a = [1,2,3,4,5];
|
|
|
|
|
let b = ~[6,7,8];
|
|
|
|
|
assert_eq!(a.move_from(b, 0, 3), 3);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(a == [6,7,8,4,5]);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
let mut a = [7,2,8,1];
|
|
|
|
|
let b = ~[3,1,4,1,5,9];
|
|
|
|
|
assert_eq!(a.move_from(b, 0, 6), 4);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(a == [3,1,4,1]);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
let mut a = [1,2,3,4];
|
|
|
|
|
let b = ~[5,6,7,8,9,0];
|
|
|
|
|
assert_eq!(a.move_from(b, 2, 3), 1);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(a == [7,2,3,4]);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
let mut a = [1,2,3,4,5];
|
|
|
|
|
let b = ~[5,6,7,8,9,0];
|
|
|
|
|
assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(a == [1,2,6,7,5]);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_copy_from() {
|
|
|
|
|
let mut a = [1,2,3,4,5];
|
|
|
|
|
let b = [6,7,8];
|
|
|
|
|
assert_eq!(a.copy_from(b), 3);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(a == [6,7,8,4,5]);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
let mut c = [7,2,8,1];
|
|
|
|
|
let d = [3,1,4,1,5,9];
|
|
|
|
|
assert_eq!(c.copy_from(d), 4);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(c == [3,1,4,1]);
|
2013-06-18 01:52:14 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-02-13 17:52:58 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_reverse_part() {
|
|
|
|
|
let mut values = [1,2,3,4,5];
|
2013-06-28 11:54:03 -05:00
|
|
|
|
values.mut_slice(1, 4).reverse();
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(values == [1,4,3,2,5]);
|
2013-02-13 17:52:58 -06:00
|
|
|
|
}
|
|
|
|
|
|
2014-02-12 13:41:34 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_show() {
|
|
|
|
|
macro_rules! test_show_vec(
|
|
|
|
|
($x:expr, $x_str:expr) => ({
|
|
|
|
|
let (x, x_str) = ($x, $x_str);
|
|
|
|
|
assert_eq!(format!("{}", x), x_str);
|
|
|
|
|
assert_eq!(format!("{}", x.as_slice()), x_str);
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
let empty: ~[int] = ~[];
|
2014-04-15 20:17:48 -05:00
|
|
|
|
test_show_vec!(empty, "[]".to_owned());
|
|
|
|
|
test_show_vec!(~[1], "[1]".to_owned());
|
|
|
|
|
test_show_vec!(~[1, 2, 3], "[1, 2, 3]".to_owned());
|
|
|
|
|
test_show_vec!(~[~[], ~[1u], ~[1u, 1u]], "[[], [1], [1, 1]]".to_owned());
|
2014-04-22 12:41:02 -05:00
|
|
|
|
|
|
|
|
|
let empty_mut: &mut [int] = &mut[];
|
|
|
|
|
test_show_vec!(empty_mut, "[]".to_owned());
|
|
|
|
|
test_show_vec!(&mut[1], "[1]".to_owned());
|
|
|
|
|
test_show_vec!(&mut[1, 2, 3], "[1, 2, 3]".to_owned());
|
|
|
|
|
test_show_vec!(&mut[&mut[], &mut[1u], &mut[1u, 1u]], "[[], [1], [1, 1]]".to_owned());
|
2014-02-12 13:41:34 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-17 02:05:51 -05:00
|
|
|
|
#[test]
|
2013-09-12 00:16:22 -05:00
|
|
|
|
fn test_vec_default() {
|
|
|
|
|
use default::Default;
|
2013-06-17 02:05:51 -05:00
|
|
|
|
macro_rules! t (
|
2013-06-27 10:45:24 -05:00
|
|
|
|
($ty:ty) => {{
|
2013-09-12 00:16:22 -05:00
|
|
|
|
let v: $ty = Default::default();
|
2013-06-17 02:05:51 -05:00
|
|
|
|
assert!(v.is_empty());
|
2013-06-27 10:45:24 -05:00
|
|
|
|
}}
|
2013-06-17 02:05:51 -05:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
t!(&[int]);
|
|
|
|
|
t!(~[int]);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
t!(Vec<int>);
|
2013-06-17 02:05:51 -05:00
|
|
|
|
}
|
2013-06-18 01:20:53 -05:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_bytes_set_memory() {
|
2014-03-08 17:11:52 -06:00
|
|
|
|
use slice::bytes::MutableByteVector;
|
2013-06-18 01:20:53 -05:00
|
|
|
|
let mut values = [1u8,2,3,4,5];
|
|
|
|
|
values.mut_slice(0,5).set_memory(0xAB);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
|
2013-06-18 01:20:53 -05:00
|
|
|
|
values.mut_slice(2,4).set_memory(0xFF);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
|
2013-06-18 01:20:53 -05:00
|
|
|
|
}
|
2013-07-03 22:59:34 -05:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_overflow_does_not_cause_segfault() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![];
|
2014-01-31 07:03:20 -06:00
|
|
|
|
v.reserve_exact(-1);
|
2013-07-03 22:59:34 -05:00
|
|
|
|
v.push(1);
|
|
|
|
|
v.push(2);
|
|
|
|
|
}
|
2013-07-10 08:50:24 -05:00
|
|
|
|
|
2013-09-11 22:00:25 -05:00
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_overflow_does_not_cause_segfault_managed() {
|
2013-12-21 19:50:54 -06:00
|
|
|
|
use rc::Rc;
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![Rc::new(1)];
|
2014-01-31 07:03:20 -06:00
|
|
|
|
v.reserve_exact(-1);
|
2013-12-21 19:50:54 -06:00
|
|
|
|
v.push(Rc::new(2));
|
2013-09-11 22:00:25 -05:00
|
|
|
|
}
|
|
|
|
|
|
2013-07-10 08:50:24 -05:00
|
|
|
|
#[test]
|
2013-12-01 11:19:39 -06:00
|
|
|
|
fn test_mut_split_at() {
|
2013-07-10 08:50:24 -05:00
|
|
|
|
let mut values = [1u8,2,3,4,5];
|
|
|
|
|
{
|
2013-12-01 11:19:39 -06:00
|
|
|
|
let (left, right) = values.mut_split_at(2);
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(left.slice(0, left.len()) == [1, 2]);
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for p in left.mut_iter() {
|
2013-07-10 08:50:24 -05:00
|
|
|
|
*p += 1;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(right.slice(0, right.len()) == [3, 4, 5]);
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for p in right.mut_iter() {
|
2013-07-10 08:50:24 -05:00
|
|
|
|
*p += 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(values == [2, 3, 5, 6, 7]);
|
2013-07-10 08:50:24 -05:00
|
|
|
|
}
|
2013-07-12 02:59:39 -05:00
|
|
|
|
|
2013-07-12 23:05:59 -05:00
|
|
|
|
#[deriving(Clone, Eq)]
|
2013-07-12 02:59:39 -05:00
|
|
|
|
struct Foo;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_iter_zero_sized() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = vec![Foo, Foo, Foo];
|
2013-07-12 02:59:39 -05:00
|
|
|
|
assert_eq!(v.len(), 3);
|
|
|
|
|
let mut cnt = 0;
|
|
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for f in v.iter() {
|
2013-07-12 02:59:39 -05:00
|
|
|
|
assert!(*f == Foo);
|
|
|
|
|
cnt += 1;
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(cnt, 3);
|
|
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for f in v.slice(1, 3).iter() {
|
2013-07-12 02:59:39 -05:00
|
|
|
|
assert!(*f == Foo);
|
|
|
|
|
cnt += 1;
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(cnt, 5);
|
|
|
|
|
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for f in v.mut_iter() {
|
2013-07-12 02:59:39 -05:00
|
|
|
|
assert!(*f == Foo);
|
|
|
|
|
cnt += 1;
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(cnt, 8);
|
|
|
|
|
|
2013-08-07 21:21:36 -05:00
|
|
|
|
for f in v.move_iter() {
|
2013-07-12 02:59:39 -05:00
|
|
|
|
assert!(f == Foo);
|
|
|
|
|
cnt += 1;
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(cnt, 11);
|
|
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let xs = vec![Foo, Foo, Foo];
|
2013-09-27 19:02:31 -05:00
|
|
|
|
assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
|
2014-04-15 20:17:48 -05:00
|
|
|
|
"~[slice::tests::Foo, slice::tests::Foo]".to_owned());
|
2013-07-12 02:59:39 -05:00
|
|
|
|
|
|
|
|
|
let xs: [Foo, ..3] = [Foo, Foo, Foo];
|
2013-09-27 19:02:31 -05:00
|
|
|
|
assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
|
2014-04-15 20:17:48 -05:00
|
|
|
|
"~[slice::tests::Foo, slice::tests::Foo]".to_owned());
|
2013-07-12 02:59:39 -05:00
|
|
|
|
cnt = 0;
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for f in xs.iter() {
|
2013-07-12 02:59:39 -05:00
|
|
|
|
assert!(*f == Foo);
|
|
|
|
|
cnt += 1;
|
|
|
|
|
}
|
|
|
|
|
assert!(cnt == 3);
|
|
|
|
|
}
|
2013-08-19 13:17:10 -05:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_shrink_to_fit() {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut xs = vec![0, 1, 2, 3];
|
2013-08-19 13:17:10 -05:00
|
|
|
|
for i in range(4, 100) {
|
|
|
|
|
xs.push(i)
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(xs.capacity(), 128);
|
|
|
|
|
xs.shrink_to_fit();
|
|
|
|
|
assert_eq!(xs.capacity(), 100);
|
2014-04-17 17:28:14 -05:00
|
|
|
|
assert_eq!(xs, range(0, 100).collect::<Vec<_>>());
|
2013-08-19 13:17:10 -05:00
|
|
|
|
}
|
2013-10-17 00:01:20 -05:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_starts_with() {
|
|
|
|
|
assert!(bytes!("foobar").starts_with(bytes!("foo")));
|
|
|
|
|
assert!(!bytes!("foobar").starts_with(bytes!("oob")));
|
|
|
|
|
assert!(!bytes!("foobar").starts_with(bytes!("bar")));
|
|
|
|
|
assert!(!bytes!("foo").starts_with(bytes!("foobar")));
|
|
|
|
|
assert!(!bytes!("bar").starts_with(bytes!("foobar")));
|
|
|
|
|
assert!(bytes!("foobar").starts_with(bytes!("foobar")));
|
|
|
|
|
let empty: &[u8] = [];
|
|
|
|
|
assert!(empty.starts_with(empty));
|
|
|
|
|
assert!(!empty.starts_with(bytes!("foo")));
|
|
|
|
|
assert!(bytes!("foobar").starts_with(empty));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_ends_with() {
|
|
|
|
|
assert!(bytes!("foobar").ends_with(bytes!("bar")));
|
|
|
|
|
assert!(!bytes!("foobar").ends_with(bytes!("oba")));
|
|
|
|
|
assert!(!bytes!("foobar").ends_with(bytes!("foo")));
|
|
|
|
|
assert!(!bytes!("foo").ends_with(bytes!("foobar")));
|
|
|
|
|
assert!(!bytes!("bar").ends_with(bytes!("foobar")));
|
|
|
|
|
assert!(bytes!("foobar").ends_with(bytes!("foobar")));
|
|
|
|
|
let empty: &[u8] = [];
|
|
|
|
|
assert!(empty.ends_with(empty));
|
|
|
|
|
assert!(!empty.ends_with(bytes!("foo")));
|
|
|
|
|
assert!(bytes!("foobar").ends_with(empty));
|
|
|
|
|
}
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_shift_ref() {
|
|
|
|
|
let mut x: &[int] = [1, 2, 3, 4, 5];
|
|
|
|
|
let h = x.shift_ref();
|
2014-01-25 11:00:46 -06:00
|
|
|
|
assert_eq!(*h.unwrap(), 1);
|
2013-11-16 16:29:19 -06:00
|
|
|
|
assert_eq!(x.len(), 4);
|
|
|
|
|
assert_eq!(x[0], 2);
|
|
|
|
|
assert_eq!(x[3], 5);
|
|
|
|
|
|
2014-01-25 11:00:46 -06:00
|
|
|
|
let mut y: &[int] = [];
|
|
|
|
|
assert_eq!(y.shift_ref(), None);
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_pop_ref() {
|
|
|
|
|
let mut x: &[int] = [1, 2, 3, 4, 5];
|
|
|
|
|
let h = x.pop_ref();
|
2014-01-25 14:33:31 -06:00
|
|
|
|
assert_eq!(*h.unwrap(), 5);
|
2013-11-16 16:29:19 -06:00
|
|
|
|
assert_eq!(x.len(), 4);
|
|
|
|
|
assert_eq!(x[0], 1);
|
|
|
|
|
assert_eq!(x[3], 4);
|
|
|
|
|
|
2014-01-25 14:33:31 -06:00
|
|
|
|
let mut y: &[int] = [];
|
|
|
|
|
assert!(y.pop_ref().is_none());
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-01 11:50:34 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_mut_splitator() {
|
|
|
|
|
let mut xs = [0,1,0,2,3,0,0,4,5,0];
|
|
|
|
|
assert_eq!(xs.mut_split(|x| *x == 0).len(), 6);
|
|
|
|
|
for slice in xs.mut_split(|x| *x == 0) {
|
|
|
|
|
slice.reverse();
|
|
|
|
|
}
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(xs == [0,1,0,3,2,0,0,5,4,0]);
|
2013-12-01 11:50:34 -06:00
|
|
|
|
|
|
|
|
|
let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
|
|
|
|
|
for slice in xs.mut_split(|x| *x == 0).take(5) {
|
|
|
|
|
slice.reverse();
|
|
|
|
|
}
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(xs == [0,1,0,3,2,0,0,5,4,0,6,7]);
|
2013-12-01 11:50:34 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2014-01-23 13:41:57 -06:00
|
|
|
|
fn test_mut_splitator_rev() {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
let mut xs = [1,2,0,3,4,0,0,5,6,0];
|
2014-01-23 13:41:57 -06:00
|
|
|
|
for slice in xs.mut_split(|x| *x == 0).rev().take(4) {
|
2013-12-01 11:50:34 -06:00
|
|
|
|
slice.reverse();
|
|
|
|
|
}
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
|
2013-12-01 11:50:34 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-30 15:28:42 -06:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_mut_chunks() {
|
|
|
|
|
let mut v = [0u8, 1, 2, 3, 4, 5, 6];
|
|
|
|
|
for (i, chunk) in v.mut_chunks(3).enumerate() {
|
|
|
|
|
for x in chunk.mut_iter() {
|
|
|
|
|
*x = i as u8;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let result = [0u8, 0, 0, 1, 1, 1, 2];
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(v == result);
|
2013-11-30 15:28:42 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-30 18:54:28 -06:00
|
|
|
|
#[test]
|
2014-01-23 13:41:57 -06:00
|
|
|
|
fn test_mut_chunks_rev() {
|
2013-11-30 18:54:28 -06:00
|
|
|
|
let mut v = [0u8, 1, 2, 3, 4, 5, 6];
|
2014-01-23 13:41:57 -06:00
|
|
|
|
for (i, chunk) in v.mut_chunks(3).rev().enumerate() {
|
2013-11-30 18:54:28 -06:00
|
|
|
|
for x in chunk.mut_iter() {
|
|
|
|
|
*x = i as u8;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let result = [2u8, 2, 2, 1, 1, 1, 0];
|
2014-02-28 03:23:06 -06:00
|
|
|
|
assert!(v == result);
|
2013-11-30 18:54:28 -06:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-30 15:28:42 -06:00
|
|
|
|
#[test]
|
|
|
|
|
#[should_fail]
|
|
|
|
|
fn test_mut_chunks_0() {
|
|
|
|
|
let mut v = [1, 2, 3, 4];
|
|
|
|
|
let _it = v.mut_chunks(0);
|
|
|
|
|
}
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_mut_shift_ref() {
|
|
|
|
|
let mut x: &mut [int] = [1, 2, 3, 4, 5];
|
|
|
|
|
let h = x.mut_shift_ref();
|
2014-01-25 11:00:46 -06:00
|
|
|
|
assert_eq!(*h.unwrap(), 1);
|
2013-11-16 16:29:19 -06:00
|
|
|
|
assert_eq!(x.len(), 4);
|
|
|
|
|
assert_eq!(x[0], 2);
|
|
|
|
|
assert_eq!(x[3], 5);
|
|
|
|
|
|
2014-01-25 11:00:46 -06:00
|
|
|
|
let mut y: &mut [int] = [];
|
|
|
|
|
assert!(y.mut_shift_ref().is_none());
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_mut_pop_ref() {
|
|
|
|
|
let mut x: &mut [int] = [1, 2, 3, 4, 5];
|
|
|
|
|
let h = x.mut_pop_ref();
|
2014-01-25 14:33:31 -06:00
|
|
|
|
assert_eq!(*h.unwrap(), 5);
|
2013-11-16 16:29:19 -06:00
|
|
|
|
assert_eq!(x.len(), 4);
|
|
|
|
|
assert_eq!(x[0], 1);
|
|
|
|
|
assert_eq!(x[3], 4);
|
|
|
|
|
|
2014-01-25 14:33:31 -06:00
|
|
|
|
let mut y: &mut [int] = [];
|
|
|
|
|
assert!(y.mut_pop_ref().is_none());
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2014-01-26 10:24:34 -06:00
|
|
|
|
fn test_mut_last() {
|
|
|
|
|
let mut x = [1, 2, 3, 4, 5];
|
|
|
|
|
let h = x.mut_last();
|
|
|
|
|
assert_eq!(*h.unwrap(), 5);
|
|
|
|
|
|
2014-01-22 21:32:16 -06:00
|
|
|
|
let y: &mut [int] = [];
|
2014-01-26 10:24:34 -06:00
|
|
|
|
assert!(y.mut_last().is_none());
|
2013-11-16 16:29:19 -06:00
|
|
|
|
}
|
2013-04-18 07:15:40 -05:00
|
|
|
|
}
|
2013-08-02 08:34:11 -05:00
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod bench {
|
2014-02-13 19:49:11 -06:00
|
|
|
|
extern crate test;
|
2014-03-31 20:16:35 -05:00
|
|
|
|
use self::test::Bencher;
|
2014-01-07 00:33:37 -06:00
|
|
|
|
use mem;
|
|
|
|
|
use prelude::*;
|
2013-12-11 23:05:26 -06:00
|
|
|
|
use ptr;
|
2013-12-18 20:23:37 -06:00
|
|
|
|
use rand::{weak_rng, Rng};
|
2013-08-02 08:34:11 -05:00
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn iterator(b: &mut Bencher) {
|
2013-08-02 08:34:11 -05:00
|
|
|
|
// peculiar numbers to stop LLVM from optimising the summation
|
|
|
|
|
// out.
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let v = Vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
|
2013-08-02 08:34:11 -05:00
|
|
|
|
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2013-08-02 08:34:11 -05:00
|
|
|
|
let mut sum = 0;
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for x in v.iter() {
|
2013-08-02 08:34:11 -05:00
|
|
|
|
sum += *x;
|
|
|
|
|
}
|
|
|
|
|
// sum == 11806, to stop dead code elimination.
|
2013-10-21 15:08:31 -05:00
|
|
|
|
if sum == 0 {fail!()}
|
2013-11-20 16:17:12 -06:00
|
|
|
|
})
|
2013-08-02 08:34:11 -05:00
|
|
|
|
}
|
2013-08-02 09:23:05 -05:00
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn mut_iterator(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::from_elem(100, 0);
|
2013-08-02 09:23:05 -05:00
|
|
|
|
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2013-08-02 09:23:05 -05:00
|
|
|
|
let mut i = 0;
|
2013-08-03 11:45:23 -05:00
|
|
|
|
for x in v.mut_iter() {
|
2013-08-02 09:23:05 -05:00
|
|
|
|
*x = i;
|
|
|
|
|
i += 1;
|
|
|
|
|
}
|
2013-11-20 16:17:12 -06:00
|
|
|
|
})
|
2013-08-02 09:23:05 -05:00
|
|
|
|
}
|
2013-08-08 22:49:49 -05:00
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn add(b: &mut Bencher) {
|
2013-08-08 22:49:49 -05:00
|
|
|
|
let xs: &[int] = [5, ..10];
|
|
|
|
|
let ys: &[int] = [5, ..10];
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2013-08-08 22:49:49 -05:00
|
|
|
|
xs + ys;
|
2013-11-20 16:17:12 -06:00
|
|
|
|
});
|
2013-08-08 22:49:49 -05:00
|
|
|
|
}
|
2013-09-27 21:53:20 -05:00
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn concat(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
xss.as_slice().concat_vec()
|
2013-11-21 19:23:21 -06:00
|
|
|
|
});
|
2013-09-27 21:53:20 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn connect(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
xss.as_slice().connect_vec(&0)
|
2013-11-21 19:23:21 -06:00
|
|
|
|
});
|
2013-09-27 21:53:20 -05:00
|
|
|
|
}
|
2013-11-20 15:19:48 -06:00
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn push(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut vec: Vec<uint> = vec![];
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2013-11-20 15:19:48 -06:00
|
|
|
|
vec.push(0);
|
2014-02-12 09:39:21 -06:00
|
|
|
|
&vec
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn starts_with_same_vector(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
vec.as_slice().starts_with(vec.as_slice())
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn starts_with_single_element(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let vec: Vec<uint> = vec![0];
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
vec.as_slice().starts_with(vec.as_slice())
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
|
|
|
|
|
let mut match_vec: Vec<uint> = Vec::from_fn(99, |i| i);
|
2013-11-20 15:19:48 -06:00
|
|
|
|
match_vec.push(0);
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
vec.as_slice().starts_with(match_vec.as_slice())
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn ends_with_same_vector(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
vec.as_slice().ends_with(vec.as_slice())
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn ends_with_single_element(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let vec: Vec<uint> = vec![0];
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
vec.as_slice().ends_with(vec.as_slice())
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
|
|
|
|
|
let mut match_vec: Vec<uint> = Vec::from_fn(100, |i| i);
|
|
|
|
|
match_vec.as_mut_slice()[0] = 200;
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
vec.as_slice().starts_with(match_vec.as_slice())
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn contains_last_element(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-02-12 09:39:21 -06:00
|
|
|
|
vec.contains(&99u)
|
2013-11-22 16:15:32 -06:00
|
|
|
|
})
|
2013-11-20 15:19:48 -06:00
|
|
|
|
}
|
2013-12-11 23:05:26 -06:00
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn zero_1kb_from_elem(b: &mut Bencher) {
|
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
Vec::from_elem(1024, 0u8)
|
2013-12-11 23:05:26 -06:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn zero_1kb_set_memory(b: &mut Bencher) {
|
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v: Vec<uint> = Vec::with_capacity(1024);
|
2013-12-11 23:05:26 -06:00
|
|
|
|
unsafe {
|
2013-12-15 06:35:12 -06:00
|
|
|
|
let vp = v.as_mut_ptr();
|
2013-12-11 23:05:26 -06:00
|
|
|
|
ptr::set_memory(vp, 0, 1024);
|
2013-12-15 06:05:30 -06:00
|
|
|
|
v.set_len(1024);
|
2013-12-11 23:05:26 -06:00
|
|
|
|
}
|
2014-02-12 09:39:21 -06:00
|
|
|
|
v
|
2013-12-11 23:05:26 -06:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn zero_1kb_fixed_repeat(b: &mut Bencher) {
|
|
|
|
|
b.iter(|| {
|
2014-02-12 09:39:21 -06:00
|
|
|
|
~[0u8, ..1024]
|
2013-12-11 23:05:26 -06:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn zero_1kb_loop_set(b: &mut Bencher) {
|
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v: Vec<uint> = Vec::with_capacity(1024);
|
2013-12-11 23:05:26 -06:00
|
|
|
|
unsafe {
|
2013-12-15 06:05:30 -06:00
|
|
|
|
v.set_len(1024);
|
2013-12-11 23:05:26 -06:00
|
|
|
|
}
|
2014-04-01 22:39:26 -05:00
|
|
|
|
for i in range(0u, 1024) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
*v.get_mut(i) = 0;
|
2013-12-11 23:05:26 -06:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn zero_1kb_mut_iter(b: &mut Bencher) {
|
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::with_capacity(1024);
|
2013-12-11 23:05:26 -06:00
|
|
|
|
unsafe {
|
2013-12-15 06:05:30 -06:00
|
|
|
|
v.set_len(1024);
|
2013-12-11 23:05:26 -06:00
|
|
|
|
}
|
|
|
|
|
for x in v.mut_iter() {
|
|
|
|
|
*x = 0;
|
|
|
|
|
}
|
2014-02-12 09:39:21 -06:00
|
|
|
|
v
|
2013-12-11 23:05:26 -06:00
|
|
|
|
});
|
|
|
|
|
}
|
2013-12-18 20:23:37 -06:00
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn random_inserts(b: &mut Bencher) {
|
2013-12-18 20:23:37 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::from_elem(30, (0u, 0u));
|
2013-12-18 20:23:37 -06:00
|
|
|
|
for _ in range(0, 100) {
|
|
|
|
|
let l = v.len();
|
|
|
|
|
v.insert(rng.gen::<uint>() % (l + 1),
|
|
|
|
|
(1, 1));
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
2013-12-18 20:56:53 -06:00
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn random_removes(b: &mut Bencher) {
|
2013-12-18 20:56:53 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::from_elem(130, (0u, 0u));
|
2013-12-18 20:56:53 -06:00
|
|
|
|
for _ in range(0, 100) {
|
|
|
|
|
let l = v.len();
|
|
|
|
|
v.remove(rng.gen::<uint>() % l);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
2013-12-19 21:42:00 -06:00
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_random_small(b: &mut Bencher) {
|
2013-12-18 16:24:26 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-03-27 07:00:46 -05:00
|
|
|
|
let mut v = rng.gen_vec::<u64>(5);
|
|
|
|
|
v.as_mut_slice().sort();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
});
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.bytes = 5 * mem::size_of::<u64>() as u64;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_random_medium(b: &mut Bencher) {
|
2013-12-18 16:24:26 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-03-27 07:00:46 -05:00
|
|
|
|
let mut v = rng.gen_vec::<u64>(100);
|
|
|
|
|
v.as_mut_slice().sort();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
});
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.bytes = 100 * mem::size_of::<u64>() as u64;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_random_large(b: &mut Bencher) {
|
2013-12-18 16:24:26 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-03-27 07:00:46 -05:00
|
|
|
|
let mut v = rng.gen_vec::<u64>(10000);
|
|
|
|
|
v.as_mut_slice().sort();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
});
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.bytes = 10000 * mem::size_of::<u64>() as u64;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_sorted(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::from_fn(10000, |i| i);
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2013-12-19 06:03:11 -06:00
|
|
|
|
v.sort();
|
2013-12-18 16:24:26 -06:00
|
|
|
|
});
|
2014-04-17 17:28:14 -05:00
|
|
|
|
b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
|
2013-12-18 16:24:26 -06:00
|
|
|
|
}
|
2014-02-04 11:56:13 -06:00
|
|
|
|
|
|
|
|
|
type BigSortable = (u64,u64,u64,u64);
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_big_random_small(b: &mut Bencher) {
|
2014-02-04 11:56:13 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-03-27 07:00:46 -05:00
|
|
|
|
let mut v = rng.gen_vec::<BigSortable>(5);
|
2014-02-04 11:56:13 -06:00
|
|
|
|
v.sort();
|
|
|
|
|
});
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
|
2014-02-04 11:56:13 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_big_random_medium(b: &mut Bencher) {
|
2014-02-04 11:56:13 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-03-27 07:00:46 -05:00
|
|
|
|
let mut v = rng.gen_vec::<BigSortable>(100);
|
2014-02-04 11:56:13 -06:00
|
|
|
|
v.sort();
|
|
|
|
|
});
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
|
2014-02-04 11:56:13 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_big_random_large(b: &mut Bencher) {
|
2014-02-04 11:56:13 -06:00
|
|
|
|
let mut rng = weak_rng();
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-03-27 07:00:46 -05:00
|
|
|
|
let mut v = rng.gen_vec::<BigSortable>(10000);
|
2014-02-04 11:56:13 -06:00
|
|
|
|
v.sort();
|
|
|
|
|
});
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
|
2014-02-04 11:56:13 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
|
fn sort_big_sorted(b: &mut Bencher) {
|
2014-04-17 17:28:14 -05:00
|
|
|
|
let mut v = Vec::from_fn(10000u, |i| (i, i, i, i));
|
2014-03-31 20:16:35 -05:00
|
|
|
|
b.iter(|| {
|
2014-02-04 11:56:13 -06:00
|
|
|
|
v.sort();
|
|
|
|
|
});
|
2014-04-17 17:28:14 -05:00
|
|
|
|
b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
|
2014-02-04 11:56:13 -06:00
|
|
|
|
}
|
2013-08-02 08:34:11 -05:00
|
|
|
|
}
|