2014-04-30 22:54:25 -07:00
|
|
|
// Copyright 2012-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.
|
|
|
|
|
|
|
|
//! Slice management and manipulation
|
|
|
|
//!
|
|
|
|
//! For more details `std::slice`.
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#![stable]
|
2014-05-28 19:53:37 -07:00
|
|
|
#![doc(primitive = "slice")]
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
// How this module is organized.
|
|
|
|
//
|
|
|
|
// The library infrastructure for slices is fairly messy. There's
|
|
|
|
// a lot of stuff defined here. Let's keep it clean.
|
|
|
|
//
|
|
|
|
// Since slices don't support inherent methods; all operations
|
|
|
|
// on them are defined on traits, which are then reexported from
|
|
|
|
// the prelude for convenience. So there are a lot of traits here.
|
|
|
|
//
|
|
|
|
// The layout of this file is thus:
|
|
|
|
//
|
|
|
|
// * Slice-specific 'extension' traits and their implementations. This
|
|
|
|
// is where most of the slice API resides.
|
|
|
|
// * Implementations of a few common traits with important slice ops.
|
|
|
|
// * Definitions of a bunch of iterators.
|
|
|
|
// * Free functions.
|
|
|
|
// * The `raw` and `bytes` submodules.
|
|
|
|
// * Boilerplate trait implementations.
|
|
|
|
|
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
|
|
|
use mem::transmute;
|
2014-04-30 22:54:25 -07:00
|
|
|
use clone::Clone;
|
2014-11-28 11:57:41 -05:00
|
|
|
use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord, Equiv};
|
|
|
|
use cmp::Ordering::{Less, Equal, Greater};
|
2014-04-30 22:54:25 -07:00
|
|
|
use cmp;
|
|
|
|
use default::Default;
|
|
|
|
use iter::*;
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
use kinds::Copy;
|
2014-11-18 20:22:13 -08:00
|
|
|
use num::Int;
|
2014-12-04 23:47:40 -05:00
|
|
|
use ops::{FnMut, mod};
|
2014-11-28 11:57:41 -05:00
|
|
|
use option::Option;
|
|
|
|
use option::Option::{None, Some};
|
2014-04-30 22:54:25 -07:00
|
|
|
use ptr;
|
|
|
|
use ptr::RawPtr;
|
|
|
|
use mem;
|
|
|
|
use mem::size_of;
|
2014-10-23 10:43:18 -05:00
|
|
|
use kinds::{Sized, marker};
|
2014-08-07 18:30:03 -07:00
|
|
|
use raw::Repr;
|
2014-08-06 20:03:55 -07:00
|
|
|
// Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
|
2014-08-18 08:29:44 -07:00
|
|
|
use raw::Slice as RawSlice;
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-08-06 20:48:25 -07:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
|
|
|
// Extension traits
|
|
|
|
//
|
|
|
|
|
2014-11-02 17:04:32 -08:00
|
|
|
/// Extension methods for slices.
|
|
|
|
#[unstable = "may merge with other traits"]
|
|
|
|
pub trait SlicePrelude<T> for Sized? {
|
2014-10-02 11:47:58 -07:00
|
|
|
/// Returns a subslice spanning the interval [`start`, `end`).
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics when the end of the new slice lies beyond the end of the
|
2014-10-02 11:47:58 -07:00
|
|
|
/// original slice (i.e. when `end > self.len()`) or when `start > end`.
|
|
|
|
///
|
|
|
|
/// Slicing with `start` equal to `end` yields an empty slice.
|
2014-09-24 23:41:09 +12:00
|
|
|
#[unstable = "waiting on final error conventions/slicing syntax"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T];
|
2014-10-02 11:47:58 -07:00
|
|
|
|
|
|
|
/// Returns a subslice from `start` to the end of the slice.
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics when `start` is strictly greater than the length of the original slice.
|
2014-10-02 11:47:58 -07:00
|
|
|
///
|
|
|
|
/// Slicing from `self.len()` yields an empty slice.
|
2014-09-24 23:41:09 +12:00
|
|
|
#[unstable = "waiting on final error conventions/slicing syntax"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_from<'a>(&'a self, start: uint) -> &'a [T];
|
2014-10-02 11:47:58 -07:00
|
|
|
|
|
|
|
/// Returns a subslice from the start of the slice to `end`.
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics when `end` is strictly greater than the length of the original slice.
|
2014-10-02 11:47:58 -07:00
|
|
|
///
|
|
|
|
/// Slicing to `0` yields an empty slice.
|
2014-09-24 23:41:09 +12:00
|
|
|
#[unstable = "waiting on final error conventions/slicing syntax"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_to<'a>(&'a self, end: uint) -> &'a [T];
|
2014-10-02 11:47:58 -07:00
|
|
|
|
2014-08-01 22:59:54 -04:00
|
|
|
/// Divides one slice into two at an index.
|
|
|
|
///
|
|
|
|
/// The first will contain all indices from `[0, mid)` (excluding
|
|
|
|
/// the index `mid` itself) and the second will contain all
|
|
|
|
/// indices from `[mid, len)` (excluding the index `len` itself).
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics if `mid > len`.
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "waiting on final error conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]);
|
2014-08-01 22:59:54 -04:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns an iterator over the slice
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "iterator type may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn iter<'a>(&'a self) -> Items<'a, T>;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns an iterator over subslices separated by elements that match
|
|
|
|
/// `pred`. The matched element is not contained in the subslices.
|
|
|
|
#[unstable = "iterator type may change, waiting on unboxed closures"]
|
2014-12-04 23:47:40 -05:00
|
|
|
fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where
|
|
|
|
P: FnMut(&T) -> bool;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns an iterator over subslices separated by elements that match
|
|
|
|
/// `pred`, limited to splitting at most `n` times. The matched element is
|
|
|
|
/// not contained in the subslices.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "iterator type may change"]
|
2014-12-04 23:47:40 -05:00
|
|
|
fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns an iterator over subslices separated by elements that match
|
|
|
|
/// `pred` limited to splitting at most `n` times. This starts at the end of
|
|
|
|
/// the slice and works backwards. The matched element is not contained in
|
|
|
|
/// the subslices.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "iterator type may change"]
|
2014-12-04 23:47:40 -05:00
|
|
|
fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool;
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns an iterator over all contiguous windows of length
|
|
|
|
/// `size`. The windows overlap. If the slice is shorter than
|
|
|
|
/// `size`, the iterator returns no values.
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// # Panics
|
2014-09-22 16:23:00 -07:00
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics if `size` is 0.
|
2014-09-22 16:23:00 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`,
|
|
|
|
/// `[3,4]`):
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let v = &[1i, 2, 3, 4];
|
|
|
|
/// for win in v.windows(2) {
|
|
|
|
/// println!("{}", win);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "iterator type may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns an iterator over `size` elements of the slice at a
|
|
|
|
/// time. The chunks do not overlap. If `size` does not divide the
|
|
|
|
/// length of the slice, then the last chunk will not have length
|
|
|
|
/// `size`.
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// # Panics
|
2014-09-22 16:23:00 -07:00
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics if `size` is 0.
|
2014-09-22 16:23:00 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// Print the slice two elements at a time (i.e. `[1,2]`,
|
|
|
|
/// `[3,4]`, `[5]`):
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let v = &[1i, 2, 3, 4, 5];
|
|
|
|
/// for win in v.chunks(2) {
|
|
|
|
/// println!("{}", win);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "iterator type may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>;
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns the element of a slice at the given index, or `None` if the
|
|
|
|
/// index is out of bounds.
|
|
|
|
#[unstable = "waiting on final collection conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn get<'a>(&'a self, index: uint) -> Option<&'a T>;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns the first element of a slice, or `None` if it is empty.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn head<'a>(&'a self) -> Option<&'a T>;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns all but the first element of a slice.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn tail<'a>(&'a self) -> &'a [T];
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns all but the last element of a slice.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn init<'a>(&'a self) -> &'a [T];
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns the last element of a slice, or `None` if it is empty.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn last<'a>(&'a self) -> Option<&'a T>;
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2014-08-06 20:08:16 -07:00
|
|
|
/// Returns a pointer to the element at the given index, without doing
|
|
|
|
/// bounds checking.
|
|
|
|
#[unstable]
|
2014-10-23 10:43:18 -05:00
|
|
|
unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T;
|
2014-08-06 20:08:16 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns an unsafe pointer to the slice's buffer
|
|
|
|
///
|
|
|
|
/// The caller must ensure that the slice outlives the pointer this
|
|
|
|
/// function returns, or else it will end up pointing to garbage.
|
|
|
|
///
|
|
|
|
/// Modifying the slice may cause its buffer to be reallocated, which
|
|
|
|
/// would also make any pointers to it invalid.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn as_ptr(&self) -> *const T;
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Binary search a sorted slice with a comparator function.
|
2014-08-07 18:30:03 -07:00
|
|
|
///
|
|
|
|
/// The comparator function should implement an order consistent
|
2014-09-22 16:23:00 -07:00
|
|
|
/// with the sort order of the underlying slice, returning an
|
2014-08-07 18:30:03 -07:00
|
|
|
/// order code that indicates whether its argument is `Less`,
|
|
|
|
/// `Equal` or `Greater` the desired target.
|
|
|
|
///
|
2014-10-06 15:46:09 +02:00
|
|
|
/// If a matching value is found then returns `Found`, containing
|
|
|
|
/// the index for the matched element; if no match is found then
|
2014-08-07 18:30:03 -07:00
|
|
|
/// `NotFound` is returned, containing the index where a matching
|
|
|
|
/// element could be inserted while maintaining sorted order.
|
2014-10-06 15:46:09 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// Looks up a series of four elements. The first is found, with a
|
|
|
|
/// uniquely determined position; the second and third are not
|
|
|
|
/// found; the fourth could match any position in `[1,4]`.
|
|
|
|
///
|
|
|
|
/// ```rust
|
2014-11-24 15:54:14 -08:00
|
|
|
/// use std::slice::BinarySearchResult::{Found, NotFound};
|
2014-10-06 15:46:09 +02:00
|
|
|
/// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
|
|
|
|
/// let s = s.as_slice();
|
|
|
|
///
|
|
|
|
/// let seek = 13;
|
|
|
|
/// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), Found(9));
|
|
|
|
/// let seek = 4;
|
|
|
|
/// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(7));
|
|
|
|
/// let seek = 100;
|
|
|
|
/// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(13));
|
|
|
|
/// let seek = 1;
|
|
|
|
/// let r = s.binary_search(|probe| probe.cmp(&seek));
|
|
|
|
/// assert!(match r { Found(1...4) => true, _ => false, });
|
|
|
|
/// ```
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "waiting on unboxed closures"]
|
2014-12-05 02:04:33 -05:00
|
|
|
fn binary_search<F>(&self, f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering;
|
2014-10-30 13:43:24 -07:00
|
|
|
|
|
|
|
/// Return the number of elements in the slice
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let a = [1i, 2, 3];
|
|
|
|
/// assert_eq!(a.len(), 3);
|
|
|
|
/// ```
|
|
|
|
#[experimental = "not triaged yet"]
|
|
|
|
fn len(&self) -> uint;
|
|
|
|
|
|
|
|
/// Returns true if the slice has a length of 0
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let a = [1i, 2, 3];
|
|
|
|
/// assert!(!a.is_empty());
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[experimental = "not triaged yet"]
|
|
|
|
fn is_empty(&self) -> bool { self.len() == 0 }
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Returns a mutable reference to the element at the given index,
|
|
|
|
/// or `None` if the index is out of bounds
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "waiting on final error conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>;
|
2014-11-02 17:04:32 -08:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Work with `self` as a mut slice.
|
|
|
|
/// Primarily intended for getting a &mut [T] from a [T, ..N].
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T];
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-10-02 11:47:58 -07:00
|
|
|
/// Returns a mutable subslice spanning the interval [`start`, `end`).
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics when the end of the new slice lies beyond the end of the
|
2014-10-02 11:47:58 -07:00
|
|
|
/// original slice (i.e. when `end > self.len()`) or when `start > end`.
|
|
|
|
///
|
|
|
|
/// Slicing with `start` equal to `end` yields an empty slice.
|
|
|
|
#[unstable = "waiting on final error conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T];
|
2014-10-02 11:47:58 -07:00
|
|
|
|
|
|
|
/// Returns a mutable subslice from `start` to the end of the slice.
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics when `start` is strictly greater than the length of the original slice.
|
2014-10-02 11:47:58 -07:00
|
|
|
///
|
|
|
|
/// Slicing from `self.len()` yields an empty slice.
|
|
|
|
#[unstable = "waiting on final error conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T];
|
2014-10-02 11:47:58 -07:00
|
|
|
|
|
|
|
/// Returns a mutable subslice from the start of the slice to `end`.
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics when `end` is strictly greater than the length of the original slice.
|
2014-10-02 11:47:58 -07:00
|
|
|
///
|
|
|
|
/// Slicing to `0` yields an empty slice.
|
|
|
|
#[unstable = "waiting on final error conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T];
|
2014-10-02 11:47:58 -07:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Returns an iterator that allows modifying each value
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "waiting on iterator type name conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T>;
|
2014-09-14 15:57:55 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
|
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn head_mut<'a>(&'a mut self) -> Option<&'a mut T>;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns all but the first element of a mutable slice
|
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn tail_mut<'a>(&'a mut self) -> &'a mut [T];
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns all but the last element of a mutable slice
|
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn init_mut<'a>(&'a mut self) -> &'a mut [T];
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns a mutable pointer to the last item in the slice.
|
|
|
|
#[unstable = "name may change"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>;
|
2014-09-14 15:57:55 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns an iterator over mutable subslices separated by elements that
|
|
|
|
/// match `pred`. The matched element is not contained in the subslices.
|
|
|
|
#[unstable = "waiting on unboxed closures, iterator type name conventions"]
|
2014-12-05 01:00:50 -05:00
|
|
|
fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where
|
|
|
|
P: FnMut(&T) -> bool;
|
2014-09-14 15:57:55 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns an iterator over subslices separated by elements that match
|
|
|
|
/// `pred`, limited to splitting at most `n` times. The matched element is
|
|
|
|
/// not contained in the subslices.
|
|
|
|
#[unstable = "waiting on unboxed closures, iterator type name conventions"]
|
2014-12-05 01:00:50 -05:00
|
|
|
fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns an iterator over subslices separated by elements that match
|
|
|
|
/// `pred` limited to splitting at most `n` times. This starts at the end of
|
|
|
|
/// the slice and works backwards. The matched element is not contained in
|
|
|
|
/// the subslices.
|
|
|
|
#[unstable = "waiting on unboxed closures, iterator type name conventions"]
|
2014-12-05 01:00:50 -05:00
|
|
|
fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool;
|
2014-09-22 16:23:00 -07:00
|
|
|
|
|
|
|
/// Returns an iterator over `chunk_size` elements of the slice at a time.
|
|
|
|
/// The chunks are mutable and do not overlap. If `chunk_size` does
|
|
|
|
/// not divide the length of the slice, then the last chunk will not
|
|
|
|
/// have length `chunk_size`.
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// # Panics
|
2014-09-22 16:23:00 -07:00
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics if `chunk_size` is 0.
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "waiting on iterator type name conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T>;
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Swaps two elements in a slice.
|
2014-06-30 13:58:53 -07:00
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics if `a` or `b` are out of bounds.
|
2014-06-30 13:58:53 -07:00
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
///
|
|
|
|
/// * a - The index of the first element
|
|
|
|
/// * b - The index of the second element
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let mut v = ["a", "b", "c", "d"];
|
|
|
|
/// v.swap(1, 3);
|
|
|
|
/// assert!(v == ["a", "d", "c", "b"]);
|
|
|
|
/// ```
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "waiting on final error conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn swap(&mut self, a: uint, b: uint);
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Divides one `&mut` into two at an index.
|
|
|
|
///
|
|
|
|
/// The first will contain all indices from `[0, mid)` (excluding
|
|
|
|
/// the index `mid` itself) and the second will contain all
|
|
|
|
/// indices from `[mid, len)` (excluding the index `len` itself).
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
/// Panics if `mid > len`.
|
2014-06-30 13:58:53 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let mut v = [1i, 2, 3, 4, 5, 6];
|
|
|
|
///
|
|
|
|
/// // scoped to restrict the lifetime of the borrows
|
|
|
|
/// {
|
2014-09-14 20:27:36 -07:00
|
|
|
/// let (left, right) = v.split_at_mut(0);
|
2014-11-21 01:20:04 -05:00
|
|
|
/// assert!(left == []);
|
|
|
|
/// assert!(right == [1i, 2, 3, 4, 5, 6]);
|
2014-06-30 13:58:53 -07:00
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// {
|
2014-09-14 20:27:36 -07:00
|
|
|
/// let (left, right) = v.split_at_mut(2);
|
2014-11-21 01:20:04 -05:00
|
|
|
/// assert!(left == [1i, 2]);
|
|
|
|
/// assert!(right == [3i, 4, 5, 6]);
|
2014-06-30 13:58:53 -07:00
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// {
|
2014-09-14 20:27:36 -07:00
|
|
|
/// let (left, right) = v.split_at_mut(6);
|
2014-11-21 01:20:04 -05:00
|
|
|
/// assert!(left == [1i, 2, 3, 4, 5, 6]);
|
|
|
|
/// assert!(right == []);
|
2014-06-30 13:58:53 -07:00
|
|
|
/// }
|
|
|
|
/// ```
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "waiting on final error conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]);
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Reverse the order of elements in a slice, in place.
|
2014-06-30 13:58:53 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let mut v = [1i, 2, 3];
|
|
|
|
/// v.reverse();
|
|
|
|
/// assert!(v == [3i, 2, 1]);
|
|
|
|
/// ```
|
2014-09-22 16:23:00 -07:00
|
|
|
#[experimental = "may be moved to iterators instead"]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn reverse(&mut self);
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Returns an unsafe mutable pointer to the element in index
|
2014-09-22 16:23:00 -07:00
|
|
|
#[experimental = "waiting on unsafe conventions"]
|
2014-10-23 10:43:18 -05:00
|
|
|
unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T;
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Return an unsafe mutable pointer to the slice's buffer.
|
2014-06-30 13:58:53 -07:00
|
|
|
///
|
2014-09-22 16:23:00 -07:00
|
|
|
/// The caller must ensure that the slice outlives the pointer this
|
2014-06-30 13:58:53 -07:00
|
|
|
/// function returns, or else it will end up pointing to garbage.
|
|
|
|
///
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Modifying the slice may cause its buffer to be reallocated, which
|
2014-06-30 13:58:53 -07:00
|
|
|
/// would also make any pointers to it invalid.
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_mut_ptr(&mut self) -> *mut T;
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-11-02 17:04:32 -08:00
|
|
|
#[unstable]
|
|
|
|
impl<T> SlicePrelude<T> for [T] {
|
|
|
|
#[inline]
|
|
|
|
fn slice(&self, start: uint, end: uint) -> &[T] {
|
|
|
|
assert!(start <= end);
|
|
|
|
assert!(end <= self.len());
|
|
|
|
unsafe {
|
|
|
|
transmute(RawSlice {
|
|
|
|
data: self.as_ptr().offset(start as int),
|
|
|
|
len: (end - start)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_from(&self, start: uint) -> &[T] {
|
|
|
|
self.slice(start, self.len())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_to(&self, end: uint) -> &[T] {
|
|
|
|
self.slice(0, end)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn split_at(&self, mid: uint) -> (&[T], &[T]) {
|
|
|
|
(self[..mid], self[mid..])
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn iter<'a>(&'a self) -> Items<'a, T> {
|
|
|
|
unsafe {
|
|
|
|
let p = self.as_ptr();
|
|
|
|
if mem::size_of::<T>() == 0 {
|
|
|
|
Items{ptr: p,
|
|
|
|
end: (p as uint + self.len()) as *const T,
|
|
|
|
marker: marker::ContravariantLifetime::<'a>}
|
|
|
|
} else {
|
|
|
|
Items{ptr: p,
|
|
|
|
end: p.offset(self.len() as int),
|
|
|
|
marker: marker::ContravariantLifetime::<'a>}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-04 23:47:40 -05:00
|
|
|
fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
2014-11-02 17:04:32 -08:00
|
|
|
Splits {
|
|
|
|
v: self,
|
|
|
|
pred: pred,
|
|
|
|
finished: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-04 23:47:40 -05:00
|
|
|
fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool,
|
|
|
|
{
|
2014-11-02 17:04:32 -08:00
|
|
|
SplitsN {
|
|
|
|
iter: self.split(pred),
|
|
|
|
count: n,
|
|
|
|
invert: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-04 23:47:40 -05:00
|
|
|
fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool,
|
|
|
|
{
|
2014-11-02 17:04:32 -08:00
|
|
|
SplitsN {
|
|
|
|
iter: self.split(pred),
|
|
|
|
count: n,
|
|
|
|
invert: true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn windows(&self, size: uint) -> Windows<T> {
|
|
|
|
assert!(size != 0);
|
|
|
|
Windows { v: self, size: size }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn chunks(&self, size: uint) -> Chunks<T> {
|
|
|
|
assert!(size != 0);
|
|
|
|
Chunks { v: self, size: size }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get(&self, index: uint) -> Option<&T> {
|
|
|
|
if index < self.len() { Some(&self[index]) } else { None }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn head(&self) -> Option<&T> {
|
|
|
|
if self.len() == 0 { None } else { Some(&self[0]) }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn tail(&self) -> &[T] { self[1..] }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn init(&self) -> &[T] {
|
|
|
|
self[..self.len() - 1]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn last(&self) -> Option<&T> {
|
|
|
|
if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn unsafe_get(&self, index: uint) -> &T {
|
|
|
|
transmute(self.repr().data.offset(index as int))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn as_ptr(&self) -> *const T {
|
|
|
|
self.repr().data
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable]
|
2014-12-05 02:04:33 -05:00
|
|
|
fn binary_search<F>(&self, mut f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering {
|
2014-11-02 17:04:32 -08:00
|
|
|
let mut base : uint = 0;
|
|
|
|
let mut lim : uint = self.len();
|
|
|
|
|
|
|
|
while lim != 0 {
|
|
|
|
let ix = base + (lim >> 1);
|
|
|
|
match f(&self[ix]) {
|
2014-11-24 15:54:14 -08:00
|
|
|
Equal => return BinarySearchResult::Found(ix),
|
2014-11-02 17:04:32 -08:00
|
|
|
Less => {
|
|
|
|
base = ix + 1;
|
|
|
|
lim -= 1;
|
|
|
|
}
|
|
|
|
Greater => ()
|
|
|
|
}
|
|
|
|
lim >>= 1;
|
|
|
|
}
|
2014-11-24 15:54:14 -08:00
|
|
|
return BinarySearchResult::NotFound(base);
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn len(&self) -> uint { self.repr().len }
|
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn get_mut(&mut self, index: uint) -> Option<&mut T> {
|
2014-06-30 13:58:53 -07:00
|
|
|
if index < self.len() { Some(&mut self[index]) } else { None }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_mut_slice(&mut self) -> &mut [T] { self }
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut start..end]
|
2014-10-02 11:48:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut start..]
|
2014-10-02 11:48:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut ..end]
|
2014-10-02 11:48:07 -07:00
|
|
|
}
|
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) {
|
2014-06-30 13:58:53 -07:00
|
|
|
unsafe {
|
2014-10-23 10:43:18 -05:00
|
|
|
let self2: &mut [T] = mem::transmute_copy(&self);
|
2014-09-24 23:41:09 +12:00
|
|
|
(self[mut ..mid], self2[mut mid..])
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
|
2014-06-30 13:58:53 -07:00
|
|
|
unsafe {
|
|
|
|
let p = self.as_mut_ptr();
|
|
|
|
if mem::size_of::<T>() == 0 {
|
|
|
|
MutItems{ptr: p,
|
|
|
|
end: (p as uint + self.len()) as *mut T,
|
|
|
|
marker: marker::ContravariantLifetime::<'a>,
|
|
|
|
marker2: marker::NoCopy}
|
|
|
|
} else {
|
|
|
|
MutItems{ptr: p,
|
|
|
|
end: p.offset(self.len() as int),
|
|
|
|
marker: marker::ContravariantLifetime::<'a>,
|
|
|
|
marker2: marker::NoCopy}
|
|
|
|
}
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn last_mut(&mut self) -> Option<&mut T> {
|
2014-06-30 13:58:53 -07:00
|
|
|
let len = self.len();
|
|
|
|
if len == 0 { return None; }
|
|
|
|
Some(&mut self[len - 1])
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn head_mut(&mut self) -> Option<&mut T> {
|
2014-09-22 16:23:00 -07:00
|
|
|
if self.len() == 0 { None } else { Some(&mut self[0]) }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn tail_mut(&mut self) -> &mut [T] {
|
2014-09-22 16:23:00 -07:00
|
|
|
let len = self.len();
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut 1..len]
|
2014-09-22 16:23:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn init_mut(&mut self) -> &mut [T] {
|
2014-09-22 16:23:00 -07:00
|
|
|
let len = self.len();
|
2014-09-24 23:41:09 +12:00
|
|
|
self[mut 0..len - 1]
|
2014-09-22 16:23:00 -07:00
|
|
|
}
|
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-12-05 01:00:50 -05:00
|
|
|
fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
|
2014-06-30 13:58:53 -07:00
|
|
|
MutSplits { v: self, pred: pred, finished: false }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
#[inline]
|
2014-12-05 01:00:50 -05:00
|
|
|
fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool
|
|
|
|
{
|
2014-09-22 16:23:00 -07:00
|
|
|
SplitsN {
|
|
|
|
iter: self.split_mut(pred),
|
|
|
|
count: n,
|
|
|
|
invert: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-05 01:00:50 -05:00
|
|
|
fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where
|
|
|
|
P: FnMut(&T) -> bool,
|
|
|
|
{
|
2014-09-22 16:23:00 -07:00
|
|
|
SplitsN {
|
|
|
|
iter: self.split_mut(pred),
|
|
|
|
count: n,
|
|
|
|
invert: true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks<T> {
|
2014-06-30 13:58:53 -07:00
|
|
|
assert!(chunk_size > 0);
|
|
|
|
MutChunks { v: self, chunk_size: chunk_size }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-10-23 10:43:18 -05:00
|
|
|
fn swap(&mut self, a: uint, b: uint) {
|
2014-06-30 13:58:53 -07:00
|
|
|
unsafe {
|
|
|
|
// Can't take two mutable loans from one vector, so instead just cast
|
|
|
|
// them to their raw pointers to do the swap
|
|
|
|
let pa: *mut T = &mut self[a];
|
|
|
|
let pb: *mut T = &mut self[b];
|
|
|
|
ptr::swap(pa, pb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-23 10:43:18 -05:00
|
|
|
fn reverse(&mut self) {
|
2014-06-30 13:58:53 -07:00
|
|
|
let mut i: uint = 0;
|
|
|
|
let ln = self.len();
|
|
|
|
while i < ln / 2 {
|
2014-09-04 19:54:41 -07:00
|
|
|
// Unsafe swap to avoid the bounds check in safe swap.
|
|
|
|
unsafe {
|
2014-09-14 20:27:36 -07:00
|
|
|
let pa: *mut T = self.unsafe_mut(i);
|
|
|
|
let pb: *mut T = self.unsafe_mut(ln - i - 1);
|
2014-09-04 19:54:41 -07:00
|
|
|
ptr::swap(pa, pb);
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T {
|
2014-06-30 13:58:53 -07:00
|
|
|
transmute((self.repr().data as *mut T).offset(index as int))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_mut_ptr(&mut self) -> *mut T {
|
2014-06-30 13:58:53 -07:00
|
|
|
self.repr().data as *mut T
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-11-05 15:44:49 -05:00
|
|
|
impl<T> ops::Index<uint, T> for [T] {
|
|
|
|
fn index(&self, &index: &uint) -> &T {
|
|
|
|
assert!(index < self.len());
|
|
|
|
|
|
|
|
unsafe { mem::transmute(self.repr().data.offset(index as int)) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> ops::IndexMut<uint, T> for [T] {
|
|
|
|
fn index_mut(&mut self, &index: &uint) -> &mut T {
|
|
|
|
assert!(index < self.len());
|
|
|
|
|
|
|
|
unsafe { mem::transmute(self.repr().data.offset(index as int)) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-02 17:04:32 -08:00
|
|
|
impl<T> ops::Slice<uint, [T]> for [T] {
|
|
|
|
#[inline]
|
|
|
|
fn as_slice_<'a>(&'a self) -> &'a [T] {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] {
|
|
|
|
self.slice_or_fail(start, &self.len())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] {
|
|
|
|
self.slice_or_fail(&0, end)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] {
|
|
|
|
assert!(*start <= *end);
|
|
|
|
assert!(*end <= self.len());
|
|
|
|
unsafe {
|
|
|
|
transmute(RawSlice {
|
|
|
|
data: self.as_ptr().offset(*start as int),
|
|
|
|
len: (*end - *start)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> ops::SliceMut<uint, [T]> for [T] {
|
|
|
|
#[inline]
|
|
|
|
fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] {
|
|
|
|
let len = &self.len();
|
|
|
|
self.slice_or_fail_mut(start, len)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] {
|
|
|
|
self.slice_or_fail_mut(&0, end)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] {
|
|
|
|
assert!(*start <= *end);
|
|
|
|
assert!(*end <= self.len());
|
|
|
|
unsafe {
|
|
|
|
transmute(RawSlice {
|
|
|
|
data: self.as_ptr().offset(*start as int),
|
|
|
|
len: (*end - *start)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Extension methods for slices containing `PartialEq` elements.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "may merge with other traits"]
|
2014-11-02 17:04:32 -08:00
|
|
|
pub trait PartialEqSlicePrelude<T: PartialEq> for Sized? {
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Find the first index containing a matching value.
|
2014-04-30 22:54:25 -07:00
|
|
|
fn position_elem(&self, t: &T) -> Option<uint>;
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Find the last index containing a matching value.
|
2014-04-30 22:54:25 -07:00
|
|
|
fn rposition_elem(&self, t: &T) -> Option<uint>;
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Return true if the slice contains an element with the given value.
|
2014-04-30 22:54:25 -07:00
|
|
|
fn contains(&self, x: &T) -> bool;
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns true if `needle` is a prefix of the slice.
|
2014-04-30 22:54:25 -07:00
|
|
|
fn starts_with(&self, needle: &[T]) -> bool;
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Returns true if `needle` is a suffix of the slice.
|
2014-04-30 22:54:25 -07:00
|
|
|
fn ends_with(&self, needle: &[T]) -> bool;
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "trait is unstable"]
|
2014-11-02 17:04:32 -08:00
|
|
|
impl<T: PartialEq> PartialEqSlicePrelude<T> for [T] {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
|
|
|
fn position_elem(&self, x: &T) -> Option<uint> {
|
|
|
|
self.iter().position(|y| *x == *y)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn rposition_elem(&self, t: &T) -> Option<uint> {
|
|
|
|
self.iter().rposition(|x| *x == *t)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn contains(&self, x: &T) -> bool {
|
|
|
|
self.iter().any(|elt| *x == *elt)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn starts_with(&self, needle: &[T]) -> bool {
|
|
|
|
let n = needle.len();
|
2014-10-23 10:43:18 -05:00
|
|
|
self.len() >= n && needle == self[..n]
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ends_with(&self, needle: &[T]) -> bool {
|
|
|
|
let (m, n) = (self.len(), needle.len());
|
2014-10-23 10:43:18 -05:00
|
|
|
m >= n && needle == self[m-n..]
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Extension methods for slices containing `Ord` elements.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "may merge with other traits"]
|
2014-11-02 17:04:32 -08:00
|
|
|
pub trait OrdSlicePrelude<T: Ord> for Sized? {
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Binary search a sorted slice for a given element.
|
|
|
|
///
|
|
|
|
/// If the value is found then `Found` is returned, containing the
|
|
|
|
/// index of the matching element; if the value is not found then
|
|
|
|
/// `NotFound` is returned, containing the index where a matching
|
|
|
|
/// element could be inserted while maintaining sorted order.
|
2014-10-06 15:46:09 +02:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// Looks up a series of four elements. The first is found, with a
|
|
|
|
/// uniquely determined position; the second and third are not
|
|
|
|
/// found; the fourth could match any position in `[1,4]`.
|
|
|
|
///
|
|
|
|
/// ```rust
|
2014-11-24 15:54:14 -08:00
|
|
|
/// use std::slice::BinarySearchResult::{Found, NotFound};
|
2014-10-06 15:46:09 +02:00
|
|
|
/// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
|
|
|
|
/// let s = s.as_slice();
|
|
|
|
///
|
|
|
|
/// assert_eq!(s.binary_search_elem(&13), Found(9));
|
|
|
|
/// assert_eq!(s.binary_search_elem(&4), NotFound(7));
|
|
|
|
/// assert_eq!(s.binary_search_elem(&100), NotFound(13));
|
|
|
|
/// let r = s.binary_search_elem(&1);
|
|
|
|
/// assert!(match r { Found(1...4) => true, _ => false, });
|
|
|
|
/// ```
|
2014-09-22 16:23:00 -07:00
|
|
|
#[unstable = "name likely to change"]
|
2014-08-06 20:48:25 -07:00
|
|
|
fn binary_search_elem(&self, x: &T) -> BinarySearchResult;
|
2014-11-02 17:04:32 -08:00
|
|
|
|
|
|
|
/// Mutates the slice to the next lexicographic permutation.
|
|
|
|
///
|
|
|
|
/// Returns `true` if successful and `false` if the slice is at the
|
|
|
|
/// last-ordered permutation.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let v: &mut [_] = &mut [0i, 1, 2];
|
|
|
|
/// v.next_permutation();
|
|
|
|
/// let b: &mut [_] = &mut [0i, 2, 1];
|
|
|
|
/// assert!(v == b);
|
|
|
|
/// v.next_permutation();
|
|
|
|
/// let b: &mut [_] = &mut [1i, 0, 2];
|
|
|
|
/// assert!(v == b);
|
|
|
|
/// ```
|
|
|
|
#[experimental]
|
|
|
|
fn next_permutation(&mut self) -> bool;
|
|
|
|
|
|
|
|
/// Mutates the slice to the previous lexicographic permutation.
|
|
|
|
///
|
|
|
|
/// Returns `true` if successful and `false` if the slice is at the
|
|
|
|
/// first-ordered permutation.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let v: &mut [_] = &mut [1i, 0, 2];
|
|
|
|
/// v.prev_permutation();
|
|
|
|
/// let b: &mut [_] = &mut [0i, 2, 1];
|
|
|
|
/// assert!(v == b);
|
|
|
|
/// v.prev_permutation();
|
|
|
|
/// let b: &mut [_] = &mut [0i, 1, 2];
|
|
|
|
/// assert!(v == b);
|
|
|
|
/// ```
|
|
|
|
#[experimental]
|
|
|
|
fn prev_permutation(&mut self) -> bool;
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "trait is unstable"]
|
2014-11-02 17:04:32 -08:00
|
|
|
impl<T: Ord> OrdSlicePrelude<T> for [T] {
|
2014-08-06 20:48:25 -07:00
|
|
|
#[unstable]
|
|
|
|
fn binary_search_elem(&self, x: &T) -> BinarySearchResult {
|
|
|
|
self.binary_search(|p| p.cmp(x))
|
|
|
|
}
|
2014-11-02 17:04:32 -08:00
|
|
|
|
|
|
|
#[experimental]
|
|
|
|
fn next_permutation(&mut self) -> bool {
|
|
|
|
// These cases only have 1 permutation each, so we can't do anything.
|
|
|
|
if self.len() < 2 { return false; }
|
|
|
|
|
|
|
|
// Step 1: Identify the longest, rightmost weakly decreasing part of the vector
|
|
|
|
let mut i = self.len() - 1;
|
|
|
|
while i > 0 && self[i-1] >= self[i] {
|
|
|
|
i -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If that is the entire vector, this is the last-ordered permutation.
|
|
|
|
if i == 0 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Step 2: Find the rightmost element larger than the pivot (i-1)
|
|
|
|
let mut j = self.len() - 1;
|
|
|
|
while j >= i && self[j] <= self[i-1] {
|
|
|
|
j -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Step 3: Swap that element with the pivot
|
|
|
|
self.swap(j, i-1);
|
|
|
|
|
|
|
|
// Step 4: Reverse the (previously) weakly decreasing part
|
|
|
|
self[mut i..].reverse();
|
|
|
|
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
#[experimental]
|
|
|
|
fn prev_permutation(&mut self) -> bool {
|
|
|
|
// These cases only have 1 permutation each, so we can't do anything.
|
|
|
|
if self.len() < 2 { return false; }
|
|
|
|
|
|
|
|
// Step 1: Identify the longest, rightmost weakly increasing part of the vector
|
|
|
|
let mut i = self.len() - 1;
|
|
|
|
while i > 0 && self[i-1] <= self[i] {
|
|
|
|
i -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If that is the entire vector, this is the first-ordered permutation.
|
|
|
|
if i == 0 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Step 2: Reverse the weakly increasing part
|
|
|
|
self[mut i..].reverse();
|
|
|
|
|
|
|
|
// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
|
|
|
|
let mut j = self.len() - 1;
|
|
|
|
while j >= i && self[j-1] < self[i-1] {
|
|
|
|
j -= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Step 4: Swap that element with the pivot
|
|
|
|
self.swap(i-1, j);
|
|
|
|
|
|
|
|
true
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-11-02 17:04:32 -08:00
|
|
|
/// Extension methods for slices on Clone elements
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "may merge with other traits"]
|
2014-11-02 17:04:32 -08:00
|
|
|
pub trait CloneSlicePrelude<T> for Sized? {
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Copies as many elements from `src` as it can into `self` (the
|
|
|
|
/// shorter of `self.len()` and `src.len()`). Returns the number
|
|
|
|
/// of elements copied.
|
2014-04-30 22:54:25 -07:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
2014-11-02 17:04:32 -08:00
|
|
|
/// use std::slice::CloneSlicePrelude;
|
2014-04-30 22:54:25 -07:00
|
|
|
///
|
2014-06-30 13:58:53 -07:00
|
|
|
/// let mut dst = [0i, 0, 0];
|
|
|
|
/// let src = [1i, 2];
|
2014-04-30 22:54:25 -07:00
|
|
|
///
|
2014-11-17 21:39:01 +13:00
|
|
|
/// assert!(dst.clone_from_slice(&src) == 2);
|
2014-06-30 13:58:53 -07:00
|
|
|
/// assert!(dst == [1, 2, 0]);
|
2014-04-30 22:54:25 -07:00
|
|
|
///
|
2014-06-30 13:58:53 -07:00
|
|
|
/// let src2 = [3i, 4, 5, 6];
|
2014-11-17 21:39:01 +13:00
|
|
|
/// assert!(dst.clone_from_slice(&src2) == 3);
|
2014-06-30 13:58:53 -07:00
|
|
|
/// assert!(dst == [3i, 4, 5]);
|
2014-04-30 22:54:25 -07:00
|
|
|
/// ```
|
2014-10-23 10:43:18 -05:00
|
|
|
fn clone_from_slice(&mut self, &[T]) -> uint;
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "trait is unstable"]
|
2014-11-02 17:04:32 -08:00
|
|
|
impl<T: Clone> CloneSlicePrelude<T> for [T] {
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn clone_from_slice(&mut self, src: &[T]) -> uint {
|
2014-10-12 01:17:11 +02:00
|
|
|
let min = cmp::min(self.len(), src.len());
|
|
|
|
let dst = self.slice_to_mut(min);
|
|
|
|
let src = src.slice_to(min);
|
|
|
|
for i in range(0, min) {
|
|
|
|
dst[i].clone_from(&src[i]);
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-10-12 01:17:11 +02:00
|
|
|
min
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
|
|
|
// Common traits
|
|
|
|
//
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Data that is viewable as a slice.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "may merge with other traits"]
|
2014-11-04 15:31:46 -08:00
|
|
|
pub trait AsSlice<T> for Sized? {
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Work with `self` as a slice.
|
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T];
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "trait is unstable"]
|
2014-11-04 15:31:46 -08:00
|
|
|
impl<T> AsSlice<T> for [T] {
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline(always)]
|
2014-11-04 15:31:46 -08:00
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T] { self }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a U {
|
|
|
|
#[inline(always)]
|
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T] { AsSlice::as_slice(*self) }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a mut U {
|
|
|
|
#[inline(always)]
|
|
|
|
fn as_slice<'a>(&'a self) -> &'a [T] { AsSlice::as_slice(*self) }
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "waiting for DST"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> Default for &'a [T] {
|
|
|
|
fn default() -> &'a [T] { &[] }
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Iterators
|
|
|
|
//
|
|
|
|
|
|
|
|
// The shared definition of the `Item` and `MutItems` iterators
|
|
|
|
macro_rules! iterator {
|
|
|
|
(struct $name:ident -> $ptr:ty, $elem:ty) => {
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> Iterator<$elem> for $name<'a, T> {
|
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<$elem> {
|
|
|
|
// could be implemented with slices, but this avoids bounds checks
|
|
|
|
unsafe {
|
|
|
|
if self.ptr == self.end {
|
|
|
|
None
|
|
|
|
} else {
|
2014-07-04 15:29:47 -07:00
|
|
|
if mem::size_of::<T>() == 0 {
|
2014-06-30 13:58:53 -07:00
|
|
|
// purposefully don't use 'ptr.offset' because for
|
|
|
|
// vectors with 0-size elements this would return the
|
|
|
|
// same pointer.
|
2014-07-04 15:29:47 -07:00
|
|
|
self.ptr = transmute(self.ptr as uint + 1);
|
|
|
|
|
|
|
|
// Use a non-null pointer value
|
|
|
|
Some(transmute(1u))
|
2014-06-30 13:58:53 -07:00
|
|
|
} else {
|
2014-07-04 15:29:47 -07:00
|
|
|
let old = self.ptr;
|
|
|
|
self.ptr = self.ptr.offset(1);
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2014-07-04 15:29:47 -07:00
|
|
|
Some(transmute(old))
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
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-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
|
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<$elem> {
|
|
|
|
// could be implemented with slices, but this avoids bounds checks
|
|
|
|
unsafe {
|
|
|
|
if self.end == self.ptr {
|
|
|
|
None
|
|
|
|
} else {
|
2014-07-04 15:29:47 -07:00
|
|
|
if mem::size_of::<T>() == 0 {
|
2014-06-30 13:58:53 -07:00
|
|
|
// See above for why 'ptr.offset' isn't used
|
2014-07-04 15:29:47 -07:00
|
|
|
self.end = transmute(self.end as uint - 1);
|
|
|
|
|
|
|
|
// Use a non-null pointer value
|
|
|
|
Some(transmute(1u))
|
2014-06-30 13:58:53 -07:00
|
|
|
} else {
|
2014-07-04 15:29:47 -07:00
|
|
|
self.end = self.end.offset(-1);
|
|
|
|
|
|
|
|
Some(transmute(self.end))
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-15 14:44:55 +11:00
|
|
|
macro_rules! make_slice {
|
|
|
|
($t: ty -> $result: ty: $start: expr, $end: expr) => {{
|
|
|
|
let diff = $end as uint - $start as uint;
|
|
|
|
let len = if mem::size_of::<T>() == 0 {
|
|
|
|
diff
|
|
|
|
} else {
|
|
|
|
diff / mem::size_of::<$t>()
|
|
|
|
};
|
|
|
|
unsafe {
|
|
|
|
transmute::<_, $result>(RawSlice { data: $start as *const T, len: len })
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Immutable slice iterator
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-09-04 15:25:23 -04:00
|
|
|
pub struct Items<'a, T: 'a> {
|
2014-06-30 13:58:53 -07:00
|
|
|
ptr: *const T,
|
|
|
|
end: *const T,
|
|
|
|
marker: marker::ContravariantLifetime<'a>
|
|
|
|
}
|
|
|
|
|
2014-11-15 14:44:55 +11:00
|
|
|
#[experimental]
|
|
|
|
impl<'a, T> ops::Slice<uint, [T]> for Items<'a, T> {
|
|
|
|
fn as_slice_(&self) -> &[T] {
|
|
|
|
self.as_slice()
|
|
|
|
}
|
|
|
|
fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] {
|
|
|
|
use ops::Slice;
|
|
|
|
self.as_slice().slice_from_or_fail(from)
|
|
|
|
}
|
|
|
|
fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] {
|
|
|
|
use ops::Slice;
|
|
|
|
self.as_slice().slice_to_or_fail(to)
|
|
|
|
}
|
|
|
|
fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] {
|
|
|
|
use ops::Slice;
|
|
|
|
self.as_slice().slice_or_fail(from, to)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T> Items<'a, T> {
|
|
|
|
/// View the underlying data as a subslice of the original data.
|
|
|
|
///
|
|
|
|
/// This has the same lifetime as the original slice, and so the
|
|
|
|
/// iterator can continue to be used while this exists.
|
|
|
|
#[experimental]
|
|
|
|
pub fn as_slice(&self) -> &'a [T] {
|
|
|
|
make_slice!(T -> &'a [T]: self.ptr, self.end)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
impl<'a,T> Copy for Items<'a,T> {}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
iterator!{struct Items -> *const T, &'a T}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-11-06 09:32:37 -08:00
|
|
|
impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> Clone for Items<'a, T> {
|
|
|
|
fn clone(&self) -> Items<'a, T> { *self }
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn indexable(&self) -> uint {
|
|
|
|
let (exact, _) = self.size_hint();
|
|
|
|
exact
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn idx(&mut self, index: uint) -> Option<&'a T> {
|
2014-04-30 22:54:25 -07:00
|
|
|
unsafe {
|
2014-06-30 13:58:53 -07:00
|
|
|
if index < self.indexable() {
|
2014-07-04 15:29:47 -07:00
|
|
|
if mem::size_of::<T>() == 0 {
|
|
|
|
// Use a non-null pointer value
|
|
|
|
Some(transmute(1u))
|
|
|
|
} else {
|
|
|
|
Some(transmute(self.ptr.offset(index as int)))
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Mutable slice iterator.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-09-04 15:25:23 -04:00
|
|
|
pub struct MutItems<'a, T: 'a> {
|
2014-06-30 13:58:53 -07:00
|
|
|
ptr: *mut T,
|
|
|
|
end: *mut T,
|
|
|
|
marker: marker::ContravariantLifetime<'a>,
|
|
|
|
marker2: marker::NoCopy
|
|
|
|
}
|
|
|
|
|
2014-11-15 14:44:55 +11:00
|
|
|
#[experimental]
|
|
|
|
impl<'a, T> ops::Slice<uint, [T]> for MutItems<'a, T> {
|
|
|
|
fn as_slice_<'b>(&'b self) -> &'b [T] {
|
|
|
|
make_slice!(T -> &'b [T]: self.ptr, self.end)
|
|
|
|
}
|
|
|
|
fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] {
|
|
|
|
use ops::Slice;
|
|
|
|
self.as_slice_().slice_from_or_fail(from)
|
|
|
|
}
|
|
|
|
fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] {
|
|
|
|
use ops::Slice;
|
|
|
|
self.as_slice_().slice_to_or_fail(to)
|
|
|
|
}
|
|
|
|
fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] {
|
|
|
|
use ops::Slice;
|
|
|
|
self.as_slice_().slice_or_fail(from, to)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[experimental]
|
|
|
|
impl<'a, T> ops::SliceMut<uint, [T]> for MutItems<'a, T> {
|
|
|
|
fn as_mut_slice_<'b>(&'b mut self) -> &'b mut [T] {
|
|
|
|
make_slice!(T -> &'b mut [T]: self.ptr, self.end)
|
|
|
|
}
|
|
|
|
fn slice_from_or_fail_mut<'b>(&'b mut self, from: &uint) -> &'b mut [T] {
|
|
|
|
use ops::SliceMut;
|
|
|
|
self.as_mut_slice_().slice_from_or_fail_mut(from)
|
|
|
|
}
|
|
|
|
fn slice_to_or_fail_mut<'b>(&'b mut self, to: &uint) -> &'b mut [T] {
|
|
|
|
use ops::SliceMut;
|
|
|
|
self.as_mut_slice_().slice_to_or_fail_mut(to)
|
|
|
|
}
|
|
|
|
fn slice_or_fail_mut<'b>(&'b mut self, from: &uint, to: &uint) -> &'b mut [T] {
|
|
|
|
use ops::SliceMut;
|
|
|
|
self.as_mut_slice_().slice_or_fail_mut(from, to)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T> MutItems<'a, T> {
|
|
|
|
/// View the underlying data as a subslice of the original data.
|
|
|
|
///
|
|
|
|
/// To avoid creating `&mut` references that alias, this is forced
|
|
|
|
/// to consume the iterator. Consider using the `Slice` and
|
|
|
|
/// `SliceMut` implementations for obtaining slices with more
|
|
|
|
/// restricted lifetimes that do not consume the iterator.
|
|
|
|
#[experimental]
|
|
|
|
pub fn into_slice(self) -> &'a mut [T] {
|
|
|
|
make_slice!(T -> &'a mut [T]: self.ptr, self.end)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
iterator!{struct MutItems -> *mut T, &'a mut T}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-11-06 09:32:37 -08:00
|
|
|
impl<'a, T> ExactSizeIterator<&'a mut T> for MutItems<'a, T> {}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// An abstraction over the splitting iterators, so that splitn, splitn_mut etc
|
|
|
|
/// can be implemented once.
|
|
|
|
trait SplitsIter<E>: DoubleEndedIterator<E> {
|
|
|
|
/// Mark the underlying iterator as complete, extracting the remaining
|
|
|
|
/// portion of the slice.
|
|
|
|
fn finish(&mut self) -> Option<E>;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An iterator over subslices separated by elements that match a predicate
|
|
|
|
/// function.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-12-04 23:47:40 -05:00
|
|
|
pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool {
|
2014-08-27 21:46:52 -04:00
|
|
|
v: &'a [T],
|
2014-12-04 23:47:40 -05:00
|
|
|
pred: P,
|
2014-08-27 21:46:52 -04:00
|
|
|
finished: bool
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-12-04 23:47:40 -05:00
|
|
|
impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
|
|
|
if self.finished { return None; }
|
|
|
|
|
|
|
|
match self.v.iter().position(|x| (self.pred)(x)) {
|
2014-09-22 16:23:00 -07:00
|
|
|
None => self.finish(),
|
2014-06-30 13:58:53 -07:00
|
|
|
Some(idx) => {
|
2014-09-24 23:41:09 +12:00
|
|
|
let ret = Some(self.v[..idx]);
|
|
|
|
self.v = self.v[idx + 1..];
|
2014-06-30 13:58:53 -07:00
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
if self.finished {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
|
|
|
(1, Some(self.v.len() + 1))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-12-04 23:47:40 -05:00
|
|
|
impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a [T]> {
|
|
|
|
if self.finished { return None; }
|
|
|
|
|
|
|
|
match self.v.iter().rposition(|x| (self.pred)(x)) {
|
2014-09-22 16:23:00 -07:00
|
|
|
None => self.finish(),
|
2014-06-30 13:58:53 -07:00
|
|
|
Some(idx) => {
|
2014-09-24 23:41:09 +12:00
|
|
|
let ret = Some(self.v[idx + 1..]);
|
|
|
|
self.v = self.v[..idx];
|
2014-06-30 13:58:53 -07:00
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-04 23:47:40 -05:00
|
|
|
impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool {
|
2014-09-22 16:23:00 -07:00
|
|
|
#[inline]
|
|
|
|
fn finish(&mut self) -> Option<&'a [T]> {
|
|
|
|
if self.finished { None } else { self.finished = true; Some(self.v) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// An iterator over the subslices of the vector which are separated
|
|
|
|
/// by elements that match `pred`.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-12-05 01:00:50 -05:00
|
|
|
pub struct MutSplits<'a, T:'a, P> where P: FnMut(&T) -> bool {
|
2014-08-27 21:46:52 -04:00
|
|
|
v: &'a mut [T],
|
2014-12-05 01:00:50 -05:00
|
|
|
pred: P,
|
2014-08-27 21:46:52 -04:00
|
|
|
finished: bool
|
|
|
|
}
|
|
|
|
|
2014-12-05 01:00:50 -05:00
|
|
|
impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
|
2014-09-22 16:23:00 -07:00
|
|
|
#[inline]
|
|
|
|
fn finish(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
if self.finished {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
self.finished = true;
|
|
|
|
Some(mem::replace(&mut self.v, &mut []))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-12-05 01:00:50 -05:00
|
|
|
impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool {
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
if self.finished { return None; }
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
let idx_opt = { // work around borrowck limitations
|
|
|
|
let pred = &mut self.pred;
|
|
|
|
self.v.iter().position(|x| (*pred)(x))
|
|
|
|
};
|
|
|
|
match idx_opt {
|
|
|
|
None => self.finish(),
|
2014-06-30 13:58:53 -07:00
|
|
|
Some(idx) => {
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2014-09-14 20:27:36 -07:00
|
|
|
let (head, tail) = tmp.split_at_mut(idx);
|
2014-09-24 23:41:09 +12:00
|
|
|
self.v = tail[mut 1..];
|
2014-06-30 13:58:53 -07:00
|
|
|
Some(head)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
if self.finished {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
|
|
|
// if the predicate doesn't match anything, we yield one slice
|
|
|
|
// if it matches every element, we yield len+1 empty slices.
|
|
|
|
(1, Some(self.v.len() + 1))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-12-05 01:00:50 -05:00
|
|
|
impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where
|
|
|
|
P: FnMut(&T) -> bool,
|
|
|
|
{
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
if self.finished { return None; }
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
let idx_opt = { // work around borrowck limitations
|
|
|
|
let pred = &mut self.pred;
|
|
|
|
self.v.iter().rposition(|x| (*pred)(x))
|
|
|
|
};
|
|
|
|
match idx_opt {
|
|
|
|
None => self.finish(),
|
2014-06-30 13:58:53 -07:00
|
|
|
Some(idx) => {
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2014-09-14 20:27:36 -07:00
|
|
|
let (head, tail) = tmp.split_at_mut(idx);
|
2014-06-30 13:58:53 -07:00
|
|
|
self.v = head;
|
2014-09-24 23:41:09 +12:00
|
|
|
Some(tail[mut 1..])
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// An iterator over subslices separated by elements that match a predicate
|
|
|
|
/// function, splitting at most a fixed number of times.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-09-22 16:23:00 -07:00
|
|
|
pub struct SplitsN<I> {
|
|
|
|
iter: I,
|
2014-08-27 21:46:52 -04:00
|
|
|
count: uint,
|
|
|
|
invert: bool
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-09-22 16:23:00 -07:00
|
|
|
impl<E, I: SplitsIter<E>> Iterator<E> for SplitsN<I> {
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
2014-09-22 16:23:00 -07:00
|
|
|
fn next(&mut self) -> Option<E> {
|
2014-06-30 13:58:53 -07:00
|
|
|
if self.count == 0 {
|
2014-09-22 16:23:00 -07:00
|
|
|
self.iter.finish()
|
2014-06-30 13:58:53 -07:00
|
|
|
} else {
|
|
|
|
self.count -= 1;
|
|
|
|
if self.invert { self.iter.next_back() } else { self.iter.next() }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2014-09-22 16:23:00 -07:00
|
|
|
let (lower, upper_opt) = self.iter.size_hint();
|
|
|
|
(lower, upper_opt.map(|upper| cmp::min(self.count + 1, upper)))
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// An iterator over overlapping subslices of length `size`.
|
2014-08-27 21:46:52 -04:00
|
|
|
#[deriving(Clone)]
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-08-27 21:46:52 -04:00
|
|
|
pub struct Windows<'a, T:'a> {
|
|
|
|
v: &'a [T],
|
|
|
|
size: uint
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
|
|
|
if self.size > self.v.len() {
|
|
|
|
None
|
|
|
|
} else {
|
2014-09-24 23:41:09 +12:00
|
|
|
let ret = Some(self.v[..self.size]);
|
|
|
|
self.v = self.v[1..];
|
2014-06-30 13:58:53 -07:00
|
|
|
ret
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
if self.size > self.v.len() {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
|
|
|
let x = self.v.len() - self.size;
|
2014-11-10 00:11:28 +11:00
|
|
|
(x.saturating_add(1), x.checked_add(1u))
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// An iterator over a slice in (non-overlapping) chunks (`size` elements at a
|
|
|
|
/// time).
|
2014-06-30 13:58:53 -07:00
|
|
|
///
|
2014-09-22 16:23:00 -07:00
|
|
|
/// When the slice len is not evenly divided by the chunk size, the last slice
|
|
|
|
/// of the iteration will be the remainder.
|
2014-06-30 13:58:53 -07:00
|
|
|
#[deriving(Clone)]
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-08-27 21:46:52 -04:00
|
|
|
pub struct Chunks<'a, T:'a> {
|
|
|
|
v: &'a [T],
|
|
|
|
size: uint
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> Iterator<&'a [T]> for Chunks<'a, T> {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let chunksz = cmp::min(self.v.len(), self.size);
|
2014-08-01 22:59:54 -04:00
|
|
|
let (fst, snd) = self.v.split_at(chunksz);
|
2014-06-30 13:58:53 -07:00
|
|
|
self.v = snd;
|
|
|
|
Some(fst)
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
2014-11-18 20:22:13 -08:00
|
|
|
let n = self.v.len() / self.size;
|
|
|
|
let rem = self.v.len() % self.size;
|
2014-06-30 13:58:53 -07:00
|
|
|
let n = if rem > 0 { n+1 } else { n };
|
|
|
|
(n, Some(n))
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> DoubleEndedIterator<&'a [T]> for Chunks<'a, T> {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn next_back(&mut self) -> Option<&'a [T]> {
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let remainder = self.v.len() % self.size;
|
|
|
|
let chunksz = if remainder != 0 { remainder } else { self.size };
|
2014-08-01 22:59:54 -04:00
|
|
|
let (fst, snd) = self.v.split_at(self.v.len() - chunksz);
|
2014-06-30 13:58:53 -07:00
|
|
|
self.v = fst;
|
|
|
|
Some(snd)
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn indexable(&self) -> uint {
|
|
|
|
self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn idx(&mut self, index: uint) -> Option<&'a [T]> {
|
|
|
|
if index < self.indexable() {
|
|
|
|
let lo = index * self.size;
|
|
|
|
let mut hi = lo + self.size;
|
|
|
|
if hi < lo || hi > self.v.len() { hi = self.v.len(); }
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-09-24 23:41:09 +12:00
|
|
|
Some(self.v[lo..hi])
|
2014-06-30 13:58:53 -07:00
|
|
|
} else {
|
|
|
|
None
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// An iterator over a slice in (non-overlapping) mutable chunks (`size`
|
|
|
|
/// elements at a time). When the slice len is not evenly divided by the chunk
|
|
|
|
/// size, the last slice of the iteration will be the remainder.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-08-27 21:46:52 -04:00
|
|
|
pub struct MutChunks<'a, T:'a> {
|
|
|
|
v: &'a mut [T],
|
|
|
|
chunk_size: uint
|
|
|
|
}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> {
|
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let sz = cmp::min(self.v.len(), self.chunk_size);
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
2014-09-14 20:27:36 -07:00
|
|
|
let (head, tail) = tmp.split_at_mut(sz);
|
2014-06-30 13:58:53 -07:00
|
|
|
self.v = tail;
|
|
|
|
Some(head)
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
2014-11-18 20:22:13 -08:00
|
|
|
let n = self.v.len() / self.chunk_size;
|
|
|
|
let rem = self.v.len() % self.chunk_size;
|
2014-06-30 13:58:53 -07:00
|
|
|
let n = if rem > 0 { n + 1 } else { n };
|
|
|
|
(n, Some(n))
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-06-30 13:58:53 -07:00
|
|
|
fn next_back(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
if self.v.len() == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let remainder = self.v.len() % self.chunk_size;
|
|
|
|
let sz = if remainder != 0 { remainder } else { self.chunk_size };
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
|
|
|
let tmp_len = tmp.len();
|
2014-09-14 20:27:36 -07:00
|
|
|
let (head, tail) = tmp.split_at_mut(tmp_len - sz);
|
2014-06-30 13:58:53 -07:00
|
|
|
self.v = head;
|
|
|
|
Some(tail)
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
2014-08-06 20:48:25 -07:00
|
|
|
/// The result of calling `binary_search`.
|
|
|
|
///
|
|
|
|
/// `Found` means the search succeeded, and the contained value is the
|
|
|
|
/// index of the matching element. `NotFound` means the search
|
|
|
|
/// succeeded, and the contained value is an index where a matching
|
|
|
|
/// value could be inserted while maintaining sort order.
|
|
|
|
#[deriving(PartialEq, Show)]
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-08-06 20:48:25 -07:00
|
|
|
pub enum BinarySearchResult {
|
|
|
|
/// The index of the found value.
|
|
|
|
Found(uint),
|
|
|
|
/// The index where the value should have been found.
|
|
|
|
NotFound(uint)
|
|
|
|
}
|
|
|
|
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
impl Copy for BinarySearchResult {}
|
|
|
|
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-08-06 20:48:25 -07:00
|
|
|
impl BinarySearchResult {
|
|
|
|
/// Converts a `Found` to `Some`, `NotFound` to `None`.
|
|
|
|
/// Similar to `Result::ok`.
|
|
|
|
pub fn found(&self) -> Option<uint> {
|
|
|
|
match *self {
|
2014-11-24 15:54:14 -08:00
|
|
|
BinarySearchResult::Found(i) => Some(i),
|
|
|
|
BinarySearchResult::NotFound(_) => None
|
2014-08-06 20:48:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert a `Found` to `None`, `NotFound` to `Some`.
|
|
|
|
/// Similar to `Result::err`.
|
|
|
|
pub fn not_found(&self) -> Option<uint> {
|
|
|
|
match *self {
|
2014-11-24 15:54:14 -08:00
|
|
|
BinarySearchResult::Found(_) => None,
|
|
|
|
BinarySearchResult::NotFound(i) => Some(i)
|
2014-08-06 20:48:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
|
|
|
// Free functions
|
|
|
|
//
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// Converts a pointer to A into a slice of length 1 (without copying).
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "waiting for DST"]
|
2014-06-30 13:58:53 -07:00
|
|
|
pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
|
|
|
|
unsafe {
|
2014-08-06 20:03:55 -07:00
|
|
|
transmute(RawSlice { data: s, len: 1 })
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// Converts a pointer to A into a slice of length 1 (without copying).
|
2014-08-06 23:59:12 -07:00
|
|
|
#[unstable = "waiting for DST"]
|
2014-06-30 13:58:53 -07:00
|
|
|
pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
|
|
|
|
unsafe {
|
|
|
|
let ptr: *const A = transmute(s);
|
2014-08-06 20:03:55 -07:00
|
|
|
transmute(RawSlice { data: ptr, len: 1 })
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 10:11:15 -08:00
|
|
|
/// Forms a slice from a pointer and a length.
|
|
|
|
///
|
|
|
|
/// The pointer given is actually a reference to the base of the slice. This
|
|
|
|
/// reference is used to give a concrete lifetime to tie the returned slice to.
|
|
|
|
/// Typically this should indicate that the slice is valid for as long as the
|
|
|
|
/// pointer itself is valid.
|
|
|
|
///
|
|
|
|
/// The `len` argument is the number of **elements**, not the number of bytes.
|
|
|
|
///
|
|
|
|
/// This function is unsafe as there is no guarantee that the given pointer is
|
|
|
|
/// valid for `len` elements, nor whether the lifetime provided is a suitable
|
|
|
|
/// lifetime for the returned slice.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use std::slice;
|
|
|
|
///
|
|
|
|
/// // manifest a slice out of thin air!
|
|
|
|
/// let ptr = 0x1234 as *const uint;
|
|
|
|
/// let amt = 10;
|
|
|
|
/// unsafe {
|
|
|
|
/// let slice = slice::from_raw_buf(&ptr, amt);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[unstable = "just renamed from `mod raw`"]
|
|
|
|
pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
|
|
|
|
transmute(RawSlice { data: *p, len: len })
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2014-11-20 10:11:15 -08:00
|
|
|
/// Performs the same functionality as `from_raw_buf`, except that a mutable
|
|
|
|
/// slice is returned.
|
|
|
|
///
|
|
|
|
/// This function is unsafe for the same reasons as `from_raw_buf`, as well as
|
|
|
|
/// not being able to provide a non-aliasing guarantee of the returned mutable
|
|
|
|
/// slice.
|
|
|
|
#[inline]
|
|
|
|
#[unstable = "just renamed from `mod raw`"]
|
|
|
|
pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
|
|
|
|
transmute(RawSlice { data: *p as *const T, len: len })
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// Submodules
|
|
|
|
//
|
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
/// Unsafe operations
|
2014-11-20 10:11:15 -08:00
|
|
|
#[deprecated]
|
2014-04-30 22:54:25 -07:00
|
|
|
pub mod raw {
|
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
|
|
|
use mem::transmute;
|
2014-04-30 22:54:25 -07:00
|
|
|
use ptr::RawPtr;
|
|
|
|
use raw::Slice;
|
2014-11-28 11:57:41 -05:00
|
|
|
use option::Option;
|
|
|
|
use option::Option::{None, Some};
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// Form a slice from a pointer and length (as a number of units,
|
|
|
|
/// not bytes).
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-11-20 10:11:15 -08:00
|
|
|
#[deprecated = "renamed to slice::from_raw_buf"]
|
2014-06-25 12:47:34 -07:00
|
|
|
pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U)
|
2014-04-30 22:54:25 -07:00
|
|
|
-> U {
|
|
|
|
f(transmute(Slice {
|
|
|
|
data: p,
|
|
|
|
len: len
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// Form a slice from a pointer and length (as a number of units,
|
|
|
|
/// not bytes).
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-11-20 10:11:15 -08:00
|
|
|
#[deprecated = "renamed to slice::from_raw_mut_buf"]
|
2014-04-30 22:54:25 -07:00
|
|
|
pub unsafe fn mut_buf_as_slice<T,
|
|
|
|
U>(
|
|
|
|
p: *mut T,
|
|
|
|
len: uint,
|
|
|
|
f: |v: &mut [T]| -> U)
|
|
|
|
-> U {
|
|
|
|
f(transmute(Slice {
|
2014-06-25 12:47:34 -07:00
|
|
|
data: p as *const T,
|
2014-04-30 22:54:25 -07:00
|
|
|
len: len
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// Returns a pointer to first element in slice and adjusts
|
|
|
|
/// slice so it no longer contains that element. Returns None
|
|
|
|
/// if the slice is empty. O(1).
|
|
|
|
#[inline]
|
2014-11-20 10:11:15 -08:00
|
|
|
#[deprecated = "inspect `Slice::{data, len}` manually (increment data by 1)"]
|
2014-06-25 12:47:34 -07:00
|
|
|
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
|
2014-05-12 19:44:19 +01:00
|
|
|
if slice.len == 0 { return None; }
|
2014-06-25 12:47:34 -07:00
|
|
|
let head: *const T = slice.data;
|
2014-04-30 22:54:25 -07:00
|
|
|
slice.data = slice.data.offset(1);
|
|
|
|
slice.len -= 1;
|
2014-05-12 19:44:19 +01:00
|
|
|
Some(head)
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// Returns a pointer to last element in slice and adjusts
|
|
|
|
/// slice so it no longer contains that element. Returns None
|
|
|
|
/// if the slice is empty. O(1).
|
2014-11-20 10:11:15 -08:00
|
|
|
#[inline]
|
|
|
|
#[deprecated = "inspect `Slice::{data, len}` manually (decrement len by 1)"]
|
2014-06-25 12:47:34 -07:00
|
|
|
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
|
2014-05-12 19:44:19 +01:00
|
|
|
if slice.len == 0 { return None; }
|
2014-06-25 12:47:34 -07:00
|
|
|
let tail: *const T = slice.data.offset((slice.len - 1) as int);
|
2014-04-30 22:54:25 -07:00
|
|
|
slice.len -= 1;
|
2014-05-12 19:44:19 +01:00
|
|
|
Some(tail)
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Operations on `[u8]`.
|
2014-08-06 23:59:12 -07:00
|
|
|
#[experimental = "needs review"]
|
2014-04-30 22:54:25 -07:00
|
|
|
pub mod bytes {
|
2014-10-23 10:43:18 -05:00
|
|
|
use kinds::Sized;
|
2014-04-30 22:54:25 -07:00
|
|
|
use ptr;
|
2014-11-02 17:04:32 -08:00
|
|
|
use slice::SlicePrelude;
|
2014-04-30 22:54:25 -07:00
|
|
|
|
|
|
|
/// A trait for operations on mutable `[u8]`s.
|
2014-10-23 10:43:18 -05:00
|
|
|
pub trait MutableByteVector for Sized? {
|
2014-04-30 22:54:25 -07:00
|
|
|
/// Sets all bytes of the receiver to the given value.
|
2014-10-23 10:43:18 -05:00
|
|
|
fn set_memory(&mut self, value: u8);
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2014-10-23 10:43:18 -05:00
|
|
|
impl MutableByteVector for [u8] {
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2014-05-29 17:40:18 -07:00
|
|
|
#[allow(experimental)]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn set_memory(&mut self, value: u8) {
|
2014-04-30 22:54:25 -07:00
|
|
|
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Copies data from `src` to `dst`
|
|
|
|
///
|
2014-12-02 17:32:37 -08:00
|
|
|
/// Panics if the length of `dst` is less than the length of `src`.
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
|
|
|
pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
|
2014-10-14 23:05:01 -07:00
|
|
|
let len_src = src.len();
|
|
|
|
assert!(dst.len() >= len_src);
|
2014-12-02 17:32:37 -08:00
|
|
|
// `dst` is unaliasable, so we know statically it doesn't overlap
|
|
|
|
// with `src`.
|
2014-10-14 23:05:01 -07:00
|
|
|
unsafe {
|
|
|
|
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(),
|
|
|
|
src.as_ptr(),
|
|
|
|
len_src);
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
|
|
|
// Boilerplate traits
|
|
|
|
//
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-10-29 20:11:16 -05:00
|
|
|
#[unstable = "waiting for DST"]
|
2014-11-21 00:14:05 -05:00
|
|
|
impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
|
|
|
|
fn eq(&self, other: &[B]) -> bool {
|
2014-10-29 20:11:16 -05:00
|
|
|
self.len() == other.len() &&
|
|
|
|
order::eq(self.iter(), other.iter())
|
|
|
|
}
|
2014-11-21 00:14:05 -05:00
|
|
|
fn ne(&self, other: &[B]) -> bool {
|
2014-10-29 20:11:16 -05:00
|
|
|
self.len() != other.len() ||
|
|
|
|
order::ne(self.iter(), other.iter())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable = "waiting for DST"]
|
|
|
|
impl<T: Eq> Eq for [T] {}
|
|
|
|
|
2014-11-26 23:50:12 -05:00
|
|
|
#[allow(deprecated)]
|
|
|
|
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
|
2014-11-04 15:31:46 -08:00
|
|
|
impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for [T] {
|
2014-06-30 15:43:13 -07:00
|
|
|
#[inline]
|
|
|
|
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2014-11-26 23:50:12 -05:00
|
|
|
#[allow(deprecated)]
|
|
|
|
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
|
2014-11-04 15:31:46 -08:00
|
|
|
impl<'a,T:PartialEq, Sized? V: AsSlice<T>> Equiv<V> for &'a mut [T] {
|
2014-08-06 11:59:40 +02:00
|
|
|
#[inline]
|
|
|
|
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
|
|
|
|
}
|
|
|
|
|
2014-10-29 20:11:16 -05:00
|
|
|
#[unstable = "waiting for DST"]
|
|
|
|
impl<T: Ord> Ord for [T] {
|
|
|
|
fn cmp(&self, other: &[T]) -> Ordering {
|
|
|
|
order::cmp(self.iter(), other.iter())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable = "waiting for DST"]
|
|
|
|
impl<T: PartialOrd> PartialOrd for [T] {
|
|
|
|
#[inline]
|
|
|
|
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
|
|
|
|
order::partial_cmp(self.iter(), other.iter())
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn lt(&self, other: &[T]) -> bool {
|
|
|
|
order::lt(self.iter(), other.iter())
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn le(&self, other: &[T]) -> bool {
|
|
|
|
order::le(self.iter(), other.iter())
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn ge(&self, other: &[T]) -> bool {
|
|
|
|
order::ge(self.iter(), other.iter())
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn gt(&self, other: &[T]) -> bool {
|
|
|
|
order::gt(self.iter(), other.iter())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-03 20:34:32 +02:00
|
|
|
/// Extension methods for immutable slices containing integers.
|
|
|
|
#[experimental]
|
2014-10-23 10:43:18 -05:00
|
|
|
pub trait ImmutableIntSlice<U, S> for Sized? {
|
2014-10-03 20:34:32 +02:00
|
|
|
/// Converts the slice to an immutable slice of unsigned integers with the same width.
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_unsigned<'a>(&'a self) -> &'a [U];
|
2014-10-03 20:34:32 +02:00
|
|
|
/// Converts the slice to an immutable slice of signed integers with the same width.
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_signed<'a>(&'a self) -> &'a [S];
|
2014-10-03 20:34:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Extension methods for mutable slices containing integers.
|
|
|
|
#[experimental]
|
2014-10-23 10:43:18 -05:00
|
|
|
pub trait MutableIntSlice<U, S> for Sized?: ImmutableIntSlice<U, S> {
|
2014-10-03 20:34:32 +02:00
|
|
|
/// Converts the slice to a mutable slice of unsigned integers with the same width.
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_unsigned_mut<'a>(&'a mut self) -> &'a mut [U];
|
2014-10-03 20:34:32 +02:00
|
|
|
/// Converts the slice to a mutable slice of signed integers with the same width.
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_signed_mut<'a>(&'a mut self) -> &'a mut [S];
|
2014-10-03 20:34:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! impl_immut_int_slice {
|
|
|
|
($u:ty, $s:ty, $t:ty) => {
|
|
|
|
#[experimental]
|
2014-10-23 10:43:18 -05:00
|
|
|
impl ImmutableIntSlice<$u, $s> for [$t] {
|
2014-10-03 20:34:32 +02:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } }
|
2014-10-03 20:34:32 +02:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } }
|
2014-10-03 20:34:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
macro_rules! impl_mut_int_slice {
|
|
|
|
($u:ty, $s:ty, $t:ty) => {
|
|
|
|
#[experimental]
|
2014-10-23 10:43:18 -05:00
|
|
|
impl MutableIntSlice<$u, $s> for [$t] {
|
2014-10-03 20:34:32 +02:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } }
|
2014-10-03 20:34:32 +02:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_signed_mut(&mut self) -> &mut [$s] { unsafe { transmute(self) } }
|
2014-10-03 20:34:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! impl_int_slice {
|
|
|
|
($u:ty, $s:ty) => {
|
2014-10-23 10:43:18 -05:00
|
|
|
impl_immut_int_slice!($u, $s, $u)
|
|
|
|
impl_immut_int_slice!($u, $s, $s)
|
|
|
|
impl_mut_int_slice!($u, $s, $u)
|
|
|
|
impl_mut_int_slice!($u, $s, $s)
|
2014-10-03 20:34:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_int_slice!(u8, i8)
|
|
|
|
impl_int_slice!(u16, i16)
|
|
|
|
impl_int_slice!(u32, i32)
|
|
|
|
impl_int_slice!(u64, i64)
|
|
|
|
impl_int_slice!(uint, int)
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
|