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.
|
|
|
|
|
2014-08-04 05:48:39 -05:00
|
|
|
//! Utilities for slice manipulation
|
|
|
|
//!
|
|
|
|
//! The `slice` module contains useful code to help work with slice values.
|
|
|
|
//! Slices are a view into a block of memory represented as a pointer and a length.
|
|
|
|
//!
|
|
|
|
//! ```rust
|
|
|
|
//! // slicing a Vec
|
|
|
|
//! let vec = vec!(1i, 2, 3);
|
|
|
|
//! let int_slice = vec.as_slice();
|
|
|
|
//! // coercing an array to a slice
|
2014-11-17 02:39:01 -06:00
|
|
|
//! let str_slice: &[&str] = &["one", "two", "three"];
|
2014-08-04 05:48:39 -05:00
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! Slices are either mutable or shared. The shared slice type is `&[T]`,
|
|
|
|
//! while the mutable slice type is `&mut[T]`. For example, you can mutate the
|
|
|
|
//! block of memory that a mutable slice points to:
|
|
|
|
//!
|
|
|
|
//! ```rust
|
2014-11-17 02:39:01 -06:00
|
|
|
//! let x: &mut[int] = &mut [1i, 2, 3];
|
2014-08-04 05:48:39 -05:00
|
|
|
//! x[1] = 7;
|
|
|
|
//! assert_eq!(x[0], 1);
|
|
|
|
//! assert_eq!(x[1], 7);
|
|
|
|
//! assert_eq!(x[2], 3);
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! Here are some of the things this module contains:
|
|
|
|
//!
|
|
|
|
//! ## Structs
|
|
|
|
//!
|
|
|
|
//! There are several structs that are useful for slices, such as `Items`, which
|
|
|
|
//! represents iteration over a slice.
|
|
|
|
//!
|
|
|
|
//! ## Traits
|
|
|
|
//!
|
2014-11-02 19:04:32 -06:00
|
|
|
//! A number of traits add methods that allow you to accomplish tasks
|
|
|
|
//! with slices, the most important being `SlicePrelude`. Other traits
|
|
|
|
//! apply only to slices of elements satisfying certain bounds (like
|
|
|
|
//! `Ord`).
|
2014-08-04 05:48:39 -05:00
|
|
|
//!
|
2014-09-24 06:41:09 -05:00
|
|
|
//! An example is the `slice` method which enables slicing syntax `[a..b]` that
|
|
|
|
//! returns an immutable "view" into a `Vec` or another slice from the index
|
|
|
|
//! interval `[a, b)`:
|
2014-08-04 05:48:39 -05:00
|
|
|
//!
|
|
|
|
//! ```rust
|
2014-09-26 00:48:16 -05:00
|
|
|
//! #![feature(slicing_syntax)]
|
|
|
|
//! fn main() {
|
|
|
|
//! let numbers = [0i, 1i, 2i];
|
|
|
|
//! let last_numbers = numbers[1..3];
|
|
|
|
//! // last_numbers is now &[1i, 2i]
|
|
|
|
//! }
|
2014-08-04 05:48:39 -05:00
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! ## Implementations of other traits
|
|
|
|
//!
|
|
|
|
//! There are several implementations of common traits for slices. Some examples
|
|
|
|
//! include:
|
|
|
|
//!
|
|
|
|
//! * `Clone`
|
|
|
|
//! * `Eq`, `Ord` - for immutable slices whose element type are `Eq` or `Ord`.
|
|
|
|
//! * `Hash` - for slices whose element type is `Hash`
|
|
|
|
//!
|
|
|
|
//! ## Iteration
|
|
|
|
//!
|
|
|
|
//! The method `iter()` returns an iteration value for a slice. The iterator
|
|
|
|
//! yields references to the slice's elements, so if the element
|
|
|
|
//! type of the slice is `int`, the element type of the iterator is `&int`.
|
|
|
|
//!
|
|
|
|
//! ```rust
|
|
|
|
//! let numbers = [0i, 1i, 2i];
|
|
|
|
//! for &x in numbers.iter() {
|
|
|
|
//! println!("{} is a number!", x);
|
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
2014-09-14 22:27:36 -05:00
|
|
|
//! * `.iter_mut()` returns an iterator that allows modifying each value.
|
2014-08-04 05:48:39 -05:00
|
|
|
//! * Further iterators exist that split, chunk or permute the slice.
|
2012-03-15 20:58:14 -05:00
|
|
|
|
2014-05-28 21:53:37 -05:00
|
|
|
#![doc(primitive = "slice")]
|
|
|
|
|
2014-11-06 02:05:53 -06:00
|
|
|
use self::Direction::*;
|
2014-10-10 04:18:42 -05:00
|
|
|
use alloc::boxed::Box;
|
2014-11-12 14:01:26 -06:00
|
|
|
use core::borrow::{BorrowFrom, BorrowFromMut};
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
use core::cmp;
|
2014-10-23 10:43:18 -05:00
|
|
|
use core::kinds::Sized;
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
use core::mem::size_of;
|
|
|
|
use core::mem;
|
2014-10-30 15:43:24 -05:00
|
|
|
use core::prelude::{Clone, Greater, Iterator, Less, None, Option};
|
2014-08-12 22:31:30 -05:00
|
|
|
use core::prelude::{Ord, Ordering, RawPtr, Some, range};
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 20:50:12 -05:00
|
|
|
use core::ptr;
|
|
|
|
use core::iter::{range_step, MultiplicativeIterator};
|
2014-06-06 18:33:44 -05:00
|
|
|
|
2014-04-17 17:28:14 -05:00
|
|
|
use vec::Vec;
|
2012-07-17 18:31:19 -05:00
|
|
|
|
2014-11-02 19:04:32 -06:00
|
|
|
pub use core::slice::{Chunks, AsSlice, SlicePrelude, PartialEqSlicePrelude};
|
|
|
|
pub use core::slice::{OrdSlicePrelude, SlicePrelude, Items, MutItems};
|
2014-10-15 11:12:41 -05:00
|
|
|
pub use core::slice::{ImmutableIntSlice, MutableIntSlice};
|
2014-08-12 22:31:30 -05:00
|
|
|
pub use core::slice::{MutSplits, MutChunks, Splits};
|
2014-11-02 19:04:32 -06:00
|
|
|
pub use core::slice::{bytes, mut_ref_slice, ref_slice, CloneSlicePrelude};
|
2014-08-12 22:31:30 -05:00
|
|
|
pub use core::slice::{Found, NotFound};
|
2011-12-13 18:25:51 -06:00
|
|
|
|
|
|
|
// Functional utilities
|
|
|
|
|
2014-10-27 17:37:07 -05:00
|
|
|
#[allow(missing_docs)]
|
2014-10-23 10:43:18 -05:00
|
|
|
pub trait VectorVector<T> for Sized? {
|
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.
|
2014-08-04 05:48:39 -05:00
|
|
|
/// Flattens a vector of vectors of `T` into a single `Vec<T>`.
|
2014-05-03 18:13:35 -05:00
|
|
|
fn concat_vec(&self) -> Vec<T>;
|
2013-06-02 22:19:37 -05:00
|
|
|
|
|
|
|
/// Concatenate a vector of vectors, placing a given separator between each.
|
2014-05-03 18:13:35 -05:00
|
|
|
fn connect_vec(&self, sep: &T) -> Vec<T>;
|
2013-06-02 22:19:37 -05:00
|
|
|
}
|
|
|
|
|
2014-10-23 10:43:18 -05:00
|
|
|
impl<T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
|
2014-05-03 18:13:35 -05:00
|
|
|
fn concat_vec(&self) -> Vec<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-05-03 18:13:35 -05:00
|
|
|
result
|
2013-06-02 22:19:37 -05:00
|
|
|
}
|
|
|
|
|
2014-05-03 18:13:35 -05:00
|
|
|
fn connect_vec(&self, sep: &T) -> Vec<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-05-03 18:13:35 -05:00
|
|
|
result
|
2012-01-28 17:41:53 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-04 05:48:39 -05:00
|
|
|
/// An iterator that yields the element swaps needed to produce
|
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
|
|
|
/// a sequence of all possible permutations for an indexed sequence of
|
|
|
|
/// elements. Each permutation is only a single swap apart.
|
|
|
|
///
|
2014-07-14 22:46:04 -05:00
|
|
|
/// The Steinhaus-Johnson-Trotter algorithm is used.
|
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
|
|
|
///
|
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-05-03 18:13:35 -05:00
|
|
|
sdir: Vec<SizeDirection>,
|
2014-08-04 05:48:39 -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 {
|
2014-08-04 05:48:39 -05:00
|
|
|
/// Creates an `ElementSwaps` iterator for a sequence of `length` elements.
|
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 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,
|
2014-05-03 18:13:35 -05:00
|
|
|
sdir: range(0, length).map(|i| SizeDirection{ size: i, dir: Neg }).collect(),
|
2014-04-25 15:19:53 -05:00
|
|
|
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 }
|
|
|
|
|
2014-08-04 05:48:39 -05:00
|
|
|
/// An `Index` and `Direction` together.
|
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
|
|
|
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() &&
|
2014-08-11 18:47:46 -05:00
|
|
|
self.sdir[new_pos(i, sd.dir)].size < sd.size)
|
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
|
|
|
.max_by(|&(_, sd)| sd.size);
|
|
|
|
match max {
|
|
|
|
Some((i, sd)) => {
|
|
|
|
let j = new_pos(i, sd.dir);
|
2014-05-03 18:13:35 -05:00
|
|
|
self.sdir.as_mut_slice().swap(i, j);
|
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
|
|
|
|
|
|
|
// Swap the direction of each larger SizeDirection
|
2014-09-14 22:27:36 -05:00
|
|
|
for x in self.sdir.iter_mut() {
|
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 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
|
|
|
}
|
|
|
|
|
2014-08-04 05:48:39 -05:00
|
|
|
/// An iterator that uses `ElementSwaps` to iterate through
|
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
|
|
|
/// 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,
|
2014-06-06 12:27:49 -05:00
|
|
|
v: Vec<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
|
|
|
}
|
|
|
|
|
2014-06-06 12:27:49 -05:00
|
|
|
impl<T: Clone> Iterator<Vec<T>> for 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
|
|
|
#[inline]
|
2014-06-06 12:27:49 -05:00
|
|
|
fn next(&mut self) -> Option<Vec<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
|
|
|
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();
|
2014-06-06 12:27:49 -05:00
|
|
|
self.v.as_mut_slice().swap(a, b);
|
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(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
|
|
|
}
|
|
|
|
|
2014-11-02 19:04:32 -06:00
|
|
|
/// Extension methods for boxed slices.
|
|
|
|
pub trait BoxedSlicePrelude<T> {
|
2014-10-10 04:18:42 -05:00
|
|
|
/// Convert `self` into a vector without clones or allocation.
|
|
|
|
fn into_vec(self) -> Vec<T>;
|
|
|
|
}
|
|
|
|
|
2014-11-02 19:04:32 -06:00
|
|
|
impl<T> BoxedSlicePrelude<T> for Box<[T]> {
|
2014-10-10 04:18:42 -05:00
|
|
|
#[experimental]
|
|
|
|
fn into_vec(mut self) -> Vec<T> {
|
|
|
|
unsafe {
|
2014-10-24 21:31:17 -05:00
|
|
|
let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
|
2014-10-10 04:18:42 -05:00
|
|
|
mem::forget(self);
|
|
|
|
xs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-02 19:04:32 -06:00
|
|
|
/// Allocating extension methods for slices containing `Clone` elements.
|
|
|
|
pub trait CloneSliceAllocPrelude<T> for Sized? {
|
|
|
|
/// Copies `self` into a new `Vec`.
|
|
|
|
fn to_vec(&self) -> Vec<T>;
|
|
|
|
|
2014-08-04 05:48:39 -05:00
|
|
|
/// Partitions the vector into two vectors `(a, b)`, where all
|
|
|
|
/// elements of `a` satisfy `f` and all elements of `b` do not.
|
2014-05-03 18:13:35 -05:00
|
|
|
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
|
2013-10-14 06:21:47 -05:00
|
|
|
|
2014-08-04 05:48:39 -05:00
|
|
|
/// Creates an iterator that yields every possible permutation of the
|
2014-05-01 00:54:25 -05:00
|
|
|
/// vector in succession.
|
2014-07-31 05:13:44 -05:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let v = [1i, 2, 3];
|
|
|
|
/// let mut perms = v.permutations();
|
|
|
|
///
|
|
|
|
/// for p in perms {
|
|
|
|
/// println!("{}", p);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// # Example 2: iterating through permutations one by one.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let v = [1i, 2, 3];
|
|
|
|
/// let mut perms = v.permutations();
|
|
|
|
///
|
|
|
|
/// assert_eq!(Some(vec![1i, 2, 3]), perms.next());
|
|
|
|
/// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
|
|
|
|
/// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
|
|
|
|
/// ```
|
2014-10-23 10:43:18 -05:00
|
|
|
fn permutations(&self) -> Permutations<T>;
|
2014-05-01 00:54:25 -05:00
|
|
|
}
|
2013-10-14 06:21:47 -05:00
|
|
|
|
2014-11-02 19:04:32 -06:00
|
|
|
impl<T: Clone> CloneSliceAllocPrelude<T> for [T] {
|
|
|
|
/// Returns a copy of `v`.
|
|
|
|
#[inline]
|
|
|
|
fn to_vec(&self) -> Vec<T> {
|
|
|
|
let mut vector = Vec::with_capacity(self.len());
|
|
|
|
vector.push_all(self);
|
|
|
|
vector
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-01 00:54:25 -05:00
|
|
|
#[inline]
|
2014-05-03 18:13:35 -05:00
|
|
|
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
|
2014-05-01 00:54:25 -05:00
|
|
|
let mut lefts = Vec::new();
|
|
|
|
let mut rights = Vec::new();
|
2013-07-02 23:54:11 -05:00
|
|
|
|
2014-05-01 00:54:25 -05:00
|
|
|
for elt in self.iter() {
|
|
|
|
if f(elt) {
|
|
|
|
lefts.push((*elt).clone());
|
|
|
|
} else {
|
|
|
|
rights.push((*elt).clone());
|
|
|
|
}
|
|
|
|
}
|
2013-06-28 22:35:25 -05:00
|
|
|
|
2014-05-03 18:13:35 -05:00
|
|
|
(lefts, rights)
|
2014-05-01 00:54:25 -05:00
|
|
|
}
|
2013-12-15 06:35:12 -06:00
|
|
|
|
2014-07-31 05:13:44 -05:00
|
|
|
/// Returns an iterator over all permutations of a vector.
|
2014-10-23 10:43:18 -05:00
|
|
|
fn permutations(&self) -> Permutations<T> {
|
2014-05-01 00:54:25 -05:00
|
|
|
Permutations{
|
|
|
|
swaps: ElementSwaps::new(self.len()),
|
2014-07-16 15:37:28 -05:00
|
|
|
v: self.to_vec(),
|
2014-05-01 00:54:25 -05:00
|
|
|
}
|
|
|
|
}
|
2013-06-29 00:05:50 -05:00
|
|
|
|
2014-05-01 00:54:25 -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.
|
2014-06-25 14:47:34 -05:00
|
|
|
let read_ptr = buf_v.offset(i) as *const T;
|
2014-02-04 11:56:13 -06:00
|
|
|
|
|
|
|
// 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),
|
2014-06-25 14:47:34 -05:00
|
|
|
&tmp as *const T,
|
2014-02-04 11:56:13 -06:00
|
|
|
1);
|
core: Remove the cast module
This commit revisits the `cast` module in libcore and libstd, and scrutinizes
all functions inside of it. The result was to remove the `cast` module entirely,
folding all functionality into the `mem` module. Specifically, this is the fate
of each function in the `cast` module.
* transmute - This function was moved to `mem`, but it is now marked as
#[unstable]. This is due to planned changes to the `transmute`
function and how it can be invoked (see the #[unstable] comment).
For more information, see RFC 5 and #12898
* transmute_copy - This function was moved to `mem`, with clarification that is
is not an error to invoke it with T/U that are different
sizes, but rather that it is strongly discouraged. This
function is now #[stable]
* forget - This function was moved to `mem` and marked #[stable]
* bump_box_refcount - This function was removed due to the deprecation of
managed boxes as well as its questionable utility.
* transmute_mut - This function was previously deprecated, and removed as part
of this commit.
* transmute_mut_unsafe - This function doesn't serve much of a purpose when it
can be achieved with an `as` in safe code, so it was
removed.
* transmute_lifetime - This function was removed because it is likely a strong
indication that code is incorrect in the first place.
* transmute_mut_lifetime - This function was removed for the same reasons as
`transmute_lifetime`
* copy_lifetime - This function was moved to `mem`, but it is marked
`#[unstable]` now due to the likelihood of being removed in
the future if it is found to not be very useful.
* copy_mut_lifetime - This function was also moved to `mem`, but had the same
treatment as `copy_lifetime`.
* copy_lifetime_vec - This function was removed because it is not used today,
and its existence is not necessary with DST
(copy_lifetime will suffice).
In summary, the cast module was stripped down to these functions, and then the
functions were moved to the `mem` module.
transmute - #[unstable]
transmute_copy - #[stable]
forget - #[stable]
copy_lifetime - #[unstable]
copy_mut_lifetime - #[unstable]
[breaking-change]
2014-05-09 12:34:51 -05:00
|
|
|
mem::forget(tmp);
|
2014-02-04 11:56:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-02 19:04:32 -06:00
|
|
|
/// Allocating extension methods for slices on Ord values.
|
|
|
|
#[experimental = "likely to merge with other traits"]
|
|
|
|
pub trait OrdSliceAllocPrelude<T> for Sized? {
|
|
|
|
/// Sorts the slice, in place.
|
|
|
|
///
|
|
|
|
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let mut v = [-5i, 4, 1, -3, 2];
|
|
|
|
///
|
|
|
|
/// v.sort();
|
|
|
|
/// assert!(v == [-5i, -3, 1, 2, 4]);
|
|
|
|
/// ```
|
|
|
|
#[experimental]
|
|
|
|
fn sort(&mut self);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Ord> OrdSliceAllocPrelude<T> for [T] {
|
|
|
|
#[experimental]
|
|
|
|
#[inline]
|
|
|
|
fn sort(&mut self) {
|
|
|
|
self.sort_by(|a, b| a.cmp(b))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Allocating extension methods for slices.
|
|
|
|
#[experimental = "likely to merge with other traits"]
|
|
|
|
pub trait SliceAllocPrelude<T> for Sized? {
|
2014-08-04 05:48:39 -05:00
|
|
|
/// Sorts the slice, in place, using `compare` to compare
|
2013-12-19 21:42:00 -06:00
|
|
|
/// 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
|
|
|
/// ```
|
2014-10-23 10:43:18 -05:00
|
|
|
fn sort_by(&mut self, compare: |&T, &T| -> Ordering);
|
2013-12-18 16:24:26 -06:00
|
|
|
|
2014-08-04 05:48:39 -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 `src` to stop copying from
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let mut a = [1i, 2, 3, 4, 5];
|
|
|
|
/// let b = vec![6i, 7, 8];
|
|
|
|
/// let num_moved = a.move_from(b, 0, 3);
|
|
|
|
/// assert_eq!(num_moved, 3);
|
|
|
|
/// assert!(a == [6i, 7, 8, 4, 5]);
|
|
|
|
/// ```
|
2014-10-23 10:43:18 -05:00
|
|
|
fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint;
|
2013-04-17 16:19:25 -05:00
|
|
|
}
|
|
|
|
|
2014-11-02 19:04:32 -06:00
|
|
|
impl<T> SliceAllocPrelude<T> for [T] {
|
2013-12-18 16:24:26 -06:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
|
2013-12-19 21:42:00 -06:00
|
|
|
merge_sort(self, compare)
|
2013-12-18 16:24:26 -06:00
|
|
|
}
|
|
|
|
|
2013-06-18 01:52:14 -05:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn move_from(&mut self, mut src: Vec<T>, start: uint, end: uint) -> uint {
|
2014-09-24 06:41:09 -05:00
|
|
|
for (a, b) in self.iter_mut().zip(src[mut start..end].iter_mut()) {
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 14:01:26 -06:00
|
|
|
#[unstable = "trait is unstable"]
|
|
|
|
impl<T> BorrowFrom<Vec<T>> for [T] {
|
|
|
|
fn borrow_from(owned: &Vec<T>) -> &[T] { owned[] }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable = "trait is unstable"]
|
|
|
|
impl<T> BorrowFromMut<Vec<T>> for [T] {
|
|
|
|
fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { owned[mut] }
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Unsafe operations
|
2012-12-14 17:47:11 -06:00
|
|
|
pub mod raw {
|
2014-05-01 00:54:25 -05:00
|
|
|
pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
|
|
|
|
pub use core::slice::raw::{shift_ptr, pop_ptr};
|
2013-11-30 18:54:28 -06:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2014-05-29 21:03:06 -05:00
|
|
|
use std::cell::Cell;
|
|
|
|
use std::default::Default;
|
|
|
|
use std::mem;
|
|
|
|
use std::prelude::*;
|
|
|
|
use std::rand::{Rng, task_rng};
|
|
|
|
use std::rc::Rc;
|
2014-06-04 02:01:40 -05:00
|
|
|
use std::rt;
|
2014-05-05 20:56:44 -05:00
|
|
|
use slice::*;
|
2012-01-17 19:28:21 -06:00
|
|
|
|
2014-05-29 21:03:06 -05:00
|
|
|
use vec::Vec;
|
|
|
|
|
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-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());
|
2014-06-27 14:30:25 -05:00
|
|
|
assert!(![0i].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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut a = vec![11i];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(a.as_slice().get(1), None);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i, 12];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(a.as_slice().get(1).unwrap(), &12);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i, 12, 13];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(a.as_slice().get(1).unwrap(), &12);
|
2013-09-29 10:59:00 -05:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_head() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let mut a = vec![];
|
|
|
|
assert_eq!(a.as_slice().head(), None);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(a.as_slice().head().unwrap(), &11);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i, 12];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(a.as_slice().head().unwrap(), &11);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2014-09-23 18:23:27 -05:00
|
|
|
#[test]
|
|
|
|
fn test_head_mut() {
|
|
|
|
let mut a = vec![];
|
|
|
|
assert_eq!(a.as_mut_slice().head_mut(), None);
|
|
|
|
a = vec![11i];
|
|
|
|
assert_eq!(*a.as_mut_slice().head_mut().unwrap(), 11);
|
|
|
|
a = vec![11i, 12];
|
|
|
|
assert_eq!(*a.as_mut_slice().head_mut().unwrap(), 11);
|
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_tail() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut a = vec![11i];
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[];
|
|
|
|
assert_eq!(a.tail(), b);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i, 12];
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[12];
|
|
|
|
assert_eq!(a.tail(), b);
|
2013-03-03 09:22:40 -06:00
|
|
|
}
|
|
|
|
|
2014-09-23 18:23:27 -05:00
|
|
|
#[test]
|
|
|
|
fn test_tail_mut() {
|
|
|
|
let mut a = vec![11i];
|
|
|
|
let b: &mut [int] = &mut [];
|
|
|
|
assert!(a.as_mut_slice().tail_mut() == b);
|
|
|
|
a = vec![11i, 12];
|
|
|
|
let b: &mut [int] = &mut [12];
|
|
|
|
assert!(a.as_mut_slice().tail_mut() == b);
|
|
|
|
}
|
|
|
|
|
2013-03-03 09:22:40 -06:00
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_tail_empty() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let a: Vec<int> = vec![];
|
2013-03-03 09:22:40 -06:00
|
|
|
a.tail();
|
|
|
|
}
|
|
|
|
|
2014-09-23 18:23:27 -05:00
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_tail_mut_empty() {
|
|
|
|
let mut a: Vec<int> = vec![];
|
|
|
|
a.as_mut_slice().tail_mut();
|
|
|
|
}
|
|
|
|
|
2013-03-03 10:06:31 -06:00
|
|
|
#[test]
|
|
|
|
fn test_init() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut a = vec![11i];
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[];
|
|
|
|
assert_eq!(a.init(), b);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i, 12];
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[11];
|
|
|
|
assert_eq!(a.init(), b);
|
2013-03-03 10:06:31 -06:00
|
|
|
}
|
|
|
|
|
2014-09-23 18:23:27 -05:00
|
|
|
#[test]
|
|
|
|
fn test_init_mut() {
|
|
|
|
let mut a = vec![11i];
|
|
|
|
let b: &mut [int] = &mut [];
|
|
|
|
assert!(a.as_mut_slice().init_mut() == b);
|
|
|
|
a = vec![11i, 12];
|
|
|
|
let b: &mut [int] = &mut [11];
|
|
|
|
assert!(a.as_mut_slice().init_mut() == b);
|
|
|
|
}
|
|
|
|
|
2013-11-05 21:16:47 -06:00
|
|
|
#[test]
|
2013-03-03 10:06:31 -06:00
|
|
|
#[should_fail]
|
|
|
|
fn test_init_empty() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let a: Vec<int> = vec![];
|
2013-03-03 10:06:31 -06:00
|
|
|
a.init();
|
|
|
|
}
|
|
|
|
|
2014-09-23 18:23:27 -05:00
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_init_mut_empty() {
|
|
|
|
let mut a: Vec<int> = vec![];
|
|
|
|
a.as_mut_slice().init_mut();
|
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
|
|
|
fn test_last() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let mut a = vec![];
|
|
|
|
assert_eq!(a.as_slice().last(), None);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(a.as_slice().last().unwrap(), &11);
|
2014-04-21 16:58:52 -05:00
|
|
|
a = vec![11i, 12];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(a.as_slice().last().unwrap(), &12);
|
2012-01-17 19:28:21 -06:00
|
|
|
}
|
|
|
|
|
2014-09-23 18:23:27 -05:00
|
|
|
#[test]
|
|
|
|
fn test_last_mut() {
|
|
|
|
let mut a = vec![];
|
|
|
|
assert_eq!(a.as_mut_slice().last_mut(), None);
|
|
|
|
a = vec![11i];
|
|
|
|
assert_eq!(*a.as_mut_slice().last_mut().unwrap(), 11);
|
|
|
|
a = vec![11i, 12];
|
|
|
|
assert_eq!(*a.as_mut_slice().last_mut().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.
|
2014-04-21 16:58:52 -05:00
|
|
|
let vec_fixed = [1i, 2, 3, 4];
|
2014-09-24 06:41:09 -05:00
|
|
|
let v_a = vec_fixed[1u..vec_fixed.len()].to_vec();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_a.len(), 3u);
|
2014-06-06 12:27:49 -05:00
|
|
|
let v_a = v_a.as_slice();
|
2013-05-18 21:02:45 -05:00
|
|
|
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.
|
2014-09-24 06:41:09 -05:00
|
|
|
let vec_stack: &[_] = &[1i, 2, 3];
|
|
|
|
let v_b = vec_stack[1u..3u].to_vec();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_b.len(), 2u);
|
2014-06-06 12:27:49 -05:00
|
|
|
let v_b = v_b.as_slice();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_b[0], 2);
|
|
|
|
assert_eq!(v_b[1], 3);
|
2013-02-08 13:28:20 -06:00
|
|
|
|
2014-05-20 22:43:18 -05:00
|
|
|
// Test `Box<[T]>`
|
2014-04-21 16:58:52 -05:00
|
|
|
let vec_unique = vec![1i, 2, 3, 4, 5, 6];
|
2014-09-24 06:41:09 -05:00
|
|
|
let v_d = vec_unique[1u..6u].to_vec();
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(v_d.len(), 5u);
|
2014-06-06 12:27:49 -05:00
|
|
|
let v_d = v_d.as_slice();
|
2013-05-18 21:02:45 -05:00
|
|
|
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() {
|
2014-08-04 07:19:02 -05:00
|
|
|
let vec: &[int] = &[1, 2, 3, 4];
|
2014-09-24 06:41:09 -05:00
|
|
|
assert_eq!(vec[0..], vec);
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[3, 4];
|
2014-09-24 06:41:09 -05:00
|
|
|
assert_eq!(vec[2..], b);
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[];
|
2014-09-24 06:41:09 -05:00
|
|
|
assert_eq!(vec[4..], b);
|
2013-07-21 08:39:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_slice_to() {
|
2014-08-04 07:19:02 -05:00
|
|
|
let vec: &[int] = &[1, 2, 3, 4];
|
2014-09-24 06:41:09 -05:00
|
|
|
assert_eq!(vec[..4], vec);
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[1, 2];
|
2014-09-24 06:41:09 -05:00
|
|
|
assert_eq!(vec[..2], b);
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &[int] = &[];
|
2014-09-24 06:41:09 -05:00
|
|
|
assert_eq!(vec[..0], b);
|
2013-07-21 08:39:01 -05:00
|
|
|
}
|
|
|
|
|
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-21 16:58:52 -05:00
|
|
|
let mut v = vec![5i];
|
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-21 16:58:52 -05:00
|
|
|
let mut v = vec![1i, 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-21 16:58:52 -05:00
|
|
|
assert_eq!(v, vec![5i, 2, 3, 4]);
|
2014-02-22 17:56:38 -06:00
|
|
|
e = v.swap_remove(3);
|
|
|
|
assert_eq!(e, Some(4));
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!(v, vec![5i, 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-21 16:58:52 -05:00
|
|
|
assert_eq!(v, vec![5i, 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-06-04 02:01:40 -05:00
|
|
|
let mut v = vec![rt::exclusive::Exclusive::new(()),
|
|
|
|
rt::exclusive::Exclusive::new(()),
|
|
|
|
rt::exclusive::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![];
|
2014-04-21 16:58:52 -05:00
|
|
|
v.push(1i);
|
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().
|
2014-04-21 16:58:52 -05:00
|
|
|
v.push(2i);
|
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![];
|
2014-09-17 14:56:31 -05:00
|
|
|
v.grow(2u, 1i);
|
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().
|
2014-09-17 14:56:31 -05:00
|
|
|
v.grow(3u, 2i);
|
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
|
|
|
}
|
|
|
|
|
2012-08-29 03:21:49 -05:00
|
|
|
#[test]
|
|
|
|
fn test_truncate() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v = vec![box 6i,box 5,box 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-21 16:58:52 -05:00
|
|
|
let mut v = vec![box 6i,box 5,box 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![]);
|
2014-04-21 16:58:52 -05:00
|
|
|
case(vec![1u], vec![1]);
|
|
|
|
case(vec![1u,1], vec![1]);
|
|
|
|
case(vec![1u,2,3], vec![1,2,3]);
|
|
|
|
case(vec![1u,1,2,3], vec![1,2,3]);
|
|
|
|
case(vec![1u,2,2,3], vec![1,2,3]);
|
|
|
|
case(vec![1u,2,3,3], vec![1,2,3]);
|
|
|
|
case(vec![1u,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-21 16:58:52 -05:00
|
|
|
let mut v0 = vec![box 1i, box 1, box 2, box 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v0.dedup();
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v1 = vec![box 1i, box 2, box 2, box 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v1.dedup();
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v2 = vec![box 1i, box 2, box 3, box 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v2.dedup();
|
2012-09-01 14:11:54 -05:00
|
|
|
/*
|
2014-05-05 20:56:44 -05:00
|
|
|
* If the boxed pointers were leaked or otherwise misused, valgrind
|
|
|
|
* and/or rustrt should raise errors.
|
2012-09-01 14:11:54 -05:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_dedup_shared() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v0 = vec![box 1i, box 1, box 2, box 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v0.dedup();
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v1 = vec![box 1i, box 2, box 2, box 3];
|
2012-09-28 00:20:47 -05:00
|
|
|
v1.dedup();
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v2 = vec![box 1i, box 2, box 3, box 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-21 16:58:52 -05:00
|
|
|
let mut v = vec![1u, 2, 3, 4, 5];
|
2013-01-14 01:10:54 -06:00
|
|
|
v.retain(is_odd);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!(v, vec![1u, 3, 5]);
|
2013-01-14 01:10:54 -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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v = [1i, 2, 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
|
|
|
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]),
|
2014-10-09 14:17:22 -05:00
|
|
|
_ => panic!(),
|
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);
|
2014-07-16 15:37:28 -05:00
|
|
|
assert_eq!(it.next(), Some(v.as_slice().to_vec()));
|
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-05-25 05:10:11 -05:00
|
|
|
let v = ["Hello".to_string()];
|
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);
|
2014-07-16 15:37:28 -05:00
|
|
|
assert_eq!(it.next(), Some(v.as_slice().to_vec()));
|
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-21 16:58:52 -05:00
|
|
|
let v = [1i, 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);
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(it.next(), Some(vec![1,2,3]));
|
|
|
|
assert_eq!(it.next(), Some(vec![1,3,2]));
|
|
|
|
assert_eq!(it.next(), Some(vec![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);
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(it.next(), Some(vec![3,2,1]));
|
|
|
|
assert_eq!(it.next(), Some(vec![2,3,1]));
|
|
|
|
assert_eq!(it.next(), Some(vec![2,1,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(), 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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-03 09:11:47 -05:00
|
|
|
#[test]
|
|
|
|
fn test_lexicographic_permutations() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let v : &mut[int] = &mut[1i, 2, 3, 4, 5];
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.prev_permutation() == false);
|
|
|
|
assert!(v.next_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[1, 2, 3, 5, 4];
|
|
|
|
assert!(v == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.prev_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[1, 2, 3, 4, 5];
|
|
|
|
assert!(v == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.next_permutation());
|
|
|
|
assert!(v.next_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[1, 2, 4, 3, 5];
|
|
|
|
assert!(v == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.next_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[1, 2, 4, 5, 3];
|
|
|
|
assert!(v == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
let v : &mut[int] = &mut[1i, 0, 0, 0];
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.next_permutation() == false);
|
|
|
|
assert!(v.prev_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[0, 1, 0, 0];
|
|
|
|
assert!(v == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.prev_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[0, 0, 1, 0];
|
|
|
|
assert!(v == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.prev_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[0, 0, 0, 1];
|
|
|
|
assert!(v == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(v.prev_permutation() == false);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_lexicographic_permutations_empty_and_short() {
|
|
|
|
let empty : &mut[int] = &mut[];
|
|
|
|
assert!(empty.next_permutation() == false);
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[];
|
|
|
|
assert!(empty == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(empty.prev_permutation() == false);
|
2014-08-04 07:19:02 -05:00
|
|
|
assert!(empty == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
let one_elem : &mut[int] = &mut[4i];
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(one_elem.prev_permutation() == false);
|
2014-08-04 07:19:02 -05:00
|
|
|
let b: &mut[int] = &mut[4];
|
|
|
|
assert!(one_elem == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(one_elem.next_permutation() == false);
|
2014-08-04 07:19:02 -05:00
|
|
|
assert!(one_elem == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
let two_elem : &mut[int] = &mut[1i, 2];
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(two_elem.prev_permutation() == false);
|
2014-08-04 07:19:02 -05:00
|
|
|
let b : &mut[int] = &mut[1, 2];
|
|
|
|
let c : &mut[int] = &mut[2, 1];
|
|
|
|
assert!(two_elem == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(two_elem.next_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
assert!(two_elem == c);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(two_elem.next_permutation() == false);
|
2014-08-04 07:19:02 -05:00
|
|
|
assert!(two_elem == c);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(two_elem.prev_permutation());
|
2014-08-04 07:19:02 -05:00
|
|
|
assert!(two_elem == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
assert!(two_elem.prev_permutation() == false);
|
2014-08-04 07:19:02 -05:00
|
|
|
assert!(two_elem == b);
|
2014-06-03 09:11:47 -05:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:28:21 -06:00
|
|
|
#[test]
|
2012-03-18 19:14:43 -05:00
|
|
|
fn test_position_elem() {
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!([].position_elem(&1i).is_none());
|
2012-01-26 10:39:45 -06:00
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
let v1 = vec![1i, 2, 3, 3, 2, 5];
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!(v1.as_slice().position_elem(&1), Some(0u));
|
|
|
|
assert_eq!(v1.as_slice().position_elem(&2), Some(1u));
|
|
|
|
assert_eq!(v1.as_slice().position_elem(&5), Some(5u));
|
|
|
|
assert!(v1.as_slice().position_elem(&4).is_none());
|
2012-01-26 20:14:27 -06:00
|
|
|
}
|
|
|
|
|
2013-01-04 15:52:18 -06:00
|
|
|
#[test]
|
2014-10-15 01:05:01 -05:00
|
|
|
fn test_binary_search_elem() {
|
|
|
|
assert_eq!([1i,2,3,4,5].binary_search_elem(&5).found(), Some(4));
|
|
|
|
assert_eq!([1i,2,3,4,5].binary_search_elem(&4).found(), Some(3));
|
|
|
|
assert_eq!([1i,2,3,4,5].binary_search_elem(&3).found(), Some(2));
|
|
|
|
assert_eq!([1i,2,3,4,5].binary_search_elem(&2).found(), Some(1));
|
|
|
|
assert_eq!([1i,2,3,4,5].binary_search_elem(&1).found(), Some(0));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert_eq!([2i,4,6,8,10].binary_search_elem(&1).found(), None);
|
|
|
|
assert_eq!([2i,4,6,8,10].binary_search_elem(&5).found(), None);
|
|
|
|
assert_eq!([2i,4,6,8,10].binary_search_elem(&4).found(), Some(1));
|
|
|
|
assert_eq!([2i,4,6,8,10].binary_search_elem(&10).found(), Some(4));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert_eq!([2i,4,6,8].binary_search_elem(&1).found(), None);
|
|
|
|
assert_eq!([2i,4,6,8].binary_search_elem(&5).found(), None);
|
|
|
|
assert_eq!([2i,4,6,8].binary_search_elem(&4).found(), Some(1));
|
|
|
|
assert_eq!([2i,4,6,8].binary_search_elem(&8).found(), Some(3));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert_eq!([2i,4,6].binary_search_elem(&1).found(), None);
|
|
|
|
assert_eq!([2i,4,6].binary_search_elem(&5).found(), None);
|
|
|
|
assert_eq!([2i,4,6].binary_search_elem(&4).found(), Some(1));
|
|
|
|
assert_eq!([2i,4,6].binary_search_elem(&6).found(), Some(2));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert_eq!([2i,4].binary_search_elem(&1).found(), None);
|
|
|
|
assert_eq!([2i,4].binary_search_elem(&5).found(), None);
|
|
|
|
assert_eq!([2i,4].binary_search_elem(&2).found(), Some(0));
|
|
|
|
assert_eq!([2i,4].binary_search_elem(&4).found(), Some(1));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert_eq!([2i].binary_search_elem(&1).found(), None);
|
|
|
|
assert_eq!([2i].binary_search_elem(&5).found(), None);
|
|
|
|
assert_eq!([2i].binary_search_elem(&2).found(), Some(0));
|
2013-05-18 21:02:45 -05:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert_eq!([].binary_search_elem(&1i).found(), None);
|
|
|
|
assert_eq!([].binary_search_elem(&5i).found(), None);
|
2013-01-08 10:44:31 -06:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert!([1i,1,1,1,1].binary_search_elem(&1).found() != None);
|
|
|
|
assert!([1i,1,1,1,2].binary_search_elem(&1).found() != None);
|
|
|
|
assert!([1i,1,1,2,2].binary_search_elem(&1).found() != None);
|
|
|
|
assert!([1i,1,2,2,2].binary_search_elem(&1).found() != None);
|
|
|
|
assert_eq!([1i,2,2,2,2].binary_search_elem(&1).found(), Some(0));
|
2013-01-08 10:44:31 -06:00
|
|
|
|
2014-10-15 01:05:01 -05:00
|
|
|
assert_eq!([1i,2,3,4,5].binary_search_elem(&6).found(), None);
|
|
|
|
assert_eq!([1i,2,3,4,5].binary_search_elem(&0).found(), 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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v: Vec<int> = vec![10i, 20];
|
2014-09-22 12:30:06 -05:00
|
|
|
assert_eq!(v[0], 10);
|
|
|
|
assert_eq!(v[1], 20);
|
2013-06-28 11:54:03 -05:00
|
|
|
v.reverse();
|
2014-09-22 12:30:06 -05:00
|
|
|
assert_eq!(v[0], 20);
|
|
|
|
assert_eq!(v[1], 10);
|
2013-07-01 21:58:23 -05:00
|
|
|
|
2014-06-06 12:27:49 -05:00
|
|
|
let mut v3: Vec<int> = vec![];
|
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() {
|
|
|
|
for len in range(4u, 25) {
|
2014-04-21 16:58:52 -05:00
|
|
|
for _ in range(0i, 100) {
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
let mut v = task_rng().gen_iter::<uint>().take(len)
|
|
|
|
.collect::<Vec<uint>>();
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-09 14:17:22 -05:00
|
|
|
// shouldn't panic
|
2013-12-18 16:24:26 -06:00
|
|
|
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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
for len in range(4i, 25) {
|
|
|
|
for _ in range(0u, 10) {
|
|
|
|
let mut counts = [0i, .. 10];
|
2013-12-18 16:24:26 -06:00
|
|
|
|
|
|
|
// 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-05-03 20:33:48 -05:00
|
|
|
}).collect::<Vec<(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.
|
2014-05-03 20:33:48 -05:00
|
|
|
assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
|
2013-12-18 16:24:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-08 14:03:33 -05:00
|
|
|
#[test]
|
|
|
|
fn test_partition() {
|
2014-06-06 12:27:49 -05:00
|
|
|
assert_eq!((vec![]).partition(|x: &int| *x < 3), (vec![], vec![]));
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!((vec![1i, 2, 3]).partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
|
|
|
|
assert_eq!((vec![1i, 2, 3]).partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
|
|
|
|
assert_eq!((vec![1i, 2, 3]).partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
|
2014-05-08 14:03:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_partitioned() {
|
|
|
|
assert_eq!(([]).partitioned(|x: &int| *x < 3), (vec![], vec![]));
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!(([1i, 2, 3]).partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
|
|
|
|
assert_eq!(([1i, 2, 3]).partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
|
|
|
|
assert_eq!(([1i, 2, 3]).partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
|
2014-05-08 14:03:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_concat() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let v: [Vec<int>, ..0] = [];
|
2014-05-08 14:03:33 -05:00
|
|
|
assert_eq!(v.concat_vec(), vec![]);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!([vec![1i], vec![2i,3i]].concat_vec(), vec![1, 2, 3]);
|
2014-05-08 14:03:33 -05:00
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let v: [&[int], ..2] = [&[1], &[2, 3]];
|
|
|
|
assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 3]);
|
|
|
|
let v: [&[int], ..3] = [&[1], &[2], &[3]];
|
|
|
|
assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 0, 3]);
|
2014-05-08 14:03:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_connect() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let v: [Vec<int>, ..0] = [];
|
2014-05-08 14:03:33 -05:00
|
|
|
assert_eq!(v.connect_vec(&0), vec![]);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!([vec![1i], vec![2i, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
|
|
|
|
assert_eq!([vec![1i], vec![2i], vec![3i]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
|
2014-05-08 14:03:33 -05:00
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let v: [&[int], ..2] = [&[1], &[2, 3]];
|
|
|
|
assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 3]);
|
|
|
|
let v: [&[int], ..3] = [&[1], &[2], &[3]];
|
|
|
|
assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 0, 3]);
|
2014-05-08 14:03:33 -05:00
|
|
|
}
|
|
|
|
|
2012-11-25 07:28:16 -06:00
|
|
|
#[test]
|
|
|
|
fn test_insert() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut a = vec![1i, 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-21 16:58:52 -05:00
|
|
|
let mut a = vec![1i, 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-21 16:58:52 -05:00
|
|
|
let mut a = vec![1i, 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![];
|
2014-04-21 16:58:52 -05:00
|
|
|
a.insert(0, 1i);
|
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-21 16:58:52 -05:00
|
|
|
let mut a = vec![1i, 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-21 16:58:52 -05:00
|
|
|
let mut a = vec![1i,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-21 16:58:52 -05:00
|
|
|
assert_eq!(a, vec![1i,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-21 16:58:52 -05:00
|
|
|
assert_eq!(a, vec![1i,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-21 16:58:52 -05:00
|
|
|
assert_eq!(a, vec![1i,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-21 16:58:52 -05:00
|
|
|
assert_eq!(a, vec![2i]);
|
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);
|
2014-11-06 11:24:47 -06:00
|
|
|
assert!(v.capacity() >= 11u);
|
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);
|
2014-11-06 11:24:47 -06:00
|
|
|
assert!(v.capacity() >= 11u);
|
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-21 16:58:52 -05:00
|
|
|
let v = vec![1i, 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| {
|
2014-10-09 14:17:22 -05:00
|
|
|
if v == 50 { panic!() }
|
2014-04-21 16:58:52 -05:00
|
|
|
box 0i
|
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() {
|
|
|
|
|
|
|
|
struct S {
|
std: deprecate cast::transmute_mut.
Turning a `&T` into an `&mut T` carries a large risk of undefined
behaviour, and needs to be done very very carefully. Providing a
convenience function for exactly this task is a bad idea, just tempting
people into doing the wrong thing.
The right thing is to use types like `Cell`, `RefCell` or `Unsafe`.
For memory safety, Rust has that guarantee that `&mut` pointers do not
alias with any other pointer, that is, if you have a `&mut T` then that
is the only usable pointer to that `T`. This allows Rust to assume that
writes through a `&mut T` do not affect the values of any other `&` or
`&mut` references. `&` pointers have no guarantees about aliasing or
not, so it's entirely possible for the same pointer to be passed into
both arguments of a function like
fn foo(x: &int, y: &int) { ... }
Converting either of `x` or `y` to a `&mut` pointer and modifying it
would affect the other value: invalid behaviour.
(Similarly, it's undefined behaviour to modify the value of an immutable
local, like `let x = 1;`.)
At a low-level, the *only* safe way to obtain an `&mut` out of a `&` is
using the `Unsafe` type (there are higher level wrappers around it, like
`Cell`, `RefCell`, `Mutex` etc.). The `Unsafe` type is registered with
the compiler so that it can reason a little about these `&` to `&mut`
casts, but it is still up to the user to ensure that the `&mut`s
obtained out of an `Unsafe` never alias.
(Note that *any* conversion from `&` to `&mut` can be invalid, including
a plain `transmute`, or casting `&T` -> `*T` -> `*mut T` -> `&mut T`.)
[breaking-change]
2014-05-04 08:17:37 -05:00
|
|
|
f: Cell<int>,
|
2014-05-05 20:56:44 -05:00
|
|
|
boxes: (Box<int>, Rc<int>)
|
2013-08-26 20:17:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for S {
|
|
|
|
fn clone(&self) -> S {
|
std: deprecate cast::transmute_mut.
Turning a `&T` into an `&mut T` carries a large risk of undefined
behaviour, and needs to be done very very carefully. Providing a
convenience function for exactly this task is a bad idea, just tempting
people into doing the wrong thing.
The right thing is to use types like `Cell`, `RefCell` or `Unsafe`.
For memory safety, Rust has that guarantee that `&mut` pointers do not
alias with any other pointer, that is, if you have a `&mut T` then that
is the only usable pointer to that `T`. This allows Rust to assume that
writes through a `&mut T` do not affect the values of any other `&` or
`&mut` references. `&` pointers have no guarantees about aliasing or
not, so it's entirely possible for the same pointer to be passed into
both arguments of a function like
fn foo(x: &int, y: &int) { ... }
Converting either of `x` or `y` to a `&mut` pointer and modifying it
would affect the other value: invalid behaviour.
(Similarly, it's undefined behaviour to modify the value of an immutable
local, like `let x = 1;`.)
At a low-level, the *only* safe way to obtain an `&mut` out of a `&` is
using the `Unsafe` type (there are higher level wrappers around it, like
`Cell`, `RefCell`, `Mutex` etc.). The `Unsafe` type is registered with
the compiler so that it can reason a little about these `&` to `&mut`
casts, but it is still up to the user to ensure that the `&mut`s
obtained out of an `Unsafe` never alias.
(Note that *any* conversion from `&` to `&mut` can be invalid, including
a plain `transmute`, or casting `&T` -> `*T` -> `*mut T` -> `&mut T`.)
[breaking-change]
2014-05-04 08:17:37 -05:00
|
|
|
self.f.set(self.f.get() + 1);
|
2014-10-09 14:17:22 -05:00
|
|
|
if self.f.get() == 10 { panic!() }
|
std: deprecate cast::transmute_mut.
Turning a `&T` into an `&mut T` carries a large risk of undefined
behaviour, and needs to be done very very carefully. Providing a
convenience function for exactly this task is a bad idea, just tempting
people into doing the wrong thing.
The right thing is to use types like `Cell`, `RefCell` or `Unsafe`.
For memory safety, Rust has that guarantee that `&mut` pointers do not
alias with any other pointer, that is, if you have a `&mut T` then that
is the only usable pointer to that `T`. This allows Rust to assume that
writes through a `&mut T` do not affect the values of any other `&` or
`&mut` references. `&` pointers have no guarantees about aliasing or
not, so it's entirely possible for the same pointer to be passed into
both arguments of a function like
fn foo(x: &int, y: &int) { ... }
Converting either of `x` or `y` to a `&mut` pointer and modifying it
would affect the other value: invalid behaviour.
(Similarly, it's undefined behaviour to modify the value of an immutable
local, like `let x = 1;`.)
At a low-level, the *only* safe way to obtain an `&mut` out of a `&` is
using the `Unsafe` type (there are higher level wrappers around it, like
`Cell`, `RefCell`, `Mutex` etc.). The `Unsafe` type is registered with
the compiler so that it can reason a little about these `&` to `&mut`
casts, but it is still up to the user to ensure that the `&mut`s
obtained out of an `Unsafe` never alias.
(Note that *any* conversion from `&` to `&mut` can be invalid, including
a plain `transmute`, or casting `&T` -> `*T` -> `*mut T` -> `&mut T`.)
[breaking-change]
2014-05-04 08:17:37 -05:00
|
|
|
S { f: self.f, boxes: self.boxes.clone() }
|
2013-08-26 20:17:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
std: deprecate cast::transmute_mut.
Turning a `&T` into an `&mut T` carries a large risk of undefined
behaviour, and needs to be done very very carefully. Providing a
convenience function for exactly this task is a bad idea, just tempting
people into doing the wrong thing.
The right thing is to use types like `Cell`, `RefCell` or `Unsafe`.
For memory safety, Rust has that guarantee that `&mut` pointers do not
alias with any other pointer, that is, if you have a `&mut T` then that
is the only usable pointer to that `T`. This allows Rust to assume that
writes through a `&mut T` do not affect the values of any other `&` or
`&mut` references. `&` pointers have no guarantees about aliasing or
not, so it's entirely possible for the same pointer to be passed into
both arguments of a function like
fn foo(x: &int, y: &int) { ... }
Converting either of `x` or `y` to a `&mut` pointer and modifying it
would affect the other value: invalid behaviour.
(Similarly, it's undefined behaviour to modify the value of an immutable
local, like `let x = 1;`.)
At a low-level, the *only* safe way to obtain an `&mut` out of a `&` is
using the `Unsafe` type (there are higher level wrappers around it, like
`Cell`, `RefCell`, `Mutex` etc.). The `Unsafe` type is registered with
the compiler so that it can reason a little about these `&` to `&mut`
casts, but it is still up to the user to ensure that the `&mut`s
obtained out of an `Unsafe` never alias.
(Note that *any* conversion from `&` to `&mut` can be invalid, including
a plain `transmute`, or casting `&T` -> `*T` -> `*mut T` -> `&mut T`.)
[breaking-change]
2014-05-04 08:17:37 -05:00
|
|
|
let s = S { f: Cell::new(0), boxes: (box 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() {
|
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 {
|
2014-10-09 14:17:22 -05:00
|
|
|
panic!()
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
2014-04-21 16:58:52 -05:00
|
|
|
(box 0i, Rc::new(0i))
|
2013-11-20 16:17:12 -06:00
|
|
|
})
|
2012-09-27 18:41:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_permute_fail() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let v = [(box 0i, Rc::new(0i)), (box 0i, Rc::new(0i)),
|
|
|
|
(box 0i, Rc::new(0i)), (box 0i, Rc::new(0i))];
|
2014-06-27 14:30:25 -05:00
|
|
|
let mut i = 0u;
|
2013-11-23 04:18:51 -06:00
|
|
|
for _ in v.permutations() {
|
2012-09-27 18:41:38 -05:00
|
|
|
if i == 2 {
|
2014-10-09 14:17:22 -05:00
|
|
|
panic!()
|
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-03-01 21:07:12 -06:00
|
|
|
#[test]
|
|
|
|
fn test_total_ord() {
|
2014-08-04 07:19:02 -05:00
|
|
|
let c: &[int] = &[1, 2, 3];
|
2014-11-03 13:55:19 -06:00
|
|
|
[1, 2, 3, 4][].cmp(c) == Greater;
|
2014-08-04 07:19:02 -05:00
|
|
|
let c: &[int] = &[1, 2, 3, 4];
|
2014-11-03 13:55:19 -06:00
|
|
|
[1, 2, 3][].cmp(c) == Less;
|
2014-08-04 07:19:02 -05:00
|
|
|
let c: &[int] = &[1, 2, 3, 6];
|
2014-11-03 13:55:19 -06:00
|
|
|
[1, 2, 3, 4][].cmp(c) == Equal;
|
2014-08-04 07:19:02 -05:00
|
|
|
let c: &[int] = &[1, 2, 3, 4, 5, 6];
|
2014-11-03 13:55:19 -06:00
|
|
|
[1, 2, 3, 4, 5, 5, 5, 5][].cmp(c) == Less;
|
2014-08-04 07:19:02 -05:00
|
|
|
let c: &[int] = &[1, 2, 3, 4];
|
2014-11-03 13:55:19 -06:00
|
|
|
[2, 2][].cmp(c) == Greater;
|
2013-03-01 21:07:12 -06:00
|
|
|
}
|
2013-04-17 18:34:53 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_iterator() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let xs = [1i, 2, 5, 10, 11];
|
2013-04-17 18:34:53 -05:00
|
|
|
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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let xs = [1i, 2, 5, 10, 11];
|
2013-07-22 19:11:24 -05:00
|
|
|
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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut xs = [1i, 2, 5, 10, 11];
|
2013-07-02 20:40:46 -05:00
|
|
|
assert_eq!(xs.iter().size_hint(), (5, Some(5)));
|
2014-09-14 22:27:36 -05:00
|
|
|
assert_eq!(xs.iter_mut().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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let xs = [1i, 2, 5];
|
2013-07-18 10:38:17 -05:00
|
|
|
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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut xs = [1i, 2, 3, 4, 5];
|
2014-09-14 22:27:36 -05:00
|
|
|
for x in xs.iter_mut() {
|
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() {
|
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
let xs = [1i, 2, 5, 10, 11];
|
2013-06-07 21:39:52 -05:00
|
|
|
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-06-07 23:07:55 -05:00
|
|
|
let mut xs = [1u, 2, 3, 4, 5];
|
2014-09-14 22:27:36 -05:00
|
|
|
for (i,x) in xs.iter_mut().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() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let xs = vec![1u,2,3,4,5];
|
2014-09-14 22:27:36 -05:00
|
|
|
assert_eq!(xs.into_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() {
|
2014-06-06 12:27:49 -05:00
|
|
|
let xs = vec![1u,2,3,4,5];
|
2014-09-14 22:27:36 -05:00
|
|
|
assert_eq!(xs.into_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];
|
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[1], &[3], &[5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[], &[2,3,4,5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x == 1).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[1,2,3,4], &[]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[1,2,3,4,5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x == 10).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[], &[], &[], &[], &[], &[]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|_| true).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[]];
|
|
|
|
assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(), splits);
|
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];
|
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[1,2,3,4,5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[1], &[3,4,5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[], &[], &[], &[4,5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.splitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[]];
|
|
|
|
assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), splits);
|
2013-07-02 23:54:11 -05:00
|
|
|
}
|
|
|
|
|
2014-09-23 18:23:27 -05:00
|
|
|
#[test]
|
|
|
|
fn test_splitnator_mut() {
|
|
|
|
let xs = &mut [1i,2,3,4,5];
|
|
|
|
|
|
|
|
let splits: &[&mut [int]] = &[&mut [1,2,3,4,5]];
|
|
|
|
assert_eq!(xs.splitn_mut(0, |x| *x % 2 == 0).collect::<Vec<&mut [int]>>().as_slice(),
|
|
|
|
splits);
|
|
|
|
let splits: &[&mut [int]] = &[&mut [1], &mut [3,4,5]];
|
|
|
|
assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<&mut [int]>>().as_slice(),
|
|
|
|
splits);
|
|
|
|
let splits: &[&mut [int]] = &[&mut [], &mut [], &mut [], &mut [4,5]];
|
|
|
|
assert_eq!(xs.splitn_mut(3, |_| true).collect::<Vec<&mut [int]>>().as_slice(),
|
|
|
|
splits);
|
|
|
|
|
|
|
|
let xs: &mut [int] = &mut [];
|
|
|
|
let splits: &[&mut [int]] = &[&mut []];
|
|
|
|
assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::<Vec<&mut [int]>>().as_slice(),
|
|
|
|
splits);
|
|
|
|
}
|
|
|
|
|
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];
|
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[5], &[3], &[1]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[2,3,4,5], &[]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[], &[1,2,3,4]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[1,2,3,4,5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[]];
|
|
|
|
assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(), splits);
|
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];
|
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[1,2,3,4,5]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[5], &[1,2,3]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
|
|
|
let splits: &[&[int]] = &[&[], &[], &[], &[1,2]];
|
2014-05-03 20:33:48 -05:00
|
|
|
assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
|
2014-08-04 07:19:02 -05:00
|
|
|
splits);
|
2013-07-02 23:54:11 -05:00
|
|
|
|
|
|
|
let xs: &[int] = &[];
|
2014-08-04 07:19:02 -05:00
|
|
|
let splits: &[&[int]] = &[&[]];
|
|
|
|
assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), splits);
|
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];
|
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let wins: &[&[int]] = &[&[1,2], &[2,3], &[3,4]];
|
|
|
|
assert_eq!(v.windows(2).collect::<Vec<&[int]>>().as_slice(), wins);
|
|
|
|
let wins: &[&[int]] = &[&[1i,2,3], &[2,3,4]];
|
|
|
|
assert_eq!(v.windows(3).collect::<Vec<&[int]>>().as_slice(), wins);
|
2013-11-23 04:18:51 -06:00
|
|
|
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];
|
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let chunks: &[&[int]] = &[&[1i,2], &[3,4], &[5]];
|
|
|
|
assert_eq!(v.chunks(2).collect::<Vec<&[int]>>().as_slice(), chunks);
|
|
|
|
let chunks: &[&[int]] = &[&[1i,2,3], &[4,5]];
|
|
|
|
assert_eq!(v.chunks(3).collect::<Vec<&[int]>>().as_slice(), chunks);
|
|
|
|
let chunks: &[&[int]] = &[&[1i,2,3,4,5]];
|
|
|
|
assert_eq!(v.chunks(6).collect::<Vec<&[int]>>().as_slice(), chunks);
|
2013-08-03 12:40:20 -05:00
|
|
|
|
2014-08-04 07:19:02 -05:00
|
|
|
let chunks: &[&[int]] = &[&[5i], &[3,4], &[1,2]];
|
|
|
|
assert_eq!(v.chunks(2).rev().collect::<Vec<&[int]>>().as_slice(), chunks);
|
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);
|
2014-08-04 07:19:02 -05:00
|
|
|
let chunk: &[int] = &[1,2];
|
|
|
|
assert_eq!(it.idx(0).unwrap(), chunk);
|
|
|
|
let chunk: &[int] = &[3,4];
|
|
|
|
assert_eq!(it.idx(1).unwrap(), chunk);
|
|
|
|
let chunk: &[int] = &[5];
|
|
|
|
assert_eq!(it.idx(2).unwrap(), chunk);
|
2013-08-03 12:40:20 -05:00
|
|
|
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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut a = [1i,2,3,4,5];
|
|
|
|
let b = vec![6i,7,8];
|
2013-06-18 01:52:14 -05:00
|
|
|
assert_eq!(a.move_from(b, 0, 3), 3);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(a == [6i,7,8,4,5]);
|
|
|
|
let mut a = [7i,2,8,1];
|
|
|
|
let b = vec![3i,1,4,1,5,9];
|
2013-06-18 01:52:14 -05:00
|
|
|
assert_eq!(a.move_from(b, 0, 6), 4);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(a == [3i,1,4,1]);
|
|
|
|
let mut a = [1i,2,3,4];
|
|
|
|
let b = vec![5i,6,7,8,9,0];
|
2013-06-18 01:52:14 -05:00
|
|
|
assert_eq!(a.move_from(b, 2, 3), 1);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(a == [7i,2,3,4]);
|
|
|
|
let mut a = [1i,2,3,4,5];
|
|
|
|
let b = vec![5i,6,7,8,9,0];
|
2014-09-24 06:41:09 -05:00
|
|
|
assert_eq!(a[mut 2..4].move_from(b,1,6), 2);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert!(a == [1i,2,6,7,5]);
|
2013-06-18 01:52:14 -05:00
|
|
|
}
|
|
|
|
|
2013-02-13 17:52:58 -06:00
|
|
|
#[test]
|
|
|
|
fn test_reverse_part() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut values = [1i,2,3,4,5];
|
2014-09-24 06:41:09 -05:00
|
|
|
values[mut 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);
|
|
|
|
})
|
|
|
|
)
|
2014-06-06 12:27:49 -05:00
|
|
|
let empty: Vec<int> = vec![];
|
2014-05-25 05:17:19 -05:00
|
|
|
test_show_vec!(empty, "[]".to_string());
|
2014-04-21 16:58:52 -05:00
|
|
|
test_show_vec!(vec![1i], "[1]".to_string());
|
|
|
|
test_show_vec!(vec![1i, 2, 3], "[1, 2, 3]".to_string());
|
2014-06-06 12:27:49 -05:00
|
|
|
test_show_vec!(vec![vec![], vec![1u], vec![1u, 1u]],
|
2014-05-25 05:17:19 -05:00
|
|
|
"[[], [1], [1, 1]]".to_string());
|
2014-04-22 12:41:02 -05:00
|
|
|
|
|
|
|
let empty_mut: &mut [int] = &mut[];
|
2014-05-25 05:17:19 -05:00
|
|
|
test_show_vec!(empty_mut, "[]".to_string());
|
2014-08-04 07:19:02 -05:00
|
|
|
let v: &mut[int] = &mut[1];
|
|
|
|
test_show_vec!(v, "[1]".to_string());
|
|
|
|
let v: &mut[int] = &mut[1, 2, 3];
|
|
|
|
test_show_vec!(v, "[1, 2, 3]".to_string());
|
|
|
|
let v: &mut [&mut[uint]] = &mut[&mut[], &mut[1u], &mut[1u, 1u]];
|
|
|
|
test_show_vec!(v, "[[], [1], [1, 1]]".to_string());
|
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() {
|
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]);
|
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];
|
2014-09-24 06:41:09 -05:00
|
|
|
values[mut 0..5].set_memory(0xAB);
|
2014-02-28 03:23:06 -06:00
|
|
|
assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
|
2014-09-24 06:41:09 -05:00
|
|
|
values[mut 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);
|
2014-06-27 14:30:25 -05:00
|
|
|
v.push(1i);
|
2013-07-03 22:59:34 -05:00
|
|
|
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() {
|
2014-06-27 14:30:25 -05:00
|
|
|
let mut v = vec![Rc::new(1i)];
|
2014-01-31 07:03:20 -06:00
|
|
|
v.reserve_exact(-1);
|
2014-06-27 14:30:25 -05:00
|
|
|
v.push(Rc::new(2i));
|
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];
|
|
|
|
{
|
2014-09-14 22:27:36 -05:00
|
|
|
let (left, right) = values.split_at_mut(2);
|
2014-09-24 06:41:09 -05:00
|
|
|
{
|
|
|
|
let left: &[_] = left;
|
2014-10-31 04:41:25 -05:00
|
|
|
assert!(left[0..left.len()] == [1, 2][]);
|
2014-09-24 06:41:09 -05:00
|
|
|
}
|
2014-09-14 22:27:36 -05:00
|
|
|
for p in left.iter_mut() {
|
2013-07-10 08:50:24 -05:00
|
|
|
*p += 1;
|
|
|
|
}
|
|
|
|
|
2014-09-24 06:41:09 -05:00
|
|
|
{
|
|
|
|
let right: &[_] = right;
|
2014-10-31 04:41:25 -05:00
|
|
|
assert!(right[0..right.len()] == [3, 4, 5][]);
|
2014-09-24 06:41:09 -05:00
|
|
|
}
|
2014-09-14 22:27:36 -05:00
|
|
|
for p in right.iter_mut() {
|
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
|
|
|
|
2014-05-29 19:45:07 -05:00
|
|
|
#[deriving(Clone, PartialEq)]
|
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);
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut cnt = 0u;
|
2013-07-12 02:59:39 -05:00
|
|
|
|
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);
|
|
|
|
|
2014-09-24 06:41:09 -05:00
|
|
|
for f in v[1..3].iter() {
|
2013-07-12 02:59:39 -05:00
|
|
|
assert!(*f == Foo);
|
|
|
|
cnt += 1;
|
|
|
|
}
|
|
|
|
assert_eq!(cnt, 5);
|
|
|
|
|
2014-09-14 22:27:36 -05:00
|
|
|
for f in v.iter_mut() {
|
2013-07-12 02:59:39 -05:00
|
|
|
assert!(*f == Foo);
|
|
|
|
cnt += 1;
|
|
|
|
}
|
|
|
|
assert_eq!(cnt, 8);
|
|
|
|
|
2014-09-14 22:27:36 -05:00
|
|
|
for f in v.into_iter() {
|
2013-07-12 02:59:39 -05:00
|
|
|
assert!(f == Foo);
|
|
|
|
cnt += 1;
|
|
|
|
}
|
|
|
|
assert_eq!(cnt, 11);
|
|
|
|
|
|
|
|
let xs: [Foo, ..3] = [Foo, Foo, Foo];
|
|
|
|
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];
|
2014-04-21 16:58:52 -05:00
|
|
|
for i in range(4i, 100) {
|
2013-08-19 13:17:10 -05:00
|
|
|
xs.push(i)
|
|
|
|
}
|
|
|
|
assert_eq!(xs.capacity(), 128);
|
|
|
|
xs.shrink_to_fit();
|
|
|
|
assert_eq!(xs.capacity(), 100);
|
2014-04-21 16:58:52 -05:00
|
|
|
assert_eq!(xs, range(0i, 100i).collect::<Vec<_>>());
|
2013-08-19 13:17:10 -05:00
|
|
|
}
|
2013-10-17 00:01:20 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_starts_with() {
|
2014-06-18 13:25:36 -05:00
|
|
|
assert!(b"foobar".starts_with(b"foo"));
|
|
|
|
assert!(!b"foobar".starts_with(b"oob"));
|
|
|
|
assert!(!b"foobar".starts_with(b"bar"));
|
|
|
|
assert!(!b"foo".starts_with(b"foobar"));
|
|
|
|
assert!(!b"bar".starts_with(b"foobar"));
|
|
|
|
assert!(b"foobar".starts_with(b"foobar"));
|
2014-11-17 02:39:01 -06:00
|
|
|
let empty: &[u8] = &[];
|
2013-10-17 00:01:20 -05:00
|
|
|
assert!(empty.starts_with(empty));
|
2014-06-18 13:25:36 -05:00
|
|
|
assert!(!empty.starts_with(b"foo"));
|
|
|
|
assert!(b"foobar".starts_with(empty));
|
2013-10-17 00:01:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_ends_with() {
|
2014-06-18 13:25:36 -05:00
|
|
|
assert!(b"foobar".ends_with(b"bar"));
|
|
|
|
assert!(!b"foobar".ends_with(b"oba"));
|
|
|
|
assert!(!b"foobar".ends_with(b"foo"));
|
|
|
|
assert!(!b"foo".ends_with(b"foobar"));
|
|
|
|
assert!(!b"bar".ends_with(b"foobar"));
|
|
|
|
assert!(b"foobar".ends_with(b"foobar"));
|
2014-11-17 02:39:01 -06:00
|
|
|
let empty: &[u8] = &[];
|
2013-10-17 00:01:20 -05:00
|
|
|
assert!(empty.ends_with(empty));
|
2014-06-18 13:25:36 -05:00
|
|
|
assert!(!empty.ends_with(b"foo"));
|
|
|
|
assert!(b"foobar".ends_with(empty));
|
2013-10-17 00:01:20 -05:00
|
|
|
}
|
2013-11-16 16:29:19 -06:00
|
|
|
|
2013-12-01 11:50:34 -06:00
|
|
|
#[test]
|
|
|
|
fn test_mut_splitator() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut xs = [0i,1,0,2,3,0,0,4,5,0];
|
2014-09-14 22:27:36 -05:00
|
|
|
assert_eq!(xs.split_mut(|x| *x == 0).count(), 6);
|
|
|
|
for slice in xs.split_mut(|x| *x == 0) {
|
2013-12-01 11:50:34 -06:00
|
|
|
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
|
|
|
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut xs = [0i,1,0,2,3,0,0,4,5,0,6,7];
|
2014-09-14 22:27:36 -05:00
|
|
|
for slice in xs.split_mut(|x| *x == 0).take(5) {
|
2013-12-01 11:50:34 -06:00
|
|
|
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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut xs = [1i,2,0,3,4,0,0,5,6,0];
|
2014-09-14 22:27:36 -05:00
|
|
|
for slice in xs.split_mut(|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
|
|
|
}
|
|
|
|
|
2014-06-08 10:05:32 -05:00
|
|
|
#[test]
|
|
|
|
fn test_get_mut() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v = [0i,1,2];
|
2014-06-08 10:05:32 -05:00
|
|
|
assert_eq!(v.get_mut(3), None);
|
|
|
|
v.get_mut(1).map(|e| *e = 7);
|
|
|
|
assert_eq!(v[1], 7);
|
|
|
|
let mut x = 2;
|
|
|
|
assert_eq!(v.get_mut(2), Some(&mut x));
|
|
|
|
}
|
|
|
|
|
2013-11-30 15:28:42 -06:00
|
|
|
#[test]
|
|
|
|
fn test_mut_chunks() {
|
|
|
|
let mut v = [0u8, 1, 2, 3, 4, 5, 6];
|
2014-09-14 22:27:36 -05:00
|
|
|
for (i, chunk) in v.chunks_mut(3).enumerate() {
|
|
|
|
for x in chunk.iter_mut() {
|
2013-11-30 15:28:42 -06:00
|
|
|
*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-09-14 22:27:36 -05:00
|
|
|
for (i, chunk) in v.chunks_mut(3).rev().enumerate() {
|
|
|
|
for x in chunk.iter_mut() {
|
2013-11-30 18:54:28 -06:00
|
|
|
*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() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut v = [1i, 2, 3, 4];
|
2014-09-14 22:27:36 -05:00
|
|
|
let _it = v.chunks_mut(0);
|
2013-11-30 15:28:42 -06:00
|
|
|
}
|
2013-11-16 16:29:19 -06:00
|
|
|
|
|
|
|
#[test]
|
2014-01-26 10:24:34 -06:00
|
|
|
fn test_mut_last() {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut x = [1i, 2, 3, 4, 5];
|
2014-09-14 22:27:36 -05:00
|
|
|
let h = x.last_mut();
|
2014-01-26 10:24:34 -06:00
|
|
|
assert_eq!(*h.unwrap(), 5);
|
|
|
|
|
2014-11-17 02:39:01 -06:00
|
|
|
let y: &mut [int] = &mut [];
|
2014-09-14 22:27:36 -05:00
|
|
|
assert!(y.last_mut().is_none());
|
2013-11-16 16:29:19 -06:00
|
|
|
}
|
2014-10-10 04:18:42 -05:00
|
|
|
|
|
|
|
#[test]
|
2014-10-11 01:03:55 -05:00
|
|
|
fn test_to_vec() {
|
2014-10-10 04:18:42 -05:00
|
|
|
let xs = box [1u, 2, 3];
|
2014-10-11 01:03:55 -05:00
|
|
|
let ys = xs.to_vec();
|
2014-10-10 05:19:40 -05:00
|
|
|
assert_eq!(ys.as_slice(), [1u, 2, 3].as_slice());
|
2014-10-10 04:18:42 -05:00
|
|
|
}
|
2013-04-18 07:15:40 -05:00
|
|
|
}
|
2013-08-02 08:34:11 -05:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod bench {
|
2014-05-29 21:03:06 -05:00
|
|
|
use std::prelude::*;
|
|
|
|
use std::rand::{weak_rng, Rng};
|
|
|
|
use std::mem;
|
|
|
|
use std::ptr;
|
|
|
|
use test::Bencher;
|
|
|
|
|
|
|
|
use vec::Vec;
|
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.
|
2014-10-09 14:17:22 -05:00
|
|
|
if sum == 0 {panic!()}
|
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-21 16:58:52 -05:00
|
|
|
let mut v = Vec::from_elem(100, 0i);
|
2013-08-02 09:23:05 -05:00
|
|
|
|
2014-03-31 20:16:35 -05:00
|
|
|
b.iter(|| {
|
2014-04-21 16:58:52 -05:00
|
|
|
let mut i = 0i;
|
2014-09-14 22:27:36 -05:00
|
|
|
for x in v.iter_mut() {
|
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
|
|
|
|
2013-09-27 21:53:20 -05:00
|
|
|
#[bench]
|
2014-03-31 20:16:35 -05:00
|
|
|
fn concat(b: &mut Bencher) {
|
2014-04-21 16:58:52 -05:00
|
|
|
let xss: Vec<Vec<uint>> =
|
|
|
|
Vec::from_fn(100, |i| range(0u, 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-21 16:58:52 -05:00
|
|
|
let xss: Vec<Vec<uint>> =
|
|
|
|
Vec::from_fn(100, |i| range(0u, 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_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-11-06 11:24:47 -06:00
|
|
|
v[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
|
|
|
}
|
2014-09-14 22:27:36 -05:00
|
|
|
for x in v.iter_mut() {
|
2014-06-27 14:30:25 -05:00
|
|
|
*x = 0i;
|
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
|
|
|
});
|
|
|
|
}
|
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));
|
2014-04-21 16:58:52 -05:00
|
|
|
for _ in range(0u, 100) {
|
2013-12-18 20:23:37 -06:00
|
|
|
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));
|
2014-04-21 16:58:52 -05:00
|
|
|
for _ in range(0u, 100) {
|
2013-12-18 20:56:53 -06:00
|
|
|
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(|| {
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
let mut v = rng.gen_iter::<u64>().take(5).collect::<Vec<u64>>();
|
2014-03-27 07:00:46 -05:00
|
|
|
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(|| {
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
let mut v = rng.gen_iter::<u64>().take(100).collect::<Vec<u64>>();
|
2014-03-27 07:00:46 -05:00
|
|
|
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(|| {
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
let mut v = rng.gen_iter::<u64>().take(10000).collect::<Vec<u64>>();
|
2014-03-27 07:00:46 -05:00
|
|
|
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-09-09 04:32:58 -05:00
|
|
|
b.bytes = (v.len() * mem::size_of_val(&v[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(|| {
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
let mut v = rng.gen_iter::<BigSortable>().take(5)
|
|
|
|
.collect::<Vec<BigSortable>>();
|
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(|| {
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
let mut v = rng.gen_iter::<BigSortable>().take(100)
|
|
|
|
.collect::<Vec<BigSortable>>();
|
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(|| {
|
std: Recreate a `rand` module
This commit shuffles around some of the `rand` code, along with some
reorganization. The new state of the world is as follows:
* The librand crate now only depends on libcore. This interface is experimental.
* The standard library has a new module, `std::rand`. This interface will
eventually become stable.
Unfortunately, this entailed more of a breaking change than just shuffling some
names around. The following breaking changes were made to the rand library:
* Rng::gen_vec() was removed. This has been replaced with Rng::gen_iter() which
will return an infinite stream of random values. Previous behavior can be
regained with `rng.gen_iter().take(n).collect()`
* Rng::gen_ascii_str() was removed. This has been replaced with
Rng::gen_ascii_chars() which will return an infinite stream of random ascii
characters. Similarly to gen_iter(), previous behavior can be emulated with
`rng.gen_ascii_chars().take(n).collect()`
* {IsaacRng, Isaac64Rng, XorShiftRng}::new() have all been removed. These all
relied on being able to use an OSRng for seeding, but this is no longer
available in librand (where these types are defined). To retain the same
functionality, these types now implement the `Rand` trait so they can be
generated with a random seed from another random number generator. This allows
the stdlib to use an OSRng to create seeded instances of these RNGs.
* Rand implementations for `Box<T>` and `@T` were removed. These seemed to be
pretty rare in the codebase, and it allows for librand to not depend on
liballoc. Additionally, other pointer types like Rc<T> and Arc<T> were not
supported. If this is undesirable, librand can depend on liballoc and regain
these implementations.
* The WeightedChoice structure is no longer built with a `Vec<Weighted<T>>`,
but rather a `&mut [Weighted<T>]`. This means that the WeightedChoice
structure now has a lifetime associated with it.
* The `sample` method on `Rng` has been moved to a top-level function in the
`rand` module due to its dependence on `Vec`.
cc #13851
[breaking-change]
2014-05-25 03:39:37 -05:00
|
|
|
let mut v = rng.gen_iter::<BigSortable>().take(10000)
|
|
|
|
.collect::<Vec<BigSortable>>();
|
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-09-09 04:32:58 -05:00
|
|
|
b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
|
2014-02-04 11:56:13 -06:00
|
|
|
}
|
2013-08-02 08:34:11 -05:00
|
|
|
}
|