2014-01-21 09:35:11 -05:00
|
|
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// 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-04-02 16:54:22 -07:00
|
|
|
|
2014-08-30 17:11:22 -04:00
|
|
|
//! A growable list type, written `Vec<T>` but pronounced 'vector.'
|
|
|
|
//!
|
|
|
|
//! Vectors have `O(1)` indexing, push (to the end) and pop (from the end).
|
2014-01-21 09:35:11 -05:00
|
|
|
|
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 18:50:12 -07:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2014-09-15 15:37:01 -04:00
|
|
|
use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
|
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 18:50:12 -07:00
|
|
|
use core::cmp::max;
|
|
|
|
use core::default::Default;
|
|
|
|
use core::fmt;
|
2014-09-19 01:38:50 +02:00
|
|
|
use core::kinds::marker::InvariantType;
|
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 18:50:12 -07:00
|
|
|
use core::mem;
|
|
|
|
use core::num;
|
2014-09-15 20:48:58 +12:00
|
|
|
use core::ops;
|
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 18:50:12 -07:00
|
|
|
use core::ptr;
|
2014-08-18 08:29:44 -07:00
|
|
|
use core::raw::Slice as RawSlice;
|
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 18:50:12 -07:00
|
|
|
use core::uint;
|
|
|
|
|
2014-08-12 20:31:30 -07:00
|
|
|
use {Mutable, MutableSeq};
|
2014-08-06 18:58:43 -07:00
|
|
|
use slice::{MutableOrdSlice, MutableSliceAllocating, CloneableVector};
|
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 18:50:12 -07:00
|
|
|
use slice::{Items, MutItems};
|
2014-03-16 16:04:29 -07:00
|
|
|
|
2014-03-19 23:01:08 -07:00
|
|
|
/// An owned, growable vector.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
2014-03-19 23:01:08 -07:00
|
|
|
/// # Examples
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-19 23:01:08 -07:00
|
|
|
/// let mut vec = Vec::new();
|
2014-04-21 17:58:52 -04:00
|
|
|
/// vec.push(1i);
|
|
|
|
/// vec.push(2i);
|
2014-03-19 23:01:08 -07:00
|
|
|
///
|
|
|
|
/// assert_eq!(vec.len(), 2);
|
2014-07-15 11:37:25 +12:00
|
|
|
/// assert_eq!(vec[0], 1);
|
2014-03-19 23:01:08 -07:00
|
|
|
///
|
|
|
|
/// assert_eq!(vec.pop(), Some(2));
|
|
|
|
/// assert_eq!(vec.len(), 1);
|
2014-07-22 11:07:49 +02:00
|
|
|
///
|
|
|
|
/// *vec.get_mut(0) = 7i;
|
|
|
|
/// assert_eq!(vec[0], 7);
|
|
|
|
///
|
|
|
|
/// vec.push_all([1, 2, 3]);
|
|
|
|
///
|
|
|
|
/// for x in vec.iter() {
|
|
|
|
/// println!("{}", x);
|
|
|
|
/// }
|
|
|
|
/// assert_eq!(vec, vec![7i, 1, 2, 3]);
|
2014-03-19 23:01:08 -07:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// The `vec!` macro is provided to make initialization more convenient:
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-21 20:33:20 +12:00
|
|
|
/// let mut vec = vec![1i, 2i, 3i];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.push(4);
|
2014-07-21 20:33:20 +12:00
|
|
|
/// assert_eq!(vec, vec![1, 2, 3, 4]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-07-21 20:33:20 +12:00
|
|
|
///
|
2014-07-22 11:07:49 +02:00
|
|
|
/// Use a `Vec` as an efficient stack:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let mut stack = Vec::new();
|
|
|
|
///
|
|
|
|
/// stack.push(1i);
|
|
|
|
/// stack.push(2i);
|
|
|
|
/// stack.push(3i);
|
|
|
|
///
|
|
|
|
/// loop {
|
|
|
|
/// let top = match stack.pop() {
|
|
|
|
/// None => break, // empty
|
|
|
|
/// Some(x) => x,
|
|
|
|
/// };
|
|
|
|
/// // Prints 3, 2, 1
|
|
|
|
/// println!("{}", top);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2014-07-21 20:33:20 +12:00
|
|
|
/// # Capacity and reallocation
|
|
|
|
///
|
|
|
|
/// The capacity of a vector is the amount of space allocated for any future
|
|
|
|
/// elements that will be added onto the vector. This is not to be confused
|
|
|
|
/// with the *length* of a vector, which specifies the number of actual
|
|
|
|
/// elements within the vector. If a vector's length exceeds its capacity,
|
|
|
|
/// its capacity will automatically be increased, but its elements will
|
|
|
|
/// have to be reallocated.
|
|
|
|
///
|
|
|
|
/// For example, a vector with capacity 10 and length 0 would be an empty
|
|
|
|
/// vector with space for 10 more elements. Pushing 10 or fewer elements onto
|
|
|
|
/// the vector will not change its capacity or cause reallocation to occur.
|
|
|
|
/// However, if the vector's length is increased to 11, it will have to
|
|
|
|
/// reallocate, which can be slow. For this reason, it is recommended
|
|
|
|
/// to use `Vec::with_capacity` whenever possible to specify how big the vector
|
|
|
|
/// is expected to get.
|
2014-03-12 22:01:33 +02:00
|
|
|
#[unsafe_no_drop_flag]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub struct Vec<T> {
|
2014-03-27 15:09:47 -07:00
|
|
|
len: uint,
|
|
|
|
cap: uint,
|
|
|
|
ptr: *mut T
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Vec<T> {
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Constructs a new, empty `Vec`.
|
|
|
|
///
|
|
|
|
/// The vector will not allocate until elements are pushed onto it.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-16 16:04:29 -07:00
|
|
|
/// let mut vec: Vec<int> = Vec::new();
|
|
|
|
/// ```
|
2014-01-21 09:35:11 -05:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn new() -> Vec<T> {
|
2014-07-04 15:29:47 -07:00
|
|
|
// We want ptr to never be NULL so instead we set it to some arbitrary
|
|
|
|
// non-null value which is fine since we never call deallocate on the ptr
|
|
|
|
// if cap is 0. The reason for this is because the pointer of a slice
|
|
|
|
// being NULL would break the null pointer optimization for enums.
|
2014-09-15 15:37:01 -04:00
|
|
|
Vec { len: 0, cap: 0, ptr: EMPTY as *mut T }
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Constructs a new, empty `Vec` with the specified capacity.
|
|
|
|
///
|
|
|
|
/// The vector will be able to hold exactly `capacity` elements without
|
|
|
|
/// reallocating. If `capacity` is 0, the vector will not allocate.
|
|
|
|
///
|
2014-07-21 20:33:20 +12:00
|
|
|
/// It is important to note that this function does not specify the
|
|
|
|
/// *length* of the returned vector, but only the *capacity*. (For an
|
|
|
|
/// explanation of the difference between length and capacity, see
|
|
|
|
/// the main `Vec` docs above, 'Capacity and reallocation'.) To create
|
|
|
|
/// a vector of a given length, use `Vec::from_elem` or `Vec::from_fn`.
|
|
|
|
///
|
2014-03-16 16:04:29 -07:00
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-21 20:33:20 +12:00
|
|
|
/// let mut vec: Vec<int> = Vec::with_capacity(10);
|
|
|
|
///
|
|
|
|
/// // The vector contains no items, even though it has capacity for more
|
|
|
|
/// assert_eq!(vec.len(), 0);
|
|
|
|
///
|
|
|
|
/// // These are all done without reallocating...
|
2014-07-21 10:18:17 -07:00
|
|
|
/// for i in range(0i, 10) {
|
2014-07-21 20:33:20 +12:00
|
|
|
/// vec.push(i);
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // ...but this may make the vector reallocate
|
|
|
|
/// vec.push(11);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn with_capacity(capacity: uint) -> Vec<T> {
|
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 10:34:51 -07:00
|
|
|
if mem::size_of::<T>() == 0 {
|
2014-09-15 15:37:01 -04:00
|
|
|
Vec { len: 0, cap: uint::MAX, ptr: EMPTY as *mut T }
|
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 10:34:51 -07:00
|
|
|
} else if capacity == 0 {
|
2014-01-21 09:35:11 -05:00
|
|
|
Vec::new()
|
|
|
|
} else {
|
2014-06-06 16:33:44 -07:00
|
|
|
let size = capacity.checked_mul(&mem::size_of::<T>())
|
|
|
|
.expect("capacity overflow");
|
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 10:34:51 -07:00
|
|
|
let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
|
2014-01-21 09:35:11 -05:00
|
|
|
Vec { len: 0, cap: capacity, ptr: ptr as *mut T }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Creates and initializes a `Vec`.
|
|
|
|
///
|
|
|
|
/// Creates a `Vec` of size `length` and initializes the elements to the
|
|
|
|
/// value returned by the closure `op`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-16 16:04:29 -07:00
|
|
|
/// let vec = Vec::from_fn(3, |idx| idx * 2);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![0, 2, 4]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "the naming is uncertain as well as this migrating to unboxed \
|
|
|
|
closures in the future"]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
|
|
|
|
unsafe {
|
|
|
|
let mut xs = Vec::with_capacity(length);
|
|
|
|
while xs.len < length {
|
2014-06-13 20:48:09 -07:00
|
|
|
let len = xs.len;
|
2014-09-14 20:27:36 -07:00
|
|
|
ptr::write(xs.as_mut_slice().unsafe_mut(len), op(len));
|
2014-01-21 09:35:11 -05:00
|
|
|
xs.len += 1;
|
|
|
|
}
|
|
|
|
xs
|
|
|
|
}
|
|
|
|
}
|
2014-03-06 23:33:46 +01:00
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Creates a `Vec<T>` directly from the raw constituents.
|
2014-03-20 01:52:37 +11:00
|
|
|
///
|
|
|
|
/// This is highly unsafe:
|
|
|
|
///
|
|
|
|
/// - if `ptr` is null, then `length` and `capacity` should be 0
|
|
|
|
/// - `ptr` must point to an allocation of size `capacity`
|
|
|
|
/// - there must be `length` valid instances of type `T` at the
|
|
|
|
/// beginning of that allocation
|
|
|
|
/// - `ptr` must be allocated by the default `Vec` allocator
|
2014-07-22 13:40:38 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::ptr;
|
|
|
|
/// use std::mem;
|
|
|
|
///
|
|
|
|
/// fn main() {
|
|
|
|
/// let mut v = vec![1i, 2, 3];
|
|
|
|
///
|
|
|
|
/// // Pull out the various important pieces of information about `v`
|
|
|
|
/// let p = v.as_mut_ptr();
|
|
|
|
/// let len = v.len();
|
|
|
|
/// let cap = v.capacity();
|
|
|
|
///
|
|
|
|
/// unsafe {
|
|
|
|
/// // Cast `v` into the void: no destructor run, so we are in
|
|
|
|
/// // complete control of the allocation to which `p` points.
|
|
|
|
/// mem::forget(v);
|
|
|
|
///
|
|
|
|
/// // Overwrite memory with 4, 5, 6
|
|
|
|
/// for i in range(0, len as int) {
|
|
|
|
/// ptr::write(p.offset(i), 4 + i);
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // Put everything back together into a Vec
|
|
|
|
/// let rebuilt = Vec::from_raw_parts(len, cap, p);
|
|
|
|
/// assert_eq!(rebuilt, vec![4i, 5i, 6i]);
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental]
|
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 10:34:51 -07:00
|
|
|
pub unsafe fn from_raw_parts(length: uint, capacity: uint,
|
|
|
|
ptr: *mut T) -> Vec<T> {
|
2014-03-20 01:52:37 +11:00
|
|
|
Vec { len: length, cap: capacity, ptr: ptr }
|
|
|
|
}
|
|
|
|
|
2014-04-21 00:49:39 -04:00
|
|
|
/// Consumes the `Vec`, partitioning it based on a predicate.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
|
|
|
|
/// satisfy `f` and all elements of `B` do not. The order of elements is
|
|
|
|
/// preserved.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2i, 3i, 4i];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// let (even, odd) = vec.partition(|&n| n % 2 == 0);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(even, vec![2, 4]);
|
|
|
|
/// assert_eq!(odd, vec![1, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-03-06 23:33:46 +01:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental]
|
2014-03-06 23:33:46 +01:00
|
|
|
pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
|
|
|
|
let mut lefts = Vec::new();
|
|
|
|
let mut rights = Vec::new();
|
|
|
|
|
2014-09-14 20:27:36 -07:00
|
|
|
for elt in self.into_iter() {
|
2014-03-06 23:33:46 +01:00
|
|
|
if f(&elt) {
|
|
|
|
lefts.push(elt);
|
|
|
|
} else {
|
|
|
|
rights.push(elt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(lefts, rights)
|
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Clone> Vec<T> {
|
2014-09-17 12:56:31 -07:00
|
|
|
/// Deprecated, call `extend` instead.
|
2014-03-30 23:53:26 -04:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[deprecated = "this function has been deprecated in favor of extend()"]
|
2014-03-30 23:53:26 -04:00
|
|
|
pub fn append(mut self, second: &[T]) -> Vec<T> {
|
|
|
|
self.push_all(second);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2014-09-17 12:56:31 -07:00
|
|
|
/// Deprecated, call `to_vec()` instead
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[deprecated = "this function has been deprecated in favor of to_vec()"]
|
2014-09-17 12:56:31 -07:00
|
|
|
pub fn from_slice(values: &[T]) -> Vec<T> { values.to_vec() }
|
2014-03-04 10:39:49 -08:00
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Constructs a `Vec` with copies of a value.
|
|
|
|
///
|
|
|
|
/// Creates a `Vec` with `length` copies of `value`.
|
|
|
|
///
|
|
|
|
/// # Example
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-16 16:04:29 -07:00
|
|
|
/// let vec = Vec::from_elem(3, "hi");
|
|
|
|
/// println!("{}", vec); // prints [hi, hi, hi]
|
|
|
|
/// ```
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "this functionality may become more generic over all collections"]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn from_elem(length: uint, value: T) -> Vec<T> {
|
|
|
|
unsafe {
|
|
|
|
let mut xs = Vec::with_capacity(length);
|
|
|
|
while xs.len < length {
|
2014-06-13 20:48:09 -07:00
|
|
|
let len = xs.len;
|
2014-09-14 20:27:36 -07:00
|
|
|
ptr::write(xs.as_mut_slice().unsafe_mut(len),
|
2014-05-29 19:03:06 -07:00
|
|
|
value.clone());
|
2014-01-21 09:35:11 -05:00
|
|
|
xs.len += 1;
|
|
|
|
}
|
|
|
|
xs
|
|
|
|
}
|
|
|
|
}
|
2014-02-18 21:36:51 -08:00
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Appends all elements in a slice to the `Vec`.
|
|
|
|
///
|
|
|
|
/// Iterates over the slice `other`, clones each element, and then appends
|
|
|
|
/// it to this `Vec`. The `other` vector is traversed in-order.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i];
|
2014-04-21 17:58:52 -04:00
|
|
|
/// vec.push_all([2i, 3, 4]);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1, 2, 3, 4]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental]
|
2014-02-18 21:36:51 -08:00
|
|
|
pub fn push_all(&mut self, other: &[T]) {
|
2014-07-07 09:11:03 -07:00
|
|
|
self.reserve_additional(other.len());
|
|
|
|
|
2014-07-07 09:45:00 -07:00
|
|
|
for i in range(0, other.len()) {
|
|
|
|
let len = self.len();
|
|
|
|
|
|
|
|
// Unsafe code so this can be optimised to a memcpy (or something similarly
|
|
|
|
// fast) when T is Copy. LLVM is easily confused, so any extra operations
|
|
|
|
// during the loop can prevent this optimisation.
|
|
|
|
unsafe {
|
|
|
|
ptr::write(
|
2014-09-14 20:27:36 -07:00
|
|
|
self.as_mut_slice().unsafe_mut(len),
|
2014-08-06 20:08:16 -07:00
|
|
|
other.unsafe_get(i).clone());
|
2014-07-07 09:45:00 -07:00
|
|
|
self.set_len(len + 1);
|
|
|
|
}
|
2014-07-05 23:11:18 -07:00
|
|
|
}
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
2014-02-28 12:54:01 -08:00
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Grows the `Vec` in-place.
|
|
|
|
///
|
|
|
|
/// Adds `n` copies of `value` to the `Vec`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec!["hello"];
|
2014-08-29 13:20:58 -07:00
|
|
|
/// vec.grow(2, "world");
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec!["hello", "world", "world"]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
|
|
|
pub fn grow(&mut self, n: uint, value: T) {
|
2014-07-03 08:40:08 -07:00
|
|
|
self.reserve_additional(n);
|
2014-02-28 12:54:01 -08:00
|
|
|
let mut i: uint = 0u;
|
|
|
|
|
|
|
|
while i < n {
|
2014-08-29 13:20:58 -07:00
|
|
|
self.push(value.clone());
|
2014-02-28 12:54:01 -08:00
|
|
|
i += 1u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Sets the value of a vector element at a given index, growing the vector
|
|
|
|
/// as needed.
|
|
|
|
///
|
|
|
|
/// Sets the element at position `index` to `value`. If `index` is past the
|
|
|
|
/// end of the vector, expands the vector by replicating `initval` to fill
|
|
|
|
/// the intervening space.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
/// # #![allow(deprecated)]
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec!["a", "b", "c"];
|
2014-05-01 01:32:13 -04:00
|
|
|
/// vec.grow_set(1, &("fill"), "d");
|
|
|
|
/// vec.grow_set(4, &("fill"), "e");
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec!["a", "d", "c", "fill", "e"]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[deprecated = "call .grow() and .push() manually instead"]
|
2014-03-16 16:04:29 -07:00
|
|
|
pub fn grow_set(&mut self, index: uint, initval: &T, value: T) {
|
2014-02-28 12:54:01 -08:00
|
|
|
let l = self.len();
|
|
|
|
if index >= l {
|
2014-08-29 13:20:58 -07:00
|
|
|
self.grow(index - l + 1u, initval.clone());
|
2014-02-28 12:54:01 -08:00
|
|
|
}
|
2014-03-16 16:04:29 -07:00
|
|
|
*self.get_mut(index) = value;
|
|
|
|
}
|
|
|
|
|
2014-04-21 00:49:39 -04:00
|
|
|
/// Partitions a vector based on a predicate.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// Clones the elements of the vector, partitioning them into two `Vec`s
|
2014-08-04 22:48:39 +12:00
|
|
|
/// `(a, b)`, where all elements of `a` satisfy `f` and all elements of `b`
|
2014-03-16 16:04:29 -07:00
|
|
|
/// do not. The order of elements is preserved.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3, 4];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// let (even, odd) = vec.partitioned(|&n| n % 2 == 0);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(even, vec![2i, 4]);
|
|
|
|
/// assert_eq!(odd, vec![1i, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental]
|
2014-02-27 23:49:25 -08:00
|
|
|
pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
|
|
|
|
let mut lefts = Vec::new();
|
|
|
|
let mut rights = Vec::new();
|
|
|
|
|
|
|
|
for elt in self.iter() {
|
|
|
|
if f(elt) {
|
|
|
|
lefts.push(elt.clone());
|
|
|
|
} else {
|
|
|
|
rights.push(elt.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(lefts, rights)
|
|
|
|
}
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-06-23 16:34:29 -07:00
|
|
|
#[unstable]
|
2014-02-18 21:36:51 -08:00
|
|
|
impl<T:Clone> Clone for Vec<T> {
|
2014-09-17 12:56:31 -07:00
|
|
|
fn clone(&self) -> Vec<T> { self.as_slice().to_vec() }
|
2014-04-03 22:28:45 +11:00
|
|
|
|
|
|
|
fn clone_from(&mut self, other: &Vec<T>) {
|
|
|
|
// drop anything in self that will not be overwritten
|
|
|
|
if self.len() > other.len() {
|
|
|
|
self.truncate(other.len())
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
2014-04-03 22:28:45 +11:00
|
|
|
|
|
|
|
// reuse the contained values' allocations/resources.
|
2014-09-14 20:27:36 -07:00
|
|
|
for (place, thing) in self.iter_mut().zip(other.iter()) {
|
2014-04-03 22:28:45 +11:00
|
|
|
place.clone_from(thing)
|
|
|
|
}
|
|
|
|
|
|
|
|
// self.len <= other.len due to the truncate above, so the
|
|
|
|
// slice here is always in-bounds.
|
2014-09-24 23:41:09 +12:00
|
|
|
let slice = other[self.len()..];
|
2014-07-07 09:11:03 -07:00
|
|
|
self.push_all(slice);
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental = "waiting on Index stability"]
|
2014-07-14 11:03:23 +12:00
|
|
|
impl<T> Index<uint,T> for Vec<T> {
|
|
|
|
#[inline]
|
2014-08-11 16:47:46 -07:00
|
|
|
#[allow(deprecated)] // allow use of get
|
2014-07-14 11:03:23 +12:00
|
|
|
fn index<'a>(&'a self, index: &uint) -> &'a T {
|
|
|
|
self.get(*index)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME(#12825) Indexing will always try IndexMut first and that causes issues.
|
|
|
|
/*impl<T> IndexMut<uint,T> for Vec<T> {
|
|
|
|
#[inline]
|
|
|
|
fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
|
|
|
|
self.get_mut(*index)
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
2014-10-05 11:59:10 +13:00
|
|
|
#[cfg(stage0)]
|
2014-09-15 20:48:58 +12:00
|
|
|
impl<T> ops::Slice<uint, [T]> for Vec<T> {
|
|
|
|
#[inline]
|
|
|
|
fn as_slice_<'a>(&'a self) -> &'a [T] {
|
|
|
|
self.as_slice()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_from_<'a>(&'a self, start: &uint) -> &'a [T] {
|
|
|
|
self.as_slice().slice_from_(start)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_to_<'a>(&'a self, end: &uint) -> &'a [T] {
|
|
|
|
self.as_slice().slice_to_(end)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn slice_<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
|
|
|
|
self.as_slice().slice_(start, end)
|
|
|
|
}
|
|
|
|
}
|
2014-10-05 11:59:10 +13:00
|
|
|
#[cfg(not(stage0))]
|
|
|
|
impl<T> ops::Slice<uint, [T]> for Vec<T> {
|
|
|
|
#[inline]
|
|
|
|
fn as_slice_<'a>(&'a self) -> &'a [T] {
|
|
|
|
self.as_slice()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
|
|
|
|
self.as_slice().slice_from_or_fail(start)
|
|
|
|
}
|
2014-09-15 20:48:58 +12:00
|
|
|
|
2014-10-05 11:59:10 +13:00
|
|
|
#[inline]
|
|
|
|
fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
|
|
|
|
self.as_slice().slice_to_or_fail(end)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
|
|
|
|
self.as_slice().slice_or_fail(start, end)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(stage0)]
|
2014-09-15 20:48:58 +12:00
|
|
|
impl<T> ops::SliceMut<uint, [T]> for Vec<T> {
|
|
|
|
#[inline]
|
|
|
|
fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_from_mut_<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice().slice_from_mut_(start)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_to_mut_<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice().slice_to_mut_(end)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn slice_mut_<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice().slice_mut_(start, end)
|
|
|
|
}
|
|
|
|
}
|
2014-10-05 11:59:10 +13:00
|
|
|
#[cfg(not(stage0))]
|
|
|
|
impl<T> ops::SliceMut<uint, [T]> for Vec<T> {
|
|
|
|
#[inline]
|
|
|
|
fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice().slice_from_or_fail_mut(start)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice().slice_to_or_fail_mut(end)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
|
|
|
|
self.as_mut_slice().slice_or_fail_mut(start, end)
|
|
|
|
}
|
|
|
|
}
|
2014-08-29 13:20:58 -07:00
|
|
|
|
|
|
|
#[experimental = "waiting on FromIterator stability"]
|
2014-02-18 21:36:51 -08:00
|
|
|
impl<T> FromIterator<T> for Vec<T> {
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-03-30 21:45:55 -07:00
|
|
|
fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
|
2014-02-18 21:36:51 -08:00
|
|
|
let (lower, _) = iterator.size_hint();
|
|
|
|
let mut vector = Vec::with_capacity(lower);
|
2014-03-20 14:12:56 +01:00
|
|
|
for element in iterator {
|
2014-02-18 21:36:51 -08:00
|
|
|
vector.push(element)
|
|
|
|
}
|
|
|
|
vector
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental = "waiting on Extendable stability"]
|
2014-03-04 07:46:24 +11:00
|
|
|
impl<T> Extendable<T> for Vec<T> {
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-03-20 14:12:56 +01:00
|
|
|
fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
|
2014-03-04 07:46:24 +11:00
|
|
|
let (lower, _) = iterator.size_hint();
|
|
|
|
self.reserve_additional(lower);
|
2014-03-20 14:12:56 +01:00
|
|
|
for element in iterator {
|
2014-03-04 07:46:24 +11:00
|
|
|
self.push(element)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "waiting on PartialEq stability"]
|
2014-05-29 17:45:07 -07:00
|
|
|
impl<T: PartialEq> PartialEq for Vec<T> {
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &Vec<T>) -> bool {
|
|
|
|
self.as_slice() == other.as_slice()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "waiting on PartialOrd stability"]
|
2014-05-29 17:45:07 -07:00
|
|
|
impl<T: PartialOrd> PartialOrd for Vec<T> {
|
2014-02-24 08:11:00 -05:00
|
|
|
#[inline]
|
2014-06-17 23:25:51 -07:00
|
|
|
fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
|
|
|
|
self.as_slice().partial_cmp(&other.as_slice())
|
2014-02-24 08:11:00 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "waiting on Eq stability"]
|
2014-05-31 10:43:52 -07:00
|
|
|
impl<T: Eq> Eq for Vec<T> {}
|
2014-02-18 21:36:51 -08:00
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental]
|
2014-10-05 12:22:42 +13:00
|
|
|
impl<T: PartialEq, V: AsSlice<T>> Equiv<V> for Vec<T> {
|
2014-06-06 10:27:49 -07:00
|
|
|
#[inline]
|
|
|
|
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "waiting on Ord stability"]
|
2014-05-31 10:43:52 -07:00
|
|
|
impl<T: Ord> Ord for Vec<T> {
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
fn cmp(&self, other: &Vec<T>) -> Ordering {
|
|
|
|
self.as_slice().cmp(&other.as_slice())
|
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental = "waiting on Collection stability"]
|
2014-05-19 11:32:09 -07:00
|
|
|
impl<T> Collection for Vec<T> {
|
2014-01-21 09:35:11 -05:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
fn len(&self) -> uint {
|
|
|
|
self.len
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-06 10:27:49 -07:00
|
|
|
impl<T: Clone> CloneableVector<T> for Vec<T> {
|
2014-08-29 13:20:58 -07:00
|
|
|
#[deprecated = "call .clone() instead"]
|
2014-07-16 22:37:28 +02:00
|
|
|
fn to_vec(&self) -> Vec<T> { self.clone() }
|
2014-08-29 13:20:58 -07:00
|
|
|
#[deprecated = "move the vector instead"]
|
2014-07-16 22:37:28 +02:00
|
|
|
fn into_vec(self) -> Vec<T> { self }
|
2014-06-06 10:27:49 -07:00
|
|
|
}
|
|
|
|
|
2014-05-06 17:01:16 -04:00
|
|
|
// FIXME: #13996: need a way to mark the return value as `noalias`
|
|
|
|
#[inline(never)]
|
2014-05-09 23:56:28 -04:00
|
|
|
unsafe fn alloc_or_realloc<T>(ptr: *mut T, size: uint, old_size: uint) -> *mut T {
|
2014-05-06 17:01:16 -04:00
|
|
|
if old_size == 0 {
|
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 10:34:51 -07:00
|
|
|
allocate(size, mem::min_align_of::<T>()) as *mut T
|
2014-05-06 17:01:16 -04:00
|
|
|
} else {
|
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 10:34:51 -07:00
|
|
|
reallocate(ptr as *mut u8, size,
|
|
|
|
mem::min_align_of::<T>(), old_size) as *mut T
|
2014-05-06 17:01:16 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-10 00:35:56 -04:00
|
|
|
#[inline]
|
|
|
|
unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
|
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 10:34:51 -07:00
|
|
|
if mem::size_of::<T>() != 0 {
|
|
|
|
deallocate(ptr as *mut u8,
|
|
|
|
len * mem::size_of::<T>(),
|
|
|
|
mem::min_align_of::<T>())
|
2014-05-10 00:35:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-21 09:35:11 -05:00
|
|
|
impl<T> Vec<T> {
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns the number of elements the vector can hold without
|
|
|
|
/// reallocating.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-16 16:04:29 -07:00
|
|
|
/// let vec: Vec<int> = Vec::with_capacity(10);
|
|
|
|
/// assert_eq!(vec.capacity(), 10);
|
|
|
|
/// ```
|
2014-01-21 09:35:11 -05:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn capacity(&self) -> uint {
|
|
|
|
self.cap
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Reserves capacity for at least `n` additional elements in the given
|
|
|
|
/// vector.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails if the new capacity overflows `uint`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec: Vec<int> = vec![1i];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.reserve_additional(10);
|
|
|
|
/// assert!(vec.capacity() >= 11);
|
|
|
|
/// ```
|
2014-03-04 07:46:24 +11:00
|
|
|
pub fn reserve_additional(&mut self, extra: uint) {
|
|
|
|
if self.cap - self.len < extra {
|
|
|
|
match self.len.checked_add(&extra) {
|
|
|
|
None => fail!("Vec::reserve_additional: `uint` overflow"),
|
|
|
|
Some(new_cap) => self.reserve(new_cap)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Reserves capacity for at least `n` elements in the given vector.
|
|
|
|
///
|
|
|
|
/// This function will over-allocate in order to amortize the allocation
|
|
|
|
/// costs in scenarios where the caller may need to repeatedly reserve
|
|
|
|
/// additional space.
|
|
|
|
///
|
|
|
|
/// If the capacity for `self` is already equal to or greater than the
|
|
|
|
/// requested capacity, then no action is taken.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.reserve(10);
|
|
|
|
/// assert!(vec.capacity() >= 10);
|
|
|
|
/// ```
|
2014-02-23 10:59:23 +11:00
|
|
|
pub fn reserve(&mut self, capacity: uint) {
|
2014-07-03 08:45:28 -07:00
|
|
|
if capacity > self.cap {
|
2014-02-23 10:59:23 +11:00
|
|
|
self.reserve_exact(num::next_power_of_two(capacity))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Reserves capacity for exactly `capacity` elements in the given vector.
|
|
|
|
///
|
|
|
|
/// If the capacity for `self` is already equal to or greater than the
|
|
|
|
/// requested capacity, then no action is taken.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-16 16:04:29 -07:00
|
|
|
/// let mut vec: Vec<int> = Vec::with_capacity(10);
|
|
|
|
/// vec.reserve_exact(11);
|
|
|
|
/// assert_eq!(vec.capacity(), 11);
|
|
|
|
/// ```
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn reserve_exact(&mut self, capacity: uint) {
|
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 10:34:51 -07:00
|
|
|
if mem::size_of::<T>() == 0 { return }
|
|
|
|
|
2014-04-01 20:16:59 +00:00
|
|
|
if capacity > self.cap {
|
2014-06-06 16:33:44 -07:00
|
|
|
let size = capacity.checked_mul(&mem::size_of::<T>())
|
|
|
|
.expect("capacity overflow");
|
2014-01-21 09:35:11 -05:00
|
|
|
unsafe {
|
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 10:34:51 -07:00
|
|
|
self.ptr = alloc_or_realloc(self.ptr, size,
|
|
|
|
self.cap * mem::size_of::<T>());
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
2014-05-06 17:01:16 -04:00
|
|
|
self.cap = capacity;
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Shrinks the capacity of the vector as much as possible.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.shrink_to_fit();
|
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn shrink_to_fit(&mut self) {
|
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 10:34:51 -07:00
|
|
|
if mem::size_of::<T>() == 0 { return }
|
|
|
|
|
2014-01-21 09:35:11 -05:00
|
|
|
if self.len == 0 {
|
2014-05-06 17:01:16 -04:00
|
|
|
if self.cap != 0 {
|
|
|
|
unsafe {
|
2014-05-10 00:35:56 -04:00
|
|
|
dealloc(self.ptr, self.cap)
|
2014-05-06 17:01:16 -04:00
|
|
|
}
|
|
|
|
self.cap = 0;
|
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
} else {
|
|
|
|
unsafe {
|
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 10:34:51 -07:00
|
|
|
// Overflow check is unnecessary as the vector is already at
|
|
|
|
// least this large.
|
|
|
|
self.ptr = reallocate(self.ptr as *mut u8,
|
|
|
|
self.len * mem::size_of::<T>(),
|
|
|
|
mem::min_align_of::<T>(),
|
|
|
|
self.cap * mem::size_of::<T>()) as *mut T;
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
self.cap = self.len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-17 12:56:31 -07:00
|
|
|
/// Deprecated, call `push` instead
|
2014-03-30 23:53:26 -04:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[deprecated = "call .push() instead"]
|
2014-03-30 23:53:26 -04:00
|
|
|
pub fn append_one(mut self, x: T) -> Vec<T> {
|
|
|
|
self.push(x);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Shorten a vector, dropping excess elements.
|
|
|
|
///
|
|
|
|
/// If `len` is greater than the vector's current length, this has no
|
|
|
|
/// effect.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3, 4];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.truncate(2);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1, 2]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-09-17 12:56:31 -07:00
|
|
|
#[unstable = "waiting on failure semantics"]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn truncate(&mut self, len: uint) {
|
|
|
|
unsafe {
|
|
|
|
// drop any extra elements
|
2014-05-14 14:57:27 -07:00
|
|
|
while len < self.len {
|
|
|
|
// decrement len before the read(), so a failure on Drop doesn't
|
|
|
|
// re-drop the just-failed value.
|
|
|
|
self.len -= 1;
|
2014-08-06 20:08:16 -07:00
|
|
|
ptr::read(self.as_slice().unsafe_get(self.len));
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Returns a mutable slice of the elements of `self`.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-16 16:04:29 -07:00
|
|
|
/// fn foo(slice: &mut [int]) {}
|
|
|
|
///
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// foo(vec.as_mut_slice());
|
|
|
|
/// ```
|
2014-01-21 09:35:11 -05:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
|
2014-04-17 15:28:14 -07:00
|
|
|
unsafe {
|
2014-08-06 20:03:55 -07:00
|
|
|
mem::transmute(RawSlice {
|
2014-06-25 12:47:34 -07:00
|
|
|
data: self.as_mut_ptr() as *const T,
|
|
|
|
len: self.len,
|
|
|
|
})
|
2014-04-17 15:28:14 -07:00
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
|
2014-09-14 15:57:55 -07:00
|
|
|
/// Deprecated: use `into_iter`.
|
|
|
|
#[deprecated = "use into_iter"]
|
|
|
|
pub fn move_iter(self) -> MoveItems<T> {
|
|
|
|
self.into_iter()
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Creates a consuming iterator, that is, one that moves each
|
|
|
|
/// value out of the vector (from start to end). The vector cannot
|
|
|
|
/// be used after calling this.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let v = vec!["a".to_string(), "b".to_string()];
|
2014-09-14 20:27:36 -07:00
|
|
|
/// for s in v.into_iter() {
|
2014-05-22 16:57:53 -07:00
|
|
|
/// // s has type String, not &String
|
2014-03-16 16:04:29 -07:00
|
|
|
/// println!("{}", s);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-01-21 09:35:11 -05:00
|
|
|
#[inline]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn into_iter(self) -> MoveItems<T> {
|
2014-01-21 09:35:11 -05:00
|
|
|
unsafe {
|
2014-05-10 00:35:56 -04:00
|
|
|
let ptr = self.ptr;
|
2014-05-06 17:01:16 -04:00
|
|
|
let cap = self.cap;
|
2014-09-04 15:25:23 -04:00
|
|
|
let begin = self.ptr as *const T;
|
2014-09-04 17:59:28 -04:00
|
|
|
let end = if mem::size_of::<T>() == 0 {
|
2014-10-02 14:06:31 -04:00
|
|
|
(ptr as uint + self.len()) as *const T
|
2014-09-04 17:59:28 -04:00
|
|
|
} else {
|
2014-10-02 14:06:31 -04:00
|
|
|
ptr.offset(self.len() as int) as *const T
|
2014-09-04 17:59:28 -04:00
|
|
|
};
|
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 10:34:51 -07:00
|
|
|
mem::forget(self);
|
2014-09-04 15:25:23 -04:00
|
|
|
MoveItems { allocation: ptr, cap: cap, ptr: begin, end: end }
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Sets the length of a vector.
|
|
|
|
///
|
|
|
|
/// This will explicitly set the size of the vector, without actually
|
|
|
|
/// modifying its buffers, so it is up to the caller to ensure that the
|
|
|
|
/// vector is actually the specified size.
|
2014-07-22 11:07:49 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let mut v = vec![1u, 2, 3, 4];
|
|
|
|
/// unsafe {
|
|
|
|
/// v.set_len(1);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-01-21 09:35:11 -05:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-01-21 09:35:11 -05:00
|
|
|
pub unsafe fn set_len(&mut self, len: uint) {
|
|
|
|
self.len = len;
|
|
|
|
}
|
2014-02-18 21:36:51 -08:00
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a reference to the value at index `index`.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails if `index` is out of bounds
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-15 11:37:25 +12:00
|
|
|
/// #![allow(deprecated)]
|
|
|
|
///
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// assert!(vec.get(1) == &2);
|
|
|
|
/// ```
|
2014-07-15 11:37:25 +12:00
|
|
|
#[deprecated="prefer using indexing, e.g., vec[0]"]
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn get<'a>(&'a self, index: uint) -> &'a T {
|
|
|
|
&self.as_slice()[index]
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a mutable reference to the value at index `index`.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails if `index` is out of bounds
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// *vec.get_mut(1) = 4;
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1i, 4, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "this is likely to be moved to actual indexing"]
|
2014-02-18 21:36:51 -08:00
|
|
|
pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T {
|
|
|
|
&mut self.as_mut_slice()[index]
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns an iterator over references to the elements of the vector in
|
|
|
|
/// order.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// for num in vec.iter() {
|
|
|
|
/// println!("{}", *num);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn iter<'a>(&'a self) -> Items<'a,T> {
|
|
|
|
self.as_slice().iter()
|
|
|
|
}
|
|
|
|
|
2014-09-14 15:57:55 -07:00
|
|
|
/// Deprecated: use `iter_mut`.
|
|
|
|
#[deprecated = "use iter_mut"]
|
|
|
|
pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a,T> {
|
|
|
|
self.iter_mut()
|
|
|
|
}
|
2014-03-16 16:04:29 -07:00
|
|
|
|
|
|
|
/// Returns an iterator over mutable references to the elements of the
|
|
|
|
/// vector in order.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-09-14 20:27:36 -07:00
|
|
|
/// for num in vec.iter_mut() {
|
2014-03-16 16:04:29 -07:00
|
|
|
/// *num = 0;
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a,T> {
|
2014-09-14 20:27:36 -07:00
|
|
|
self.as_mut_slice().iter_mut()
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Sorts the vector, in place, using `compare` to compare elements.
|
2014-03-16 16:04:29 -07: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
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut v = vec![5i, 4, 1, 3, 2];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// v.sort_by(|a, b| a.cmp(b));
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(v, vec![1i, 2, 3, 4, 5]);
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// // reverse sorting
|
|
|
|
/// v.sort_by(|a, b| b.cmp(a));
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(v, vec![5i, 4, 3, 2, 1]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
|
|
|
|
self.as_mut_slice().sort_by(compare)
|
|
|
|
}
|
|
|
|
|
2014-06-05 09:33:49 +02:00
|
|
|
/// Returns a slice of self spanning the interval [`start`, `end`).
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
2014-06-05 09:33:49 +02:00
|
|
|
/// Fails when the slice (or part of it) is outside the bounds of self, or when
|
2014-03-16 16:04:29 -07:00
|
|
|
/// `start` > `end`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3, 4];
|
2014-09-24 23:41:09 +12:00
|
|
|
/// assert!(vec[0..2] == [1, 2]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[start..end]
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a slice containing all but the first element of the vector.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails when the vector is empty.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// assert!(vec.tail() == [2, 3]);
|
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn tail<'a>(&'a self) -> &'a [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[].tail()
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns all but the first `n' elements of a vector.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails when there are fewer than `n` elements in the vector.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-09-22 19:31:31 +02:00
|
|
|
/// #![allow(deprecated)]
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3, 4];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// assert!(vec.tailn(2) == [3, 4]);
|
|
|
|
/// ```
|
2014-03-04 10:39:49 -08:00
|
|
|
#[inline]
|
2014-10-02 11:48:07 -07:00
|
|
|
#[deprecated = "use slice_from"]
|
2014-03-04 10:39:49 -08:00
|
|
|
pub fn tailn<'a>(&'a self, n: uint) -> &'a [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[n..]
|
2014-03-04 10:39:49 -08:00
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a reference to the last element of a vector, or `None` if it is
|
|
|
|
/// empty.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// assert!(vec.last() == Some(&3));
|
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn last<'a>(&'a self) -> Option<&'a T> {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[].last()
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-09-14 15:57:55 -07:00
|
|
|
/// Deprecated: use `last_mut`.
|
|
|
|
#[deprecated = "use last_mut"]
|
|
|
|
pub fn mut_last<'a>(&'a mut self) -> Option<&'a mut T> {
|
|
|
|
self.last_mut()
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a mutable reference to the last element of a vector, or `None`
|
|
|
|
/// if it is empty.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-09-14 20:27:36 -07:00
|
|
|
/// *vec.last_mut().unwrap() = 4;
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1i, 2, 4]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> {
|
2014-09-14 20:27:36 -07:00
|
|
|
self.as_mut_slice().last_mut()
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Removes an element from anywhere in the vector and return it, replacing
|
2014-03-16 16:04:29 -07:00
|
|
|
/// it with the last element. This does not preserve ordering, but is O(1).
|
|
|
|
///
|
|
|
|
/// Returns `None` if `index` is out of bounds.
|
|
|
|
///
|
|
|
|
/// # Example
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut v = vec!["foo".to_string(), "bar".to_string(),
|
|
|
|
/// "baz".to_string(), "qux".to_string()];
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
2014-05-25 03:10:11 -07:00
|
|
|
/// assert_eq!(v.swap_remove(1), Some("bar".to_string()));
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(v, vec!["foo".to_string(), "qux".to_string(), "baz".to_string()]);
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
2014-05-25 03:10:11 -07:00
|
|
|
/// assert_eq!(v.swap_remove(0), Some("foo".to_string()));
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(v, vec!["baz".to_string(), "qux".to_string()]);
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// assert_eq!(v.swap_remove(2), None);
|
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "the naming of this function may be altered"]
|
2014-02-23 10:56:38 +11:00
|
|
|
pub fn swap_remove(&mut self, index: uint) -> Option<T> {
|
2014-02-18 21:36:51 -08:00
|
|
|
let length = self.len();
|
2014-08-02 14:36:51 -04:00
|
|
|
if length > 0 && index < length - 1 {
|
2014-02-18 21:36:51 -08:00
|
|
|
self.as_mut_slice().swap(index, length - 1);
|
2014-02-23 10:56:38 +11:00
|
|
|
} else if index >= length {
|
|
|
|
return None
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
2014-02-23 10:56:38 +11:00
|
|
|
self.pop()
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Prepends an element to the vector.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Warning
|
|
|
|
///
|
|
|
|
/// This is an O(n) operation as it requires copying every element in the
|
|
|
|
/// vector.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-20 17:57:29 -07:00
|
|
|
/// ```ignore
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.unshift(4);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![4, 1, 2, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-02-18 21:36:51 -08:00
|
|
|
#[inline]
|
2014-07-14 13:54:10 -07:00
|
|
|
#[deprecated = "use insert(0, ...)"]
|
2014-02-18 21:36:51 -08:00
|
|
|
pub fn unshift(&mut self, element: T) {
|
|
|
|
self.insert(0, element)
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Removes the first element from a vector and returns it, or `None` if
|
|
|
|
/// the vector is empty.
|
|
|
|
///
|
|
|
|
/// # Warning
|
|
|
|
///
|
|
|
|
/// This is an O(n) operation as it requires copying every element in the
|
|
|
|
/// vector.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-09-22 19:31:31 +02:00
|
|
|
/// #![allow(deprecated)]
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// assert!(vec.shift() == Some(1));
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![2, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-03-11 00:53:23 -04:00
|
|
|
#[inline]
|
2014-07-14 13:54:10 -07:00
|
|
|
#[deprecated = "use remove(0)"]
|
2014-03-11 00:53:23 -04:00
|
|
|
pub fn shift(&mut self) -> Option<T> {
|
|
|
|
self.remove(0)
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Inserts an element at position `index` within the vector, shifting all
|
|
|
|
/// elements after position `i` one position to the right.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
2014-06-27 10:51:56 +02:00
|
|
|
/// Fails if `index` is not between `0` and the vector's length (both
|
|
|
|
/// bounds inclusive).
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.insert(1, 4);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1, 4, 2, 3]);
|
2014-06-27 10:51:56 +02:00
|
|
|
/// vec.insert(4, 5);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1, 4, 2, 3, 5]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-09-17 12:56:31 -07:00
|
|
|
#[unstable = "failure semantics need settling"]
|
2014-02-18 21:36:51 -08:00
|
|
|
pub fn insert(&mut self, index: uint, element: T) {
|
|
|
|
let len = self.len();
|
|
|
|
assert!(index <= len);
|
|
|
|
// space for the new element
|
2014-02-23 10:59:23 +11:00
|
|
|
self.reserve(len + 1);
|
2014-02-18 21:36:51 -08:00
|
|
|
|
|
|
|
unsafe { // infallible
|
|
|
|
// The spot to put the new value
|
|
|
|
{
|
2014-03-16 17:20:44 -04:00
|
|
|
let p = self.as_mut_ptr().offset(index as int);
|
2014-02-18 21:36:51 -08:00
|
|
|
// Shift everything over to make space. (Duplicating the
|
|
|
|
// `index`th element into two consecutive places.)
|
|
|
|
ptr::copy_memory(p.offset(1), &*p, len - index);
|
|
|
|
// Write it in, overwriting the first copy of the `index`th
|
|
|
|
// element.
|
2014-05-29 19:03:06 -07:00
|
|
|
ptr::write(&mut *p, element);
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
self.set_len(len + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Removes and returns the element at position `index` within the vector,
|
2014-03-16 16:04:29 -07:00
|
|
|
/// shifting all elements after position `index` one position to the left.
|
|
|
|
/// Returns `None` if `i` is out of bounds.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut v = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// assert_eq!(v.remove(1), Some(2));
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(v, vec![1, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// assert_eq!(v.remove(4), None);
|
|
|
|
/// // v is unchanged:
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(v, vec![1, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-09-17 12:56:31 -07:00
|
|
|
#[unstable = "failure semantics need settling"]
|
2014-03-18 11:53:32 -05:00
|
|
|
pub fn remove(&mut self, index: uint) -> Option<T> {
|
2014-03-11 00:53:23 -04:00
|
|
|
let len = self.len();
|
|
|
|
if index < len {
|
|
|
|
unsafe { // infallible
|
|
|
|
let ret;
|
|
|
|
{
|
|
|
|
// the place we are taking from.
|
2014-03-16 17:20:44 -04:00
|
|
|
let ptr = self.as_mut_ptr().offset(index as int);
|
2014-03-11 00:53:23 -04:00
|
|
|
// copy it out, unsafely having a copy of the value on
|
|
|
|
// the stack and in the vector at the same time.
|
2014-06-25 12:47:34 -07:00
|
|
|
ret = Some(ptr::read(ptr as *const T));
|
2014-03-11 00:53:23 -04:00
|
|
|
|
|
|
|
// Shift everything down to fill in that spot.
|
|
|
|
ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
|
|
|
|
}
|
|
|
|
self.set_len(len - 1);
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Takes ownership of the vector `other`, moving all elements into
|
|
|
|
/// the current vector. This does not copy any elements, and it is
|
|
|
|
/// illegal to use the `other` vector after calling this method
|
|
|
|
/// (because it is moved here).
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-09-17 12:56:31 -07:00
|
|
|
/// # #![allow(deprecated)]
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![box 1i];
|
|
|
|
/// vec.push_all_move(vec![box 2, box 3, box 4]);
|
|
|
|
/// assert_eq!(vec, vec![box 1, box 2, box 3, box 4]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-09-17 12:56:31 -07:00
|
|
|
#[deprecated = "use .extend(other.into_iter())"]
|
2014-02-18 21:36:51 -08:00
|
|
|
pub fn push_all_move(&mut self, other: Vec<T>) {
|
2014-09-14 20:27:36 -07:00
|
|
|
self.extend(other.into_iter());
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
|
|
|
|
2014-09-14 15:57:55 -07:00
|
|
|
/// Deprecated: use `slice_mut`.
|
2014-10-05 11:59:10 +13:00
|
|
|
#[deprecated = "use slice_mut"]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn mut_slice<'a>(&'a mut self, start: uint, end: uint)
|
|
|
|
-> &'a mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut start..end]
|
2014-09-14 15:57:55 -07:00
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a mutable slice of `self` between `start` and `end`.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails when `start` or `end` point outside the bounds of `self`, or when
|
|
|
|
/// `start` > `end`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3, 4];
|
2014-09-24 23:41:09 +12:00
|
|
|
/// assert!(vec[mut 0..2] == [1, 2]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-03-04 10:39:49 -08:00
|
|
|
#[inline]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn slice_mut<'a>(&'a mut self, start: uint, end: uint)
|
2014-03-16 16:04:29 -07:00
|
|
|
-> &'a mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut start..end]
|
2014-03-04 10:39:49 -08:00
|
|
|
}
|
|
|
|
|
2014-09-14 15:57:55 -07:00
|
|
|
/// Deprecated: use "slice_from_mut".
|
2014-10-02 11:48:07 -07:00
|
|
|
#[deprecated = "use slice_from_mut"]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn mut_slice_from<'a>(&'a mut self, start: uint) -> &'a mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut start..]
|
2014-09-14 15:57:55 -07:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Returns a mutable slice of `self` from `start` to the end of the `Vec`.
|
2014-03-18 12:52:06 +09:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails when `start` points outside the bounds of self.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3, 4];
|
2014-09-24 23:41:09 +12:00
|
|
|
/// assert!(vec[mut 2..] == [3, 4]);
|
2014-03-18 12:52:06 +09:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut start..]
|
2014-03-18 12:52:06 +09:00
|
|
|
}
|
|
|
|
|
2014-09-14 15:57:55 -07:00
|
|
|
/// Deprecated: use `slice_to_mut`.
|
2014-10-02 11:48:07 -07:00
|
|
|
#[deprecated = "use slice_to_mut"]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn mut_slice_to<'a>(&'a mut self, end: uint) -> &'a mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut ..end]
|
2014-09-14 15:57:55 -07:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Returns a mutable slice of `self` from the start of the `Vec` to `end`.
|
2014-03-18 12:52:06 +09:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails when `end` points outside the bounds of self.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3, 4];
|
2014-09-24 23:41:09 +12:00
|
|
|
/// assert!(vec[mut ..2] == [1, 2]);
|
2014-03-18 12:52:06 +09:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut ..end]
|
2014-03-18 12:52:06 +09:00
|
|
|
}
|
|
|
|
|
2014-09-14 15:57:55 -07:00
|
|
|
/// Deprecated: use `split_at_mut`.
|
|
|
|
#[deprecated = "use split_at_mut"]
|
|
|
|
pub fn mut_split_at<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
|
|
|
|
self.split_at_mut(mid)
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Returns a pair of mutable slices that divides the `Vec` at an index.
|
2014-03-18 12:52:06 +09:00
|
|
|
///
|
|
|
|
/// The first will contain all indices from `[0, mid)` (excluding
|
|
|
|
/// the index `mid` itself) and the second will contain all
|
|
|
|
/// indices from `[mid, len)` (excluding the index `len` itself).
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails if `mid > len`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3, 4, 5, 6];
|
2014-03-18 12:52:06 +09:00
|
|
|
///
|
|
|
|
/// // scoped to restrict the lifetime of the borrows
|
|
|
|
/// {
|
2014-09-14 20:27:36 -07:00
|
|
|
/// let (left, right) = vec.split_at_mut(0);
|
2014-03-18 12:52:06 +09:00
|
|
|
/// assert!(left == &mut []);
|
|
|
|
/// assert!(right == &mut [1, 2, 3, 4, 5, 6]);
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// {
|
2014-09-14 20:27:36 -07:00
|
|
|
/// let (left, right) = vec.split_at_mut(2);
|
2014-03-18 12:52:06 +09:00
|
|
|
/// assert!(left == &mut [1, 2]);
|
|
|
|
/// assert!(right == &mut [3, 4, 5, 6]);
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// {
|
2014-09-14 20:27:36 -07:00
|
|
|
/// let (left, right) = vec.split_at_mut(6);
|
2014-03-18 12:52:06 +09:00
|
|
|
/// assert!(left == &mut [1, 2, 3, 4, 5, 6]);
|
|
|
|
/// assert!(right == &mut []);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
2014-09-14 15:57:55 -07:00
|
|
|
pub fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut].split_at_mut(mid)
|
2014-03-18 12:52:06 +09:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Reverses the order of elements in a vector, in place.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut v = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// v.reverse();
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(v, vec![3i, 2, 1]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-03-04 10:39:49 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn reverse(&mut self) {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut].reverse()
|
2014-03-04 10:39:49 -08:00
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a slice of `self` from `start` to the end of the vec.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails when `start` points outside the bounds of self.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3];
|
2014-09-24 23:41:09 +12:00
|
|
|
/// assert!(vec[1..] == [2, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-03-04 10:39:49 -08:00
|
|
|
#[inline]
|
2014-02-18 21:36:51 -08:00
|
|
|
pub fn slice_from<'a>(&'a self, start: uint) -> &'a [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[start..]
|
2014-02-18 21:36:51 -08:00
|
|
|
}
|
2014-02-28 12:55:51 -08:00
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a slice of self from the start of the vec to `end`.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails when `end` points outside the bounds of self.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 11:07:49 +02:00
|
|
|
/// let vec = vec![1i, 2, 3, 4];
|
2014-09-24 23:41:09 +12:00
|
|
|
/// assert!(vec[..2] == [1, 2]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-03-04 10:39:49 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn slice_to<'a>(&'a self, end: uint) -> &'a [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[..end]
|
2014-03-04 10:39:49 -08:00
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a slice containing all but the last element of the vector.
|
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails if the vector is empty
|
2014-07-22 11:07:49 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let vec = vec![1i, 2, 3];
|
|
|
|
/// assert!(vec.init() == [1, 2]);
|
|
|
|
/// ```
|
2014-02-28 12:55:51 -08:00
|
|
|
#[inline]
|
|
|
|
pub fn init<'a>(&'a self) -> &'a [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[0..self.len() - 1]
|
2014-02-28 12:55:51 -08:00
|
|
|
}
|
2014-03-04 10:39:49 -08:00
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
|
|
|
|
/// Returns an unsafe pointer to the vector's buffer.
|
|
|
|
///
|
|
|
|
/// The caller must ensure that the vector outlives the pointer this
|
|
|
|
/// function returns, or else it will end up pointing to garbage.
|
|
|
|
///
|
|
|
|
/// Modifying the vector may cause its buffer to be reallocated, which
|
|
|
|
/// would also make any pointers to it invalid.
|
2014-07-22 11:07:49 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let v = vec![1i, 2, 3];
|
|
|
|
/// let p = v.as_ptr();
|
|
|
|
/// unsafe {
|
2014-07-22 13:40:38 +02:00
|
|
|
/// // Examine each element manually
|
|
|
|
/// assert_eq!(*p, 1i);
|
|
|
|
/// assert_eq!(*p.offset(1), 2i);
|
|
|
|
/// assert_eq!(*p.offset(2), 3i);
|
2014-07-22 11:07:49 +02:00
|
|
|
/// }
|
|
|
|
/// ```
|
2014-03-04 10:39:49 -08:00
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
pub fn as_ptr(&self) -> *const T {
|
2014-07-03 22:24:33 -07:00
|
|
|
self.ptr as *const T
|
2014-03-04 10:39:49 -08:00
|
|
|
}
|
2014-03-16 17:20:44 -04:00
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Returns a mutable unsafe pointer to the vector's buffer.
|
|
|
|
///
|
|
|
|
/// The caller must ensure that the vector outlives the pointer this
|
|
|
|
/// function returns, or else it will end up pointing to garbage.
|
|
|
|
///
|
|
|
|
/// Modifying the vector may cause its buffer to be reallocated, which
|
|
|
|
/// would also make any pointers to it invalid.
|
2014-07-22 11:07:49 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::ptr;
|
|
|
|
///
|
|
|
|
/// let mut v = vec![1i, 2, 3];
|
|
|
|
/// let p = v.as_mut_ptr();
|
|
|
|
/// unsafe {
|
|
|
|
/// ptr::write(p, 9i);
|
2014-07-22 13:40:38 +02:00
|
|
|
/// ptr::write(p.offset(2), 5i);
|
2014-07-22 11:07:49 +02:00
|
|
|
/// }
|
2014-07-22 13:40:38 +02:00
|
|
|
/// assert_eq!(v, vec![9i, 2, 5]);
|
2014-07-22 11:07:49 +02:00
|
|
|
/// ```
|
2014-03-16 17:20:44 -04:00
|
|
|
#[inline]
|
|
|
|
pub fn as_mut_ptr(&mut self) -> *mut T {
|
2014-07-03 22:24:33 -07:00
|
|
|
self.ptr
|
2014-03-16 17:20:44 -04:00
|
|
|
}
|
2014-04-02 23:10:36 -04:00
|
|
|
|
|
|
|
/// Retains only the elements specified by the predicate.
|
|
|
|
///
|
|
|
|
/// In other words, remove all elements `e` such that `f(&e)` returns false.
|
2014-08-07 11:27:06 -04:00
|
|
|
/// This method operates in place and preserves the order of the retained elements.
|
2014-04-02 23:10:36 -04:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 3, 4];
|
2014-04-02 23:10:36 -04:00
|
|
|
/// vec.retain(|x| x%2 == 0);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![2, 4]);
|
2014-04-02 23:10:36 -04:00
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "the closure argument may become an unboxed closure"]
|
2014-04-02 23:10:36 -04:00
|
|
|
pub fn retain(&mut self, f: |&T| -> bool) {
|
|
|
|
let len = self.len();
|
|
|
|
let mut del = 0u;
|
|
|
|
{
|
|
|
|
let v = self.as_mut_slice();
|
|
|
|
|
|
|
|
for i in range(0u, len) {
|
|
|
|
if !f(&v[i]) {
|
|
|
|
del += 1;
|
|
|
|
} else if del > 0 {
|
|
|
|
v.swap(i-del, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if del > 0 {
|
|
|
|
self.truncate(len - del);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Expands a vector in place, initializing the new elements to the result of a function.
|
|
|
|
///
|
|
|
|
/// The vector is grown by `n` elements. The i-th new element are initialized to the value
|
|
|
|
/// returned by `f(i)` where `i` is in the range [0, n).
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![0u, 1];
|
2014-04-02 23:10:36 -04:00
|
|
|
/// vec.grow_fn(3, |i| i);
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![0, 1, 0, 1, 2]);
|
2014-04-02 23:10:36 -04:00
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "this function may be renamed or change to unboxed closures"]
|
2014-04-02 23:10:36 -04:00
|
|
|
pub fn grow_fn(&mut self, n: uint, f: |uint| -> T) {
|
|
|
|
self.reserve_additional(n);
|
|
|
|
for i in range(0u, n) {
|
|
|
|
self.push(f(i));
|
|
|
|
}
|
|
|
|
}
|
2014-03-08 21:47:12 +01:00
|
|
|
}
|
2014-03-04 10:39:49 -08:00
|
|
|
|
2014-05-31 10:43:52 -07:00
|
|
|
impl<T:Ord> Vec<T> {
|
2014-03-16 16:04:29 -07:00
|
|
|
/// Sorts the vector in place.
|
|
|
|
///
|
|
|
|
/// This sort is `O(n log n)` worst-case and stable, but allocates
|
|
|
|
/// approximately `2 * n`, where `n` is the length of `self`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![3i, 1, 2];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.sort();
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1, 2, 3]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
|
|
|
pub fn sort(&mut self) {
|
|
|
|
self.as_mut_slice().sort()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental = "waiting on Mutable stability"]
|
2014-03-08 21:47:12 +01:00
|
|
|
impl<T> Mutable for Vec<T> {
|
2014-03-04 10:39:49 -08:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-03-08 21:47:12 +01:00
|
|
|
fn clear(&mut self) {
|
2014-03-04 10:39:49 -08:00
|
|
|
self.truncate(0)
|
|
|
|
}
|
2014-02-28 12:55:51 -08:00
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
impl<T: PartialEq> Vec<T> {
|
|
|
|
/// Returns true if a vector contains an element equal to the given value.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2, 3];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// assert!(vec.contains(&1));
|
|
|
|
/// ```
|
2014-06-02 21:56:29 -07:00
|
|
|
#[inline]
|
2014-02-28 12:55:51 -08:00
|
|
|
pub fn contains(&self, x: &T) -> bool {
|
|
|
|
self.as_slice().contains(x)
|
|
|
|
}
|
2014-03-04 10:39:49 -08:00
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Removes consecutive repeated elements in the vector.
|
2014-03-16 16:04:29 -07:00
|
|
|
///
|
|
|
|
/// If the vector is sorted, this removes all duplicates.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let mut vec = vec![1i, 2, 2, 3, 2];
|
2014-03-16 16:04:29 -07:00
|
|
|
/// vec.dedup();
|
2014-07-22 10:33:26 +02:00
|
|
|
/// assert_eq!(vec, vec![1i, 2, 3, 2]);
|
2014-03-16 16:04:29 -07:00
|
|
|
/// ```
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "this function may be renamed"]
|
2014-03-04 10:39:49 -08:00
|
|
|
pub fn dedup(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
// Although we have a mutable reference to `self`, we cannot make
|
2014-05-29 17:45:07 -07:00
|
|
|
// *arbitrary* changes. The `PartialEq` comparisons could fail, so we
|
2014-03-04 10:39:49 -08:00
|
|
|
// must ensure that the vector is in a valid state at all time.
|
|
|
|
//
|
|
|
|
// The way that we handle this is by using swaps; we iterate
|
|
|
|
// over all the elements, swapping as we go so that at the end
|
|
|
|
// the elements we wish to keep are in the front, and those we
|
|
|
|
// wish to reject are at the back. We can then truncate the
|
|
|
|
// vector. This operation is still O(n).
|
|
|
|
//
|
|
|
|
// Example: We start in this state, where `r` represents "next
|
|
|
|
// read" and `w` represents "next_write`.
|
|
|
|
//
|
|
|
|
// r
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// | 0 | 1 | 1 | 2 | 3 | 3 |
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// w
|
|
|
|
//
|
2014-04-28 15:39:11 +02:00
|
|
|
// Comparing self[r] against self[w-1], this is not a duplicate, so
|
2014-03-04 10:39:49 -08:00
|
|
|
// we swap self[r] and self[w] (no effect as r==w) and then increment both
|
|
|
|
// r and w, leaving us with:
|
|
|
|
//
|
|
|
|
// r
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// | 0 | 1 | 1 | 2 | 3 | 3 |
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// w
|
|
|
|
//
|
|
|
|
// Comparing self[r] against self[w-1], this value is a duplicate,
|
|
|
|
// so we increment `r` but leave everything else unchanged:
|
|
|
|
//
|
|
|
|
// r
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// | 0 | 1 | 1 | 2 | 3 | 3 |
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// w
|
|
|
|
//
|
|
|
|
// Comparing self[r] against self[w-1], this is not a duplicate,
|
|
|
|
// so swap self[r] and self[w] and advance r and w:
|
|
|
|
//
|
|
|
|
// r
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// | 0 | 1 | 2 | 1 | 3 | 3 |
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// w
|
|
|
|
//
|
|
|
|
// Not a duplicate, repeat:
|
|
|
|
//
|
|
|
|
// r
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// | 0 | 1 | 2 | 3 | 1 | 3 |
|
|
|
|
// +---+---+---+---+---+---+
|
|
|
|
// w
|
|
|
|
//
|
|
|
|
// Duplicate, advance r. End of vec. Truncate to w.
|
|
|
|
|
|
|
|
let ln = self.len();
|
|
|
|
if ln < 1 { return; }
|
|
|
|
|
|
|
|
// Avoid bounds checks by using unsafe pointers.
|
|
|
|
let p = self.as_mut_slice().as_mut_ptr();
|
|
|
|
let mut r = 1;
|
|
|
|
let mut w = 1;
|
|
|
|
|
|
|
|
while r < ln {
|
|
|
|
let p_r = p.offset(r as int);
|
|
|
|
let p_wm1 = p.offset((w - 1) as int);
|
|
|
|
if *p_r != *p_wm1 {
|
|
|
|
if r != w {
|
|
|
|
let p_w = p_wm1.offset(1);
|
|
|
|
mem::swap(&mut *p_r, &mut *p_w);
|
|
|
|
}
|
|
|
|
w += 1;
|
|
|
|
}
|
|
|
|
r += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.truncate(w);
|
|
|
|
}
|
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
|
2014-10-05 12:22:42 +13:00
|
|
|
impl<T> AsSlice<T> for Vec<T> {
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Returns a slice into `self`.
|
2014-03-06 10:22:21 -08:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-07-22 14:02:55 +02:00
|
|
|
/// ```
|
2014-03-06 10:22:21 -08:00
|
|
|
/// fn foo(slice: &[int]) {}
|
|
|
|
///
|
2014-07-22 10:33:26 +02:00
|
|
|
/// let vec = vec![1i, 2];
|
2014-03-06 10:22:21 -08:00
|
|
|
/// foo(vec.as_slice());
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-03-06 10:22:21 -08:00
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T] {
|
2014-08-06 20:03:55 -07:00
|
|
|
unsafe { mem::transmute(RawSlice { data: self.as_ptr(), len: self.len }) }
|
2014-03-06 10:22:21 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-05 12:22:42 +13:00
|
|
|
impl<T: Clone, V: AsSlice<T>> Add<V, Vec<T>> for Vec<T> {
|
2014-05-03 23:09:45 -07:00
|
|
|
#[inline]
|
|
|
|
fn add(&self, rhs: &V) -> Vec<T> {
|
|
|
|
let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
|
|
|
|
res.push_all(self.as_slice());
|
|
|
|
res.push_all(rhs.as_slice());
|
|
|
|
res
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-21 09:35:11 -05:00
|
|
|
#[unsafe_destructor]
|
|
|
|
impl<T> Drop for Vec<T> {
|
|
|
|
fn drop(&mut self) {
|
2014-03-12 22:01:33 +02:00
|
|
|
// This is (and should always remain) a no-op if the fields are
|
|
|
|
// zeroed (when moving out, because of #[unsafe_no_drop_flag]).
|
2014-05-06 17:01:16 -04:00
|
|
|
if self.cap != 0 {
|
|
|
|
unsafe {
|
|
|
|
for x in self.as_mut_slice().iter() {
|
|
|
|
ptr::read(x);
|
|
|
|
}
|
2014-05-10 00:35:56 -04:00
|
|
|
dealloc(self.ptr, self.cap)
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-02-28 12:55:51 -08:00
|
|
|
impl<T> Default for Vec<T> {
|
|
|
|
fn default() -> Vec<T> {
|
|
|
|
Vec::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental = "waiting on Show stability"]
|
2014-02-28 12:54:01 -08:00
|
|
|
impl<T:fmt::Show> fmt::Show for Vec<T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
self.as_slice().fmt(f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 13:20:58 -07:00
|
|
|
#[experimental = "waiting on MutableSeq stability"]
|
2014-07-11 10:12:38 -07:00
|
|
|
impl<T> MutableSeq<T> for Vec<T> {
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Appends an element to the back of a collection.
|
2014-07-14 14:51:54 -07:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Fails if the number of elements in the vector overflows a `uint`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let mut vec = vec!(1i, 2);
|
|
|
|
/// vec.push(3);
|
|
|
|
/// assert_eq!(vec, vec!(1, 2, 3));
|
|
|
|
/// ```
|
2014-07-11 10:12:38 -07:00
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-07-11 10:12:38 -07:00
|
|
|
fn push(&mut self, value: T) {
|
|
|
|
if mem::size_of::<T>() == 0 {
|
|
|
|
// zero-size types consume no memory, so we can't rely on the address space running out
|
|
|
|
self.len = self.len.checked_add(&1).expect("length overflow");
|
|
|
|
unsafe { mem::forget(value); }
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if self.len == self.cap {
|
|
|
|
let old_size = self.cap * mem::size_of::<T>();
|
|
|
|
let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
|
|
|
|
if old_size > size { fail!("capacity overflow") }
|
|
|
|
unsafe {
|
|
|
|
self.ptr = alloc_or_realloc(self.ptr, size,
|
|
|
|
self.cap * mem::size_of::<T>());
|
|
|
|
}
|
|
|
|
self.cap = max(self.cap, 2) * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let end = (self.ptr as *const T).offset(self.len as int) as *mut T;
|
|
|
|
ptr::write(&mut *end, value);
|
|
|
|
self.len += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[stable]
|
2014-07-11 10:12:38 -07:00
|
|
|
fn pop(&mut self) -> Option<T> {
|
|
|
|
if self.len == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
unsafe {
|
|
|
|
self.len -= 1;
|
2014-08-06 20:08:16 -07:00
|
|
|
Some(ptr::read(self.as_slice().unsafe_get(self.len())))
|
2014-07-11 10:12:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-03-16 16:04:29 -07:00
|
|
|
/// An iterator that moves out of a vector.
|
2014-01-21 09:35:11 -05:00
|
|
|
pub struct MoveItems<T> {
|
2014-05-10 00:35:56 -04:00
|
|
|
allocation: *mut T, // the block of memory allocated for the vector
|
2014-05-06 17:01:16 -04:00
|
|
|
cap: uint, // the capacity of the vector
|
2014-09-04 15:25:23 -04:00
|
|
|
ptr: *const T,
|
|
|
|
end: *const T
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
|
2014-08-31 15:29:22 +02:00
|
|
|
impl<T> MoveItems<T> {
|
|
|
|
#[inline]
|
|
|
|
/// Drops all items that have not yet been moved and returns the empty vector.
|
|
|
|
pub fn unwrap(mut self) -> Vec<T> {
|
|
|
|
unsafe {
|
|
|
|
for _x in self { }
|
2014-10-02 14:06:31 -04:00
|
|
|
let MoveItems { allocation, cap, ptr: _ptr, end: _end } = self;
|
2014-08-31 15:29:22 +02:00
|
|
|
mem::forget(self);
|
|
|
|
Vec { ptr: allocation, cap: cap, len: 0 }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-21 09:35:11 -05:00
|
|
|
impl<T> Iterator<T> for MoveItems<T> {
|
|
|
|
#[inline]
|
2014-08-27 21:46:52 -04:00
|
|
|
fn next<'a>(&'a mut self) -> Option<T> {
|
2014-01-21 09:35:11 -05:00
|
|
|
unsafe {
|
2014-09-04 15:25:23 -04:00
|
|
|
if self.ptr == self.end {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
if mem::size_of::<T>() == 0 {
|
|
|
|
// purposefully don't use 'ptr.offset' because for
|
|
|
|
// vectors with 0-size elements this would return the
|
|
|
|
// same pointer.
|
|
|
|
self.ptr = mem::transmute(self.ptr as uint + 1);
|
|
|
|
|
|
|
|
// Use a non-null pointer value
|
|
|
|
Some(ptr::read(mem::transmute(1u)))
|
|
|
|
} else {
|
|
|
|
let old = self.ptr;
|
|
|
|
self.ptr = self.ptr.offset(1);
|
|
|
|
|
|
|
|
Some(ptr::read(old))
|
|
|
|
}
|
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2014-09-04 15:25:23 -04:00
|
|
|
let diff = (self.end as uint) - (self.ptr as uint);
|
|
|
|
let size = mem::size_of::<T>();
|
|
|
|
let exact = diff / (if size == 0 {1} else {size});
|
|
|
|
(exact, Some(exact))
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> DoubleEndedIterator<T> for MoveItems<T> {
|
|
|
|
#[inline]
|
2014-08-27 21:46:52 -04:00
|
|
|
fn next_back<'a>(&'a mut self) -> Option<T> {
|
2014-01-21 09:35:11 -05:00
|
|
|
unsafe {
|
2014-09-04 15:25:23 -04:00
|
|
|
if self.end == self.ptr {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
if mem::size_of::<T>() == 0 {
|
|
|
|
// See above for why 'ptr.offset' isn't used
|
|
|
|
self.end = mem::transmute(self.end as uint - 1);
|
|
|
|
|
|
|
|
// Use a non-null pointer value
|
|
|
|
Some(ptr::read(mem::transmute(1u)))
|
|
|
|
} else {
|
|
|
|
self.end = self.end.offset(-1);
|
|
|
|
|
|
|
|
Some(ptr::read(mem::transmute(self.end)))
|
|
|
|
}
|
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-14 23:25:08 -04:00
|
|
|
impl<T> ExactSize<T> for MoveItems<T> {}
|
|
|
|
|
2014-01-21 09:35:11 -05:00
|
|
|
#[unsafe_destructor]
|
|
|
|
impl<T> Drop for MoveItems<T> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
// destroy the remaining elements
|
2014-05-06 17:01:16 -04:00
|
|
|
if self.cap != 0 {
|
|
|
|
for _x in *self {}
|
|
|
|
unsafe {
|
2014-05-10 00:35:56 -04:00
|
|
|
dealloc(self.allocation, self.cap);
|
2014-05-06 17:01:16 -04:00
|
|
|
}
|
2014-01-21 09:35:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-03-04 07:46:24 +11:00
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Converts an iterator of pairs into a pair of vectors.
|
|
|
|
///
|
|
|
|
/// Returns a tuple containing two vectors where the i-th element of the first
|
|
|
|
/// vector contains the first element of the i-th tuple of the input iterator,
|
|
|
|
/// and the i-th element of the second vector contains the second element
|
|
|
|
/// of the i-th tuple of the input iterator.
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable = "this functionality may become more generic over time"]
|
2014-05-03 18:10:04 -07:00
|
|
|
pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
|
|
|
|
let (lo, _) = iter.size_hint();
|
|
|
|
let mut ts = Vec::with_capacity(lo);
|
|
|
|
let mut us = Vec::with_capacity(lo);
|
|
|
|
for (t, u) in iter {
|
|
|
|
ts.push(t);
|
|
|
|
us.push(u);
|
|
|
|
}
|
|
|
|
(ts, us)
|
|
|
|
}
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Unsafe vector operations.
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable]
|
2014-05-03 18:20:35 -07:00
|
|
|
pub mod raw {
|
|
|
|
use super::Vec;
|
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 18:50:12 -07:00
|
|
|
use core::ptr;
|
2014-05-03 18:20:35 -07:00
|
|
|
|
|
|
|
/// Constructs a vector from an unsafe pointer to a buffer.
|
|
|
|
///
|
|
|
|
/// The elements of the buffer are copied into the vector without cloning,
|
|
|
|
/// as if `ptr::read()` were called on them.
|
|
|
|
#[inline]
|
2014-08-29 13:20:58 -07:00
|
|
|
#[unstable]
|
2014-06-25 12:47:34 -07:00
|
|
|
pub unsafe fn from_buf<T>(ptr: *const T, elts: uint) -> Vec<T> {
|
2014-05-03 18:20:35 -07:00
|
|
|
let mut dst = Vec::with_capacity(elts);
|
|
|
|
dst.set_len(elts);
|
|
|
|
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
|
|
|
|
dst
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-19 01:38:50 +02:00
|
|
|
/// An owned, partially type-converted vector of elements with non-zero size.
|
2014-07-01 15:10:22 +02:00
|
|
|
///
|
2014-09-19 01:38:50 +02:00
|
|
|
/// `T` and `U` must have the same, non-zero size. They must also have the same
|
|
|
|
/// alignment.
|
2014-08-03 14:16:10 +02:00
|
|
|
///
|
2014-09-19 01:38:50 +02:00
|
|
|
/// When the destructor of this struct runs, all `U`s from `start_u` (incl.) to
|
|
|
|
/// `end_u` (excl.) and all `T`s from `start_t` (incl.) to `end_t` (excl.) are
|
|
|
|
/// destructed. Additionally the underlying storage of `vec` will be freed.
|
|
|
|
struct PartialVecNonZeroSized<T,U> {
|
2014-07-01 15:10:22 +02:00
|
|
|
vec: Vec<T>,
|
|
|
|
|
|
|
|
start_u: *mut U,
|
|
|
|
end_u: *mut U,
|
|
|
|
start_t: *mut T,
|
|
|
|
end_t: *mut T,
|
|
|
|
}
|
|
|
|
|
2014-09-19 01:38:50 +02:00
|
|
|
/// An owned, partially type-converted vector of zero-sized elements.
|
|
|
|
///
|
|
|
|
/// When the destructor of this struct runs, all `num_t` `T`s and `num_u` `U`s
|
|
|
|
/// are destructed.
|
|
|
|
struct PartialVecZeroSized<T,U> {
|
|
|
|
num_t: uint,
|
|
|
|
num_u: uint,
|
|
|
|
marker_t: InvariantType<T>,
|
|
|
|
marker_u: InvariantType<U>,
|
2014-07-01 15:10:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[unsafe_destructor]
|
2014-09-19 01:38:50 +02:00
|
|
|
impl<T,U> Drop for PartialVecNonZeroSized<T,U> {
|
2014-07-01 15:10:22 +02:00
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
2014-09-19 01:38:50 +02:00
|
|
|
// `vec` hasn't been modified until now. As it has a length
|
|
|
|
// currently, this would run destructors of `T`s which might not be
|
|
|
|
// there. So at first, set `vec`s length to `0`. This must be done
|
|
|
|
// at first to remain memory-safe as the destructors of `U` or `T`
|
|
|
|
// might cause unwinding where `vec`s destructor would be executed.
|
2014-07-01 15:10:22 +02:00
|
|
|
self.vec.set_len(0);
|
|
|
|
|
2014-09-19 01:38:50 +02:00
|
|
|
// We have instances of `U`s and `T`s in `vec`. Destruct them.
|
|
|
|
while self.start_u != self.end_u {
|
2014-07-01 15:10:22 +02:00
|
|
|
let _ = ptr::read(self.start_u as *const U); // Run a `U` destructor.
|
|
|
|
self.start_u = self.start_u.offset(1);
|
|
|
|
}
|
2014-09-19 01:38:50 +02:00
|
|
|
while self.start_t != self.end_t {
|
2014-07-01 15:10:22 +02:00
|
|
|
let _ = ptr::read(self.start_t as *const T); // Run a `T` destructor.
|
|
|
|
self.start_t = self.start_t.offset(1);
|
|
|
|
}
|
|
|
|
// After this destructor ran, the destructor of `vec` will run,
|
|
|
|
// deallocating the underlying memory.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-19 01:38:50 +02:00
|
|
|
#[unsafe_destructor]
|
|
|
|
impl<T,U> Drop for PartialVecZeroSized<T,U> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
// Destruct the instances of `T` and `U` this struct owns.
|
|
|
|
while self.num_t != 0 {
|
|
|
|
let _: T = mem::uninitialized(); // Run a `T` destructor.
|
|
|
|
self.num_t -= 1;
|
|
|
|
}
|
|
|
|
while self.num_u != 0 {
|
|
|
|
let _: U = mem::uninitialized(); // Run a `U` destructor.
|
|
|
|
self.num_u -= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-01 15:10:22 +02:00
|
|
|
impl<T> Vec<T> {
|
2014-08-03 14:16:10 +02:00
|
|
|
/// Converts a `Vec<T>` to a `Vec<U>` where `T` and `U` have the same
|
2014-09-19 01:38:50 +02:00
|
|
|
/// size and in case they are not zero-sized the same minimal alignment.
|
2014-08-03 14:16:10 +02:00
|
|
|
///
|
|
|
|
/// # Failure
|
|
|
|
///
|
2014-09-19 01:38:50 +02:00
|
|
|
/// Fails if `T` and `U` have differing sizes or are not zero-sized and
|
|
|
|
/// have differing minimal alignments.
|
2014-07-01 15:10:22 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-09-11 02:04:51 +02:00
|
|
|
/// ```
|
2014-07-01 15:10:22 +02:00
|
|
|
/// let v = vec![0u, 1, 2];
|
2014-09-11 02:04:51 +02:00
|
|
|
/// let w = v.map_in_place(|i| i + 3);
|
2014-09-14 21:33:48 +02:00
|
|
|
/// assert_eq!(w.as_slice(), [3, 4, 5].as_slice());
|
2014-07-01 15:10:22 +02:00
|
|
|
///
|
2014-09-14 21:33:48 +02:00
|
|
|
/// #[deriving(PartialEq, Show)]
|
|
|
|
/// struct Newtype(u8);
|
|
|
|
/// let bytes = vec![0x11, 0x22];
|
|
|
|
/// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
|
|
|
|
/// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice());
|
2014-07-01 15:10:22 +02:00
|
|
|
/// ```
|
2014-09-11 02:04:51 +02:00
|
|
|
pub fn map_in_place<U>(self, f: |T| -> U) -> Vec<U> {
|
2014-09-19 01:38:50 +02:00
|
|
|
// FIXME: Assert statically that the types `T` and `U` have the same
|
|
|
|
// size.
|
|
|
|
assert!(mem::size_of::<T>() == mem::size_of::<U>());
|
|
|
|
|
|
|
|
let mut vec = self;
|
|
|
|
|
|
|
|
if mem::size_of::<T>() != 0 {
|
|
|
|
// FIXME: Assert statically that the types `T` and `U` have the
|
|
|
|
// same minimal alignment in case they are not zero-sized.
|
|
|
|
|
|
|
|
// These asserts are necessary because the `min_align_of` of the
|
|
|
|
// types are passed to the allocator by `Vec`.
|
|
|
|
assert!(mem::min_align_of::<T>() == mem::min_align_of::<U>());
|
|
|
|
|
|
|
|
// This `as int` cast is safe, because the size of the elements of the
|
|
|
|
// vector is not 0, and:
|
|
|
|
//
|
|
|
|
// 1) If the size of the elements in the vector is 1, the `int` may
|
|
|
|
// overflow, but it has the correct bit pattern so that the
|
|
|
|
// `.offset()` function will work.
|
|
|
|
//
|
|
|
|
// Example:
|
|
|
|
// Address space 0x0-0xF.
|
|
|
|
// `u8` array at: 0x1.
|
|
|
|
// Size of `u8` array: 0x8.
|
|
|
|
// Calculated `offset`: -0x8.
|
|
|
|
// After `array.offset(offset)`: 0x9.
|
|
|
|
// (0x1 + 0x8 = 0x1 - 0x8)
|
|
|
|
//
|
|
|
|
// 2) If the size of the elements in the vector is >1, the `uint` ->
|
|
|
|
// `int` conversion can't overflow.
|
|
|
|
let offset = vec.len() as int;
|
|
|
|
let start = vec.as_mut_ptr();
|
|
|
|
|
|
|
|
let mut pv = PartialVecNonZeroSized {
|
|
|
|
vec: vec,
|
|
|
|
|
|
|
|
start_t: start,
|
|
|
|
// This points inside the vector, as the vector has length
|
|
|
|
// `offset`.
|
|
|
|
end_t: unsafe { start.offset(offset) },
|
|
|
|
start_u: start as *mut U,
|
|
|
|
end_u: start as *mut U,
|
|
|
|
};
|
|
|
|
// start_t
|
|
|
|
// start_u
|
|
|
|
// |
|
|
|
|
// +-+-+-+-+-+-+
|
|
|
|
// |T|T|T|...|T|
|
|
|
|
// +-+-+-+-+-+-+
|
|
|
|
// | |
|
|
|
|
// end_u end_t
|
|
|
|
|
|
|
|
while pv.end_u as *mut T != pv.end_t {
|
|
|
|
unsafe {
|
|
|
|
// start_u start_t
|
|
|
|
// | |
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// |U|...|U|T|T|...|T|
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// | |
|
|
|
|
// end_u end_t
|
|
|
|
|
|
|
|
let t = ptr::read(pv.start_t as *const T);
|
|
|
|
// start_u start_t
|
|
|
|
// | |
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// |U|...|U|X|T|...|T|
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// | |
|
|
|
|
// end_u end_t
|
|
|
|
// We must not fail here, one cell is marked as `T`
|
|
|
|
// although it is not `T`.
|
|
|
|
|
|
|
|
pv.start_t = pv.start_t.offset(1);
|
|
|
|
// start_u start_t
|
|
|
|
// | |
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// |U|...|U|X|T|...|T|
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// | |
|
|
|
|
// end_u end_t
|
|
|
|
// We may fail again.
|
|
|
|
|
|
|
|
// The function given by the user might fail.
|
|
|
|
let u = f(t);
|
|
|
|
|
|
|
|
ptr::write(pv.end_u, u);
|
|
|
|
// start_u start_t
|
|
|
|
// | |
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// |U|...|U|U|T|...|T|
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// | |
|
|
|
|
// end_u end_t
|
|
|
|
// We should not fail here, because that would leak the `U`
|
|
|
|
// pointed to by `end_u`.
|
|
|
|
|
|
|
|
pv.end_u = pv.end_u.offset(1);
|
|
|
|
// start_u start_t
|
|
|
|
// | |
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// |U|...|U|U|T|...|T|
|
|
|
|
// +-+-+-+-+-+-+-+-+-+
|
|
|
|
// | |
|
|
|
|
// end_u end_t
|
|
|
|
// We may fail again.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// start_u start_t
|
|
|
|
// | |
|
|
|
|
// +-+-+-+-+-+-+
|
|
|
|
// |U|...|U|U|U|
|
|
|
|
// +-+-+-+-+-+-+
|
|
|
|
// |
|
|
|
|
// end_t
|
|
|
|
// end_u
|
|
|
|
// Extract `vec` and prevent the destructor of
|
|
|
|
// `PartialVecNonZeroSized` from running. Note that none of the
|
|
|
|
// function calls can fail, thus no resources can be leaked (as the
|
|
|
|
// `vec` member of `PartialVec` is the only one which holds
|
|
|
|
// allocations -- and it is returned from this function. None of
|
|
|
|
// this can fail.
|
|
|
|
unsafe {
|
|
|
|
let vec_len = pv.vec.len();
|
|
|
|
let vec_cap = pv.vec.capacity();
|
|
|
|
let vec_ptr = pv.vec.as_mut_ptr() as *mut U;
|
|
|
|
mem::forget(pv);
|
|
|
|
Vec::from_raw_parts(vec_len, vec_cap, vec_ptr)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Put the `Vec` into the `PartialVecZeroSized` structure and
|
|
|
|
// prevent the destructor of the `Vec` from running. Since the
|
|
|
|
// `Vec` contained zero-sized objects, it did not allocate, so we
|
|
|
|
// are not leaking memory here.
|
|
|
|
let mut pv = PartialVecZeroSized::<T,U> {
|
|
|
|
num_t: vec.len(),
|
|
|
|
num_u: 0,
|
|
|
|
marker_t: InvariantType,
|
|
|
|
marker_u: InvariantType,
|
2014-07-01 15:10:22 +02:00
|
|
|
};
|
2014-09-19 01:38:50 +02:00
|
|
|
unsafe { mem::forget(vec); }
|
|
|
|
|
|
|
|
while pv.num_t != 0 {
|
|
|
|
unsafe {
|
|
|
|
// Create a `T` out of thin air and decrement `num_t`. This
|
|
|
|
// must not fail between these steps, as otherwise a
|
|
|
|
// destructor of `T` which doesn't exist runs.
|
|
|
|
let t = mem::uninitialized();
|
|
|
|
pv.num_t -= 1;
|
|
|
|
|
|
|
|
// The function given by the user might fail.
|
|
|
|
let u = f(t);
|
|
|
|
|
|
|
|
// Forget the `U` and increment `num_u`. This increment
|
|
|
|
// cannot overflow the `uint` as we only do this for a
|
|
|
|
// number of times that fits into a `uint` (and start with
|
|
|
|
// `0`). Again, we should not fail between these steps.
|
|
|
|
mem::forget(u);
|
|
|
|
pv.num_u += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Create a `Vec` from our `PartialVecZeroSized` and make sure the
|
|
|
|
// destructor of the latter will not run. None of this can fail.
|
|
|
|
let mut result = Vec::new();
|
|
|
|
unsafe { result.set_len(pv.num_u); }
|
|
|
|
result
|
2014-07-01 15:10:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-04 07:46:24 +11:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2014-06-20 23:08:17 -04:00
|
|
|
extern crate test;
|
|
|
|
|
2014-05-29 19:03:06 -07:00
|
|
|
use std::prelude::*;
|
|
|
|
use std::mem::size_of;
|
2014-06-20 23:08:17 -04:00
|
|
|
use test::Bencher;
|
2014-06-06 10:27:49 -07:00
|
|
|
use super::{unzip, raw, Vec};
|
2014-03-12 22:01:33 +02:00
|
|
|
|
2014-07-11 10:12:38 -07:00
|
|
|
use MutableSeq;
|
|
|
|
|
2014-03-12 22:01:33 +02:00
|
|
|
#[test]
|
|
|
|
fn test_small_vec_struct() {
|
|
|
|
assert!(size_of::<Vec<u8>>() == size_of::<uint>() * 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_double_drop() {
|
|
|
|
struct TwoVec<T> {
|
|
|
|
x: Vec<T>,
|
|
|
|
y: Vec<T>
|
|
|
|
}
|
|
|
|
|
|
|
|
struct DropCounter<'a> {
|
|
|
|
count: &'a mut int
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unsafe_destructor]
|
|
|
|
impl<'a> Drop for DropCounter<'a> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
*self.count += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-28 11:33:06 -07:00
|
|
|
let (mut count_x, mut count_y) = (0, 0);
|
2014-03-12 22:01:33 +02:00
|
|
|
{
|
|
|
|
let mut tv = TwoVec {
|
|
|
|
x: Vec::new(),
|
|
|
|
y: Vec::new()
|
|
|
|
};
|
|
|
|
tv.x.push(DropCounter {count: &mut count_x});
|
|
|
|
tv.y.push(DropCounter {count: &mut count_y});
|
|
|
|
|
|
|
|
// If Vec had a drop flag, here is where it would be zeroed.
|
|
|
|
// Instead, it should rely on its internal state to prevent
|
|
|
|
// doing anything significant when dropped multiple times.
|
|
|
|
drop(tv.x);
|
|
|
|
|
|
|
|
// Here tv goes out of scope, tv.y should be dropped, but not tv.x.
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(count_x, 1);
|
|
|
|
assert_eq!(count_y, 1);
|
|
|
|
}
|
2014-03-04 07:46:24 +11:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_reserve_additional() {
|
|
|
|
let mut v = Vec::new();
|
|
|
|
assert_eq!(v.capacity(), 0);
|
|
|
|
|
|
|
|
v.reserve_additional(2);
|
|
|
|
assert!(v.capacity() >= 2);
|
|
|
|
|
2014-04-21 17:58:52 -04:00
|
|
|
for i in range(0i, 16) {
|
2014-03-04 07:46:24 +11:00
|
|
|
v.push(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(v.capacity() >= 16);
|
|
|
|
v.reserve_additional(16);
|
|
|
|
assert!(v.capacity() >= 32);
|
|
|
|
|
|
|
|
v.push(16);
|
|
|
|
|
|
|
|
v.reserve_additional(16);
|
|
|
|
assert!(v.capacity() >= 33)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_extend() {
|
|
|
|
let mut v = Vec::new();
|
|
|
|
let mut w = Vec::new();
|
|
|
|
|
2014-04-21 17:58:52 -04:00
|
|
|
v.extend(range(0i, 3));
|
|
|
|
for i in range(0i, 3) { w.push(i) }
|
2014-03-04 07:46:24 +11:00
|
|
|
|
|
|
|
assert_eq!(v, w);
|
|
|
|
|
2014-04-21 17:58:52 -04:00
|
|
|
v.extend(range(3i, 10));
|
|
|
|
for i in range(3i, 10) { w.push(i) }
|
2014-03-04 07:46:24 +11:00
|
|
|
|
|
|
|
assert_eq!(v, w);
|
|
|
|
}
|
2014-03-18 12:52:06 +09:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mut_slice_from() {
|
|
|
|
let mut values = Vec::from_slice([1u8,2,3,4,5]);
|
|
|
|
{
|
2014-09-14 20:27:36 -07:00
|
|
|
let slice = values.slice_from_mut(2);
|
2014-03-18 12:52:06 +09:00
|
|
|
assert!(slice == [3, 4, 5]);
|
2014-09-14 20:27:36 -07:00
|
|
|
for p in slice.iter_mut() {
|
2014-03-18 12:52:06 +09:00
|
|
|
*p += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(values.as_slice() == [1, 2, 5, 6, 7]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mut_slice_to() {
|
|
|
|
let mut values = Vec::from_slice([1u8,2,3,4,5]);
|
|
|
|
{
|
2014-09-14 20:27:36 -07:00
|
|
|
let slice = values.slice_to_mut(2);
|
2014-03-18 12:52:06 +09:00
|
|
|
assert!(slice == [1, 2]);
|
2014-09-14 20:27:36 -07:00
|
|
|
for p in slice.iter_mut() {
|
2014-03-18 12:52:06 +09:00
|
|
|
*p += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(values.as_slice() == [2, 3, 3, 4, 5]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_mut_split_at() {
|
|
|
|
let mut values = Vec::from_slice([1u8,2,3,4,5]);
|
|
|
|
{
|
2014-09-14 20:27:36 -07:00
|
|
|
let (left, right) = values.split_at_mut(2);
|
2014-09-24 23:41:09 +12:00
|
|
|
{
|
|
|
|
let left: &[_] = left;
|
|
|
|
assert!(left[0..left.len()] == [1, 2]);
|
|
|
|
}
|
2014-09-14 20:27:36 -07:00
|
|
|
for p in left.iter_mut() {
|
2014-03-18 12:52:06 +09:00
|
|
|
*p += 1;
|
|
|
|
}
|
|
|
|
|
2014-09-24 23:41:09 +12:00
|
|
|
{
|
|
|
|
let right: &[_] = right;
|
|
|
|
assert!(right[0..right.len()] == [3, 4, 5]);
|
|
|
|
}
|
2014-09-14 20:27:36 -07:00
|
|
|
for p in right.iter_mut() {
|
2014-03-18 12:52:06 +09:00
|
|
|
*p += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(values == Vec::from_slice([2u8, 3, 5, 6, 7]));
|
|
|
|
}
|
2014-04-03 22:28:45 +11:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_clone() {
|
|
|
|
let v: Vec<int> = vec!();
|
2014-04-21 17:58:52 -04:00
|
|
|
let w = vec!(1i, 2, 3);
|
2014-04-03 22:28:45 +11:00
|
|
|
|
|
|
|
assert_eq!(v, v.clone());
|
|
|
|
|
|
|
|
let z = w.clone();
|
|
|
|
assert_eq!(w, z);
|
|
|
|
// they should be disjoint in memory.
|
|
|
|
assert!(w.as_ptr() != z.as_ptr())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_clone_from() {
|
|
|
|
let mut v = vec!();
|
2014-04-21 17:58:52 -04:00
|
|
|
let three = vec!(box 1i, box 2, box 3);
|
|
|
|
let two = vec!(box 4i, box 5);
|
2014-04-03 22:28:45 +11:00
|
|
|
// zero, long
|
|
|
|
v.clone_from(&three);
|
|
|
|
assert_eq!(v, three);
|
|
|
|
|
|
|
|
// equal
|
|
|
|
v.clone_from(&three);
|
|
|
|
assert_eq!(v, three);
|
|
|
|
|
|
|
|
// long, short
|
|
|
|
v.clone_from(&two);
|
|
|
|
assert_eq!(v, two);
|
|
|
|
|
|
|
|
// short, long
|
|
|
|
v.clone_from(&three);
|
|
|
|
assert_eq!(v, three)
|
|
|
|
}
|
2014-04-02 23:10:36 -04:00
|
|
|
|
2014-04-07 13:30:48 -07:00
|
|
|
#[test]
|
2014-04-02 23:10:36 -04:00
|
|
|
fn test_grow_fn() {
|
|
|
|
let mut v = Vec::from_slice([0u, 1]);
|
|
|
|
v.grow_fn(3, |i| i);
|
|
|
|
assert!(v == Vec::from_slice([0u, 1, 0, 1, 2]));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_retain() {
|
|
|
|
let mut vec = Vec::from_slice([1u, 2, 3, 4]);
|
|
|
|
vec.retain(|x| x%2 == 0);
|
|
|
|
assert!(vec == Vec::from_slice([2u, 4]));
|
|
|
|
}
|
2014-04-11 14:34:21 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn zero_sized_values() {
|
|
|
|
let mut v = Vec::new();
|
|
|
|
assert_eq!(v.len(), 0);
|
|
|
|
v.push(());
|
|
|
|
assert_eq!(v.len(), 1);
|
|
|
|
v.push(());
|
|
|
|
assert_eq!(v.len(), 2);
|
|
|
|
assert_eq!(v.pop(), Some(()));
|
|
|
|
assert_eq!(v.pop(), Some(()));
|
|
|
|
assert_eq!(v.pop(), None);
|
|
|
|
|
2014-06-05 23:18:51 -07:00
|
|
|
assert_eq!(v.iter().count(), 0);
|
2014-04-11 14:34:21 -07:00
|
|
|
v.push(());
|
2014-06-05 23:18:51 -07:00
|
|
|
assert_eq!(v.iter().count(), 1);
|
2014-04-11 14:34:21 -07:00
|
|
|
v.push(());
|
2014-06-05 23:18:51 -07:00
|
|
|
assert_eq!(v.iter().count(), 2);
|
2014-04-11 14:34:21 -07:00
|
|
|
|
|
|
|
for &() in v.iter() {}
|
|
|
|
|
2014-09-14 20:27:36 -07:00
|
|
|
assert_eq!(v.iter_mut().count(), 2);
|
2014-04-11 14:34:21 -07:00
|
|
|
v.push(());
|
2014-09-14 20:27:36 -07:00
|
|
|
assert_eq!(v.iter_mut().count(), 3);
|
2014-04-11 14:34:21 -07:00
|
|
|
v.push(());
|
2014-09-14 20:27:36 -07:00
|
|
|
assert_eq!(v.iter_mut().count(), 4);
|
2014-04-11 14:34:21 -07:00
|
|
|
|
2014-09-14 20:27:36 -07:00
|
|
|
for &() in v.iter_mut() {}
|
2014-04-11 14:34:21 -07:00
|
|
|
unsafe { v.set_len(0); }
|
2014-09-14 20:27:36 -07:00
|
|
|
assert_eq!(v.iter_mut().count(), 0);
|
2014-04-11 14:34:21 -07:00
|
|
|
}
|
2014-05-03 16:13:35 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_partition() {
|
|
|
|
assert_eq!(vec![].partition(|x: &int| *x < 3), (vec![], vec![]));
|
2014-04-21 17:58:52 -04: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-03 16:13:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_partitioned() {
|
2014-05-08 12:03:33 -07:00
|
|
|
assert_eq!(vec![].partitioned(|x: &int| *x < 3), (vec![], vec![]))
|
2014-04-21 17:58:52 -04:00
|
|
|
assert_eq!(vec![1i, 2, 3].partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
|
|
|
|
assert_eq!(vec![1i, 2, 3].partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
|
|
|
|
assert_eq!(vec![1i, 2, 3].partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
|
2014-05-03 16:13:35 -07:00
|
|
|
}
|
2014-05-03 18:10:04 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_zip_unzip() {
|
2014-04-21 17:58:52 -04:00
|
|
|
let z1 = vec![(1i, 4i), (2, 5), (3, 6)];
|
2014-05-03 18:10:04 -07:00
|
|
|
|
|
|
|
let (left, right) = unzip(z1.iter().map(|&x| x));
|
|
|
|
|
|
|
|
let (left, right) = (left.as_slice(), right.as_slice());
|
|
|
|
assert_eq!((1, 4), (left[0], right[0]));
|
|
|
|
assert_eq!((2, 5), (left[1], right[1]));
|
|
|
|
assert_eq!((3, 6), (left[2], right[2]));
|
|
|
|
}
|
2014-05-03 18:20:35 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_unsafe_ptrs() {
|
|
|
|
unsafe {
|
|
|
|
// Test on-stack copy-from-buf.
|
2014-04-21 17:58:52 -04:00
|
|
|
let a = [1i, 2, 3];
|
2014-05-03 18:20:35 -07:00
|
|
|
let ptr = a.as_ptr();
|
|
|
|
let b = raw::from_buf(ptr, 3u);
|
|
|
|
assert_eq!(b, vec![1, 2, 3]);
|
|
|
|
|
|
|
|
// Test on-heap copy-from-buf.
|
2014-04-21 17:58:52 -04:00
|
|
|
let c = vec![1i, 2, 3, 4, 5];
|
2014-05-03 18:20:35 -07:00
|
|
|
let ptr = c.as_ptr();
|
|
|
|
let d = raw::from_buf(ptr, 5u);
|
|
|
|
assert_eq!(d, vec![1, 2, 3, 4, 5]);
|
|
|
|
}
|
|
|
|
}
|
2014-05-06 20:14:54 -07:00
|
|
|
|
2014-05-14 14:57:27 -07:00
|
|
|
#[test]
|
|
|
|
fn test_vec_truncate_drop() {
|
|
|
|
static mut drops: uint = 0;
|
|
|
|
struct Elem(int);
|
|
|
|
impl Drop for Elem {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe { drops += 1; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
|
|
|
|
assert_eq!(unsafe { drops }, 0);
|
|
|
|
v.truncate(3);
|
|
|
|
assert_eq!(unsafe { drops }, 2);
|
|
|
|
v.truncate(0);
|
|
|
|
assert_eq!(unsafe { drops }, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_vec_truncate_fail() {
|
|
|
|
struct BadElem(int);
|
|
|
|
impl Drop for BadElem {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
let BadElem(ref mut x) = *self;
|
|
|
|
if *x == 0xbadbeef {
|
|
|
|
fail!("BadElem failure: 0xbadbeef")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
|
|
|
|
v.truncate(0);
|
|
|
|
}
|
2014-06-02 21:56:29 -07:00
|
|
|
|
2014-07-14 11:03:23 +12:00
|
|
|
#[test]
|
|
|
|
fn test_index() {
|
|
|
|
let vec = vec!(1i, 2, 3);
|
|
|
|
assert!(vec[1] == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_index_out_of_bounds() {
|
|
|
|
let vec = vec!(1i, 2, 3);
|
|
|
|
let _ = vec[3];
|
|
|
|
}
|
|
|
|
|
2014-09-15 20:48:58 +12:00
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_slice_out_of_bounds_1() {
|
|
|
|
let x: Vec<int> = vec![1, 2, 3, 4, 5];
|
|
|
|
x[-1..];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_slice_out_of_bounds_2() {
|
|
|
|
let x: Vec<int> = vec![1, 2, 3, 4, 5];
|
|
|
|
x[..6];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_slice_out_of_bounds_3() {
|
|
|
|
let x: Vec<int> = vec![1, 2, 3, 4, 5];
|
|
|
|
x[-1..4];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_slice_out_of_bounds_4() {
|
|
|
|
let x: Vec<int> = vec![1, 2, 3, 4, 5];
|
|
|
|
x[1..6];
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
|
|
|
fn test_slice_out_of_bounds_5() {
|
|
|
|
let x: Vec<int> = vec![1, 2, 3, 4, 5];
|
|
|
|
x[3..2];
|
|
|
|
}
|
|
|
|
|
2014-08-02 14:36:51 -04:00
|
|
|
#[test]
|
|
|
|
fn test_swap_remove_empty() {
|
|
|
|
let mut vec: Vec<uint> = vec!();
|
|
|
|
assert_eq!(vec.swap_remove(0), None);
|
|
|
|
}
|
|
|
|
|
2014-08-31 15:29:22 +02:00
|
|
|
#[test]
|
|
|
|
fn test_move_iter_unwrap() {
|
|
|
|
let mut vec: Vec<uint> = Vec::with_capacity(7);
|
|
|
|
vec.push(1);
|
|
|
|
vec.push(2);
|
|
|
|
let ptr = vec.as_ptr();
|
2014-09-14 20:27:36 -07:00
|
|
|
vec = vec.into_iter().unwrap();
|
2014-08-31 15:29:22 +02:00
|
|
|
assert_eq!(vec.as_ptr(), ptr);
|
|
|
|
assert_eq!(vec.capacity(), 7);
|
|
|
|
assert_eq!(vec.len(), 0);
|
2014-09-13 01:38:16 +02:00
|
|
|
}
|
2014-07-01 15:10:22 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_fail]
|
2014-09-19 01:38:50 +02:00
|
|
|
fn test_map_in_place_incompatible_types_fail() {
|
2014-07-01 15:10:22 +02:00
|
|
|
let v = vec![0u, 1, 2];
|
2014-09-11 02:04:51 +02:00
|
|
|
v.map_in_place(|_| ());
|
2014-07-01 15:10:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2014-09-11 02:04:51 +02:00
|
|
|
fn test_map_in_place() {
|
2014-07-01 15:10:22 +02:00
|
|
|
let v = vec![0u, 1, 2];
|
2014-09-14 21:33:48 +02:00
|
|
|
assert_eq!(v.map_in_place(|i: uint| i as int - 1).as_slice(), [-1i, 0, 1].as_slice());
|
2014-08-31 15:29:22 +02:00
|
|
|
}
|
|
|
|
|
2014-09-19 01:38:50 +02:00
|
|
|
#[test]
|
|
|
|
fn test_map_in_place_zero_sized() {
|
|
|
|
let v = vec![(), ()];
|
|
|
|
#[deriving(PartialEq, Show)]
|
|
|
|
struct ZeroSized;
|
|
|
|
assert_eq!(v.map_in_place(|_| ZeroSized).as_slice(), [ZeroSized, ZeroSized].as_slice());
|
|
|
|
}
|
|
|
|
|
2014-10-02 11:19:47 -04:00
|
|
|
#[test]
|
|
|
|
fn test_move_items() {
|
|
|
|
let mut vec = vec!(1i, 2, 3);
|
|
|
|
let mut vec2 : Vec<int> = vec!();
|
2014-10-02 14:06:31 -04:00
|
|
|
for i in vec.into_iter() {
|
2014-10-02 11:19:47 -04:00
|
|
|
vec2.push(i);
|
|
|
|
}
|
|
|
|
assert!(vec2 == vec!(1i, 2, 3));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_move_items_reverse() {
|
|
|
|
let mut vec = vec!(1i, 2, 3);
|
|
|
|
let mut vec2 : Vec<int> = vec!();
|
2014-10-02 14:06:31 -04:00
|
|
|
for i in vec.into_iter().rev() {
|
2014-10-02 11:19:47 -04:00
|
|
|
vec2.push(i);
|
|
|
|
}
|
|
|
|
assert!(vec2 == vec!(3i, 2, 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_move_items_zero_sized() {
|
|
|
|
let mut vec = vec!((), (), ());
|
|
|
|
let mut vec2 : Vec<()> = vec!();
|
2014-10-02 14:06:31 -04:00
|
|
|
for i in vec.into_iter() {
|
2014-10-02 11:19:47 -04:00
|
|
|
vec2.push(i);
|
|
|
|
}
|
|
|
|
assert!(vec2 == vec!((), (), ()));
|
|
|
|
}
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
#[bench]
|
|
|
|
fn bench_new(b: &mut Bencher) {
|
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let v: Vec<uint> = Vec::new();
|
|
|
|
assert_eq!(v.len(), 0);
|
2014-06-02 21:56:29 -07:00
|
|
|
assert_eq!(v.capacity(), 0);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-07-05 23:07:28 -07:00
|
|
|
fn do_bench_with_capacity(b: &mut Bencher, src_len: uint) {
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let v: Vec<uint> = Vec::with_capacity(src_len);
|
|
|
|
assert_eq!(v.len(), 0);
|
|
|
|
assert_eq!(v.capacity(), src_len);
|
2014-06-02 21:56:29 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-07-05 23:07:28 -07:00
|
|
|
#[bench]
|
|
|
|
fn bench_with_capacity_0000(b: &mut Bencher) {
|
|
|
|
do_bench_with_capacity(b, 0)
|
|
|
|
}
|
2014-06-02 21:56:29 -07:00
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_with_capacity_0010(b: &mut Bencher) {
|
|
|
|
do_bench_with_capacity(b, 10)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_with_capacity_0100(b: &mut Bencher) {
|
|
|
|
do_bench_with_capacity(b, 100)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_with_capacity_1000(b: &mut Bencher) {
|
|
|
|
do_bench_with_capacity(b, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_from_fn(b: &mut Bencher, src_len: uint) {
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let dst = Vec::from_fn(src_len, |i| i);
|
|
|
|
assert_eq!(dst.len(), src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
|
2014-06-02 21:56:29 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_from_fn_0000(b: &mut Bencher) {
|
|
|
|
do_bench_from_fn(b, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_fn_0010(b: &mut Bencher) {
|
|
|
|
do_bench_from_fn(b, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_fn_0100(b: &mut Bencher) {
|
|
|
|
do_bench_from_fn(b, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_fn_1000(b: &mut Bencher) {
|
|
|
|
do_bench_from_fn(b, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_from_elem(b: &mut Bencher, src_len: uint) {
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let dst: Vec<uint> = Vec::from_elem(src_len, 5);
|
|
|
|
assert_eq!(dst.len(), src_len);
|
|
|
|
assert!(dst.iter().all(|x| *x == 5));
|
2014-06-02 21:56:29 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_from_elem_0000(b: &mut Bencher) {
|
|
|
|
do_bench_from_elem(b, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_elem_0010(b: &mut Bencher) {
|
|
|
|
do_bench_from_elem(b, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_elem_0100(b: &mut Bencher) {
|
|
|
|
do_bench_from_elem(b, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_elem_1000(b: &mut Bencher) {
|
|
|
|
do_bench_from_elem(b, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_from_slice(b: &mut Bencher, src_len: uint) {
|
|
|
|
let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
|
|
|
|
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let dst = Vec::from_slice(src.clone().as_slice());
|
|
|
|
assert_eq!(dst.len(), src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_slice_0000(b: &mut Bencher) {
|
|
|
|
do_bench_from_slice(b, 0)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_from_slice_0010(b: &mut Bencher) {
|
|
|
|
do_bench_from_slice(b, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_slice_0100(b: &mut Bencher) {
|
|
|
|
do_bench_from_slice(b, 100)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_from_slice_1000(b: &mut Bencher) {
|
|
|
|
do_bench_from_slice(b, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_from_iter(b: &mut Bencher, src_len: uint) {
|
|
|
|
let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
|
|
|
|
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-09-14 20:27:36 -07:00
|
|
|
let dst: Vec<uint> = FromIterator::from_iter(src.clone().into_iter());
|
2014-07-05 23:07:28 -07:00
|
|
|
assert_eq!(dst.len(), src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_iter_0000(b: &mut Bencher) {
|
|
|
|
do_bench_from_iter(b, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_from_iter_0010(b: &mut Bencher) {
|
|
|
|
do_bench_from_iter(b, 10)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_from_iter_0100(b: &mut Bencher) {
|
|
|
|
do_bench_from_iter(b, 100)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_from_iter_1000(b: &mut Bencher) {
|
|
|
|
do_bench_from_iter(b, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_extend(b: &mut Bencher, dst_len: uint, src_len: uint) {
|
|
|
|
let dst: Vec<uint> = FromIterator::from_iter(range(0, dst_len));
|
|
|
|
let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
|
|
|
|
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let mut dst = dst.clone();
|
2014-09-14 20:27:36 -07:00
|
|
|
dst.extend(src.clone().into_iter());
|
2014-07-05 23:07:28 -07:00
|
|
|
assert_eq!(dst.len(), dst_len + src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_extend_0000_0000(b: &mut Bencher) {
|
|
|
|
do_bench_extend(b, 0, 0)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_extend_0000_0010(b: &mut Bencher) {
|
|
|
|
do_bench_extend(b, 0, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_extend_0000_0100(b: &mut Bencher) {
|
|
|
|
do_bench_extend(b, 0, 100)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_extend_0000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_extend(b, 0, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_extend_0010_0010(b: &mut Bencher) {
|
|
|
|
do_bench_extend(b, 10, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_extend_0100_0100(b: &mut Bencher) {
|
|
|
|
do_bench_extend(b, 100, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_extend_1000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_extend(b, 1000, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_push_all(b: &mut Bencher, dst_len: uint, src_len: uint) {
|
|
|
|
let dst: Vec<uint> = FromIterator::from_iter(range(0, dst_len));
|
|
|
|
let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
|
|
|
|
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let mut dst = dst.clone();
|
|
|
|
dst.push_all(src.as_slice());
|
|
|
|
assert_eq!(dst.len(), dst_len + src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_0000_0000(b: &mut Bencher) {
|
|
|
|
do_bench_push_all(b, 0, 0)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_push_all_0000_0010(b: &mut Bencher) {
|
|
|
|
do_bench_push_all(b, 0, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_0000_0100(b: &mut Bencher) {
|
|
|
|
do_bench_push_all(b, 0, 100)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_push_all_0000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_push_all(b, 0, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_0010_0010(b: &mut Bencher) {
|
|
|
|
do_bench_push_all(b, 10, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_0100_0100(b: &mut Bencher) {
|
|
|
|
do_bench_push_all(b, 100, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_1000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_push_all(b, 1000, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_push_all_move(b: &mut Bencher, dst_len: uint, src_len: uint) {
|
|
|
|
let dst: Vec<uint> = FromIterator::from_iter(range(0u, dst_len));
|
|
|
|
let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
|
|
|
|
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let mut dst = dst.clone();
|
|
|
|
dst.push_all_move(src.clone());
|
|
|
|
assert_eq!(dst.len(), dst_len + src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_move_0000_0000(b: &mut Bencher) {
|
|
|
|
do_bench_push_all_move(b, 0, 0)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_push_all_move_0000_0010(b: &mut Bencher) {
|
|
|
|
do_bench_push_all_move(b, 0, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_move_0000_0100(b: &mut Bencher) {
|
|
|
|
do_bench_push_all_move(b, 0, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_move_0000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_push_all_move(b, 0, 1000)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_push_all_move_0010_0010(b: &mut Bencher) {
|
|
|
|
do_bench_push_all_move(b, 10, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_move_0100_0100(b: &mut Bencher) {
|
|
|
|
do_bench_push_all_move(b, 100, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_push_all_move_1000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_push_all_move(b, 1000, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_bench_clone(b: &mut Bencher, src_len: uint) {
|
|
|
|
let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
|
|
|
|
|
|
|
|
b.bytes = src_len as u64;
|
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let dst = src.clone();
|
|
|
|
assert_eq!(dst.len(), src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
|
|
|
|
});
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-05 23:07:28 -07:00
|
|
|
fn bench_clone_0000(b: &mut Bencher) {
|
|
|
|
do_bench_clone(b, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_0010(b: &mut Bencher) {
|
|
|
|
do_bench_clone(b, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone(b, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_1000(b: &mut Bencher) {
|
|
|
|
do_bench_clone(b, 1000)
|
|
|
|
}
|
|
|
|
|
2014-07-07 09:07:49 -07:00
|
|
|
fn do_bench_clone_from(b: &mut Bencher, times: uint, dst_len: uint, src_len: uint) {
|
2014-07-05 23:07:28 -07:00
|
|
|
let dst: Vec<uint> = FromIterator::from_iter(range(0, src_len));
|
|
|
|
let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
|
|
|
|
|
2014-07-07 09:07:49 -07:00
|
|
|
b.bytes = (times * src_len) as u64;
|
2014-07-05 23:07:28 -07:00
|
|
|
|
2014-06-02 21:56:29 -07:00
|
|
|
b.iter(|| {
|
2014-07-05 23:07:28 -07:00
|
|
|
let mut dst = dst.clone();
|
2014-07-07 09:07:49 -07:00
|
|
|
|
|
|
|
for _ in range(0, times) {
|
|
|
|
dst.clone_from(&src);
|
|
|
|
|
|
|
|
assert_eq!(dst.len(), src_len);
|
|
|
|
assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
|
|
|
|
}
|
2014-07-05 23:07:28 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 0, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 0, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 0, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 0, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 10, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 100, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 1000, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 10, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 100, 1000)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 10, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 100, 10)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 1, 1000, 100)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 0, 0)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 0, 10)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 0, 100)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 0, 1000)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 10, 10)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 100, 100)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 1000, 1000)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 10, 100)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 100, 1000)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 10, 0)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 100, 10)
|
2014-07-05 23:07:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2014-07-07 09:07:49 -07:00
|
|
|
fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
|
|
|
|
do_bench_clone_from(b, 10, 1000, 100)
|
2014-06-02 21:56:29 -07:00
|
|
|
}
|
2014-03-04 07:46:24 +11:00
|
|
|
}
|