2017-03-17 15:05:44 +01:00
|
|
|
// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
|
2014-04-30 22:54:25 -07:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
//! Slice management and manipulation
|
|
|
|
//!
|
2017-03-14 13:42:12 -04:00
|
|
|
//! For more details see [`std::slice`].
|
|
|
|
//!
|
|
|
|
//! [`std::slice`]: ../../std/slice/index.html
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#![stable(feature = "rust1", since = "1.0.0")]
|
2014-05-28 19:53:37 -07:00
|
|
|
|
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.
|
|
|
|
|
2016-08-22 10:02:28 +00:00
|
|
|
use cmp::Ordering::{self, Less, Equal, Greater};
|
2014-04-30 22:54:25 -07:00
|
|
|
use cmp;
|
2016-03-04 18:49:43 -08:00
|
|
|
use fmt;
|
2015-02-02 19:25:44 +01:00
|
|
|
use intrinsics::assume;
|
2014-04-30 22:54:25 -07:00
|
|
|
use iter::*;
|
2017-10-22 22:47:27 -07:00
|
|
|
use ops::{FnMut, Try, self};
|
2016-07-19 10:50:52 +02:00
|
|
|
use option::Option;
|
|
|
|
use option::Option::{None, Some};
|
|
|
|
use result::Result;
|
|
|
|
use result::Result::{Ok, Err};
|
2014-04-30 22:54:25 -07:00
|
|
|
use ptr;
|
|
|
|
use mem;
|
2016-07-19 10:50:52 +02:00
|
|
|
use marker::{Copy, Send, Sync, Sized, self};
|
2016-04-21 21:35:39 +02:00
|
|
|
use iter_private::TrustedRandomAccess;
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2017-12-13 01:02:19 -06:00
|
|
|
#[unstable(feature = "slice_internals", issue = "0",
|
|
|
|
reason = "exposed from core to be reused in std; use the memchr crate")]
|
|
|
|
/// Pure rust memchr implementation, taken from rust-memchr
|
|
|
|
pub mod memchr;
|
|
|
|
|
2017-04-30 23:50:59 -07:00
|
|
|
mod rotate;
|
2017-03-17 15:05:44 +01:00
|
|
|
mod sort;
|
|
|
|
|
2016-04-07 10:42:53 -07:00
|
|
|
#[repr(C)]
|
|
|
|
struct Repr<T> {
|
|
|
|
pub data: *const T,
|
|
|
|
pub len: usize,
|
|
|
|
}
|
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.
|
2015-06-09 11:18:03 -07:00
|
|
|
#[unstable(feature = "core_slice_ext",
|
2015-08-12 17:23:48 -07:00
|
|
|
reason = "stable interface provided by `impl [T]` in later crates",
|
2016-03-07 16:34:35 -08:00
|
|
|
issue = "32110")]
|
2015-12-02 17:31:49 -08:00
|
|
|
#[allow(missing_docs)] // documented elsewhere
|
2015-01-04 21:39:02 -05:00
|
|
|
pub trait SliceExt {
|
2015-01-02 09:12:27 -05:00
|
|
|
type Item;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split_at(&self, mid: usize) -> (&[Self::Item], &[Self::Item]);
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn iter(&self) -> Iter<Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split<P>(&self, pred: P) -> Split<Self::Item, P>
|
2017-03-17 15:05:44 +01:00
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2017-04-03 15:25:30 -05:00
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
fn rsplit<P>(&self, pred: P) -> RSplit<Self::Item, P>
|
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P>
|
2017-03-17 15:05:44 +01:00
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn rsplitn<P>(&self, n: usize, pred: P) -> RSplitN<Self::Item, P>
|
2017-03-17 15:05:44 +01:00
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn windows(&self, size: usize) -> Windows<Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn chunks(&self, size: usize) -> Chunks<Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get<I>(&self, index: I) -> Option<&I::Output>
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<Self>;
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn first(&self) -> Option<&Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split_first(&self) -> Option<(&Self::Item, &[Self::Item])>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn last(&self) -> Option<&Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2016-07-19 10:50:52 +02:00
|
|
|
unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<Self>;
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn as_ptr(&self) -> *const Self::Item;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2017-08-18 12:20:04 -05:00
|
|
|
fn binary_search(&self, x: &Self::Item) -> Result<usize, usize>
|
|
|
|
where Self::Item: Ord;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2016-07-11 18:18:11 +05:30
|
|
|
fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
|
|
|
|
where F: FnMut(&'a Self::Item) -> Ordering;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
std: Stabilize APIs for the 1.10 release
This commit applies the FCP decisions made by the libs team for the 1.10 cycle,
including both new stabilizations and deprecations. Specifically, the list of
APIs is:
Stabilized:
* `os::windows::fs::OpenOptionsExt::access_mode`
* `os::windows::fs::OpenOptionsExt::share_mode`
* `os::windows::fs::OpenOptionsExt::custom_flags`
* `os::windows::fs::OpenOptionsExt::attributes`
* `os::windows::fs::OpenOptionsExt::security_qos_flags`
* `os::unix::fs::OpenOptionsExt::custom_flags`
* `sync::Weak::new`
* `Default for sync::Weak`
* `panic::set_hook`
* `panic::take_hook`
* `panic::PanicInfo`
* `panic::PanicInfo::payload`
* `panic::PanicInfo::location`
* `panic::Location`
* `panic::Location::file`
* `panic::Location::line`
* `ffi::CStr::from_bytes_with_nul`
* `ffi::CStr::from_bytes_with_nul_unchecked`
* `ffi::FromBytesWithNulError`
* `fs::Metadata::modified`
* `fs::Metadata::accessed`
* `fs::Metadata::created`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange`
* `sync::atomic::Atomic{Usize,Isize,Bool,Ptr}::compare_exchange_weak`
* `collections::{btree,hash}_map::{Occupied,Vacant,}Entry::key`
* `os::unix::net::{UnixStream, UnixListener, UnixDatagram, SocketAddr}`
* `SocketAddr::is_unnamed`
* `SocketAddr::as_pathname`
* `UnixStream::connect`
* `UnixStream::pair`
* `UnixStream::try_clone`
* `UnixStream::local_addr`
* `UnixStream::peer_addr`
* `UnixStream::set_read_timeout`
* `UnixStream::set_write_timeout`
* `UnixStream::read_timeout`
* `UnixStream::write_Timeout`
* `UnixStream::set_nonblocking`
* `UnixStream::take_error`
* `UnixStream::shutdown`
* Read/Write/RawFd impls for `UnixStream`
* `UnixListener::bind`
* `UnixListener::accept`
* `UnixListener::try_clone`
* `UnixListener::local_addr`
* `UnixListener::set_nonblocking`
* `UnixListener::take_error`
* `UnixListener::incoming`
* RawFd impls for `UnixListener`
* `UnixDatagram::bind`
* `UnixDatagram::unbound`
* `UnixDatagram::pair`
* `UnixDatagram::connect`
* `UnixDatagram::try_clone`
* `UnixDatagram::local_addr`
* `UnixDatagram::peer_addr`
* `UnixDatagram::recv_from`
* `UnixDatagram::recv`
* `UnixDatagram::send_to`
* `UnixDatagram::send`
* `UnixDatagram::set_read_timeout`
* `UnixDatagram::set_write_timeout`
* `UnixDatagram::read_timeout`
* `UnixDatagram::write_timeout`
* `UnixDatagram::set_nonblocking`
* `UnixDatagram::take_error`
* `UnixDatagram::shutdown`
* RawFd impls for `UnixDatagram`
* `{BTree,Hash}Map::values_mut`
* `<[_]>::binary_search_by_key`
Deprecated:
* `StaticCondvar` - this, and all other static synchronization primitives
below, are usable today through the lazy-static crate on
stable Rust today. Additionally, we'd like the non-static
versions to be directly usable in a static context one day,
so they're unlikely to be the final forms of the APIs in any
case.
* `CONDVAR_INIT`
* `StaticMutex`
* `MUTEX_INIT`
* `StaticRwLock`
* `RWLOCK_INIT`
* `iter::Peekable::is_empty`
Closes #27717
Closes #27720
cc #27784 (but encode methods still exist)
Closes #30014
Closes #30425
Closes #30449
Closes #31190
Closes #31399
Closes #31767
Closes #32111
Closes #32281
Closes #32312
Closes #32551
Closes #33018
2016-05-17 11:57:07 -07:00
|
|
|
#[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
|
2017-08-18 12:20:04 -05:00
|
|
|
fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
|
2016-07-11 18:18:11 +05:30
|
|
|
where F: FnMut(&'a Self::Item) -> B,
|
2017-08-18 12:20:04 -05:00
|
|
|
B: Ord;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn len(&self) -> usize;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2014-10-30 13:43:24 -07:00
|
|
|
fn is_empty(&self) -> bool { self.len() == 0 }
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<Self>;
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn iter_mut(&mut self) -> IterMut<Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn first_mut(&mut self) -> Option<&mut Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split_first_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split_last_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn last_mut(&mut self) -> Option<&mut Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P>
|
2017-03-17 15:05:44 +01:00
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2017-04-03 15:25:30 -05:00
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<Self::Item, P>
|
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P>
|
2017-03-17 15:05:44 +01:00
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn rsplitn_mut<P>(&mut self, n: usize, pred: P) -> RSplitNMut<Self::Item, P>
|
2017-03-17 15:05:44 +01:00
|
|
|
where P: FnMut(&Self::Item) -> bool;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn swap(&mut self, a: usize, b: usize);
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn split_at_mut(&mut self, mid: usize) -> (&mut [Self::Item], &mut [Self::Item]);
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn reverse(&mut self);
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2016-07-19 10:50:52 +02:00
|
|
|
unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<Self>;
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn as_mut_ptr(&mut self) -> *mut Self::Item;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
|
|
|
|
|
2017-05-10 10:23:19 -07:00
|
|
|
#[unstable(feature = "slice_rotate", issue = "41891")]
|
2017-05-21 03:05:19 -07:00
|
|
|
fn rotate(&mut self, mid: usize);
|
2017-04-30 23:50:59 -07:00
|
|
|
|
2016-01-15 10:07:52 -08:00
|
|
|
#[stable(feature = "clone_from_slice", since = "1.7.0")]
|
2016-04-07 10:42:53 -07:00
|
|
|
fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2016-04-07 10:42:53 -07:00
|
|
|
#[stable(feature = "copy_from_slice", since = "1.9.0")]
|
2016-02-22 23:06:53 -08:00
|
|
|
fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
|
2017-03-17 15:05:44 +01:00
|
|
|
|
2017-08-21 22:20:00 -07:00
|
|
|
#[unstable(feature = "swap_with_slice", issue = "44030")]
|
|
|
|
fn swap_with_slice(&mut self, src: &mut [Self::Item]);
|
|
|
|
|
2017-07-02 11:16:37 +02:00
|
|
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn sort_unstable(&mut self)
|
|
|
|
where Self::Item: Ord;
|
|
|
|
|
2017-07-02 11:16:37 +02:00
|
|
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn sort_unstable_by<F>(&mut self, compare: F)
|
|
|
|
where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
|
|
|
|
|
2017-07-02 11:16:37 +02:00
|
|
|
#[stable(feature = "sort_unstable", since = "1.20.0")]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn sort_unstable_by_key<B, F>(&mut self, f: F)
|
|
|
|
where F: FnMut(&Self::Item) -> B,
|
|
|
|
B: Ord;
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2015-05-15 15:20:42 +02:00
|
|
|
// Use macros to be generic over const/mut
|
|
|
|
macro_rules! slice_offset {
|
|
|
|
($ptr:expr, $by:expr) => {{
|
|
|
|
let ptr = $ptr;
|
|
|
|
if size_from_ptr(ptr) == 0 {
|
2016-11-23 23:02:30 +01:00
|
|
|
(ptr as *mut i8).wrapping_offset($by) as _
|
2015-05-15 15:20:42 +02:00
|
|
|
} else {
|
|
|
|
ptr.offset($by)
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2016-11-23 23:02:30 +01:00
|
|
|
// make a &T from a *const T
|
|
|
|
macro_rules! make_ref {
|
|
|
|
($ptr:expr) => {{
|
|
|
|
let ptr = $ptr;
|
|
|
|
if size_from_ptr(ptr) == 0 {
|
|
|
|
// Use a non-null pointer value
|
|
|
|
&*(1 as *mut _)
|
|
|
|
} else {
|
|
|
|
&*ptr
|
|
|
|
}
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
|
|
|
// make a &mut T from a *mut T
|
|
|
|
macro_rules! make_ref_mut {
|
2015-05-15 15:20:42 +02:00
|
|
|
($ptr:expr) => {{
|
|
|
|
let ptr = $ptr;
|
|
|
|
if size_from_ptr(ptr) == 0 {
|
|
|
|
// Use a non-null pointer value
|
|
|
|
&mut *(1 as *mut _)
|
|
|
|
} else {
|
2016-11-23 23:02:30 +01:00
|
|
|
&mut *ptr
|
2015-05-15 15:20:42 +02:00
|
|
|
}
|
|
|
|
}};
|
|
|
|
}
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
#[unstable(feature = "core_slice_ext",
|
|
|
|
reason = "stable interface provided by `impl [T]` in later crates",
|
2016-03-07 16:34:35 -08:00
|
|
|
issue = "32110")]
|
2015-01-02 09:12:27 -05:00
|
|
|
impl<T> SliceExt for [T] {
|
|
|
|
type Item = T;
|
|
|
|
|
2014-11-02 17:04:32 -08:00
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn split_at(&self, mid: usize) -> (&[T], &[T]) {
|
2015-01-12 16:59:18 -05:00
|
|
|
(&self[..mid], &self[mid..])
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn iter(&self) -> Iter<T> {
|
2014-11-02 17:04:32 -08:00
|
|
|
unsafe {
|
2015-05-15 15:20:42 +02:00
|
|
|
let p = if mem::size_of::<T>() == 0 {
|
|
|
|
1 as *const _
|
2014-11-02 17:04:32 -08:00
|
|
|
} else {
|
2015-05-15 15:20:42 +02:00
|
|
|
let p = self.as_ptr();
|
|
|
|
assume(!p.is_null());
|
|
|
|
p
|
|
|
|
};
|
|
|
|
|
|
|
|
Iter {
|
|
|
|
ptr: p,
|
|
|
|
end: slice_offset!(p, self.len() as isize),
|
|
|
|
_marker: marker::PhantomData
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn split<P>(&self, pred: P) -> Split<T, P>
|
|
|
|
where P: FnMut(&T) -> bool
|
|
|
|
{
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
Split {
|
2014-11-02 17:04:32 -08:00
|
|
|
v: self,
|
2017-08-06 22:54:09 -07:00
|
|
|
pred,
|
2014-11-02 17:04:32 -08:00
|
|
|
finished: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-03 15:25:30 -05:00
|
|
|
#[inline]
|
|
|
|
fn rsplit<P>(&self, pred: P) -> RSplit<T, P>
|
|
|
|
where P: FnMut(&T) -> bool
|
|
|
|
{
|
|
|
|
RSplit { inner: self.split(pred) }
|
|
|
|
}
|
|
|
|
|
2014-11-02 17:04:32 -08:00
|
|
|
#[inline]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn splitn<P>(&self, n: usize, pred: P) -> SplitN<T, P>
|
|
|
|
where P: FnMut(&T) -> bool
|
2014-12-04 23:47:40 -05:00
|
|
|
{
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
SplitN {
|
|
|
|
inner: GenericSplitN {
|
|
|
|
iter: self.split(pred),
|
2017-04-03 15:27:42 -05:00
|
|
|
count: n
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
}
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn rsplitn<P>(&self, n: usize, pred: P) -> RSplitN<T, P>
|
|
|
|
where P: FnMut(&T) -> bool
|
2014-12-04 23:47:40 -05:00
|
|
|
{
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
RSplitN {
|
|
|
|
inner: GenericSplitN {
|
2017-04-03 15:27:42 -05:00
|
|
|
iter: self.rsplit(pred),
|
|
|
|
count: n
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
}
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn windows(&self, size: usize) -> Windows<T> {
|
2014-11-02 17:04:32 -08:00
|
|
|
assert!(size != 0);
|
|
|
|
Windows { v: self, size: size }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2018-01-02 01:46:50 +02:00
|
|
|
fn chunks(&self, chunk_size: usize) -> Chunks<T> {
|
|
|
|
assert!(chunk_size != 0);
|
|
|
|
Chunks { v: self, chunk_size: chunk_size }
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get<I>(&self, index: I) -> Option<&I::Output>
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<[T]>
|
2016-07-19 10:50:52 +02:00
|
|
|
{
|
|
|
|
index.get(self)
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
fn first(&self) -> Option<&T> {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.is_empty() { None } else { Some(&self[0]) }
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-07-11 14:34:57 +03:00
|
|
|
fn split_first(&self) -> Option<(&T, &[T])> {
|
|
|
|
if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn split_last(&self) -> Option<(&T, &[T])> {
|
|
|
|
let len = self.len();
|
|
|
|
if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn last(&self) -> Option<&T> {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.is_empty() { None } else { Some(&self[self.len() - 1]) }
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<[T]>
|
2016-07-19 10:50:52 +02:00
|
|
|
{
|
|
|
|
index.get_unchecked(self)
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn as_ptr(&self) -> *const T {
|
2016-03-01 20:21:55 +01:00
|
|
|
self as *const [T] as *const T
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
2016-07-11 18:18:11 +05:30
|
|
|
fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
|
|
|
|
where F: FnMut(&'a T) -> Ordering
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
{
|
2017-10-16 14:05:16 +02:00
|
|
|
let s = self;
|
|
|
|
let mut size = s.len();
|
|
|
|
if size == 0 {
|
|
|
|
return Err(0);
|
|
|
|
}
|
2016-01-14 18:05:00 -02:00
|
|
|
let mut base = 0usize;
|
2017-10-16 14:05:16 +02:00
|
|
|
while size > 1 {
|
|
|
|
let half = size / 2;
|
|
|
|
let mid = base + half;
|
2017-12-20 11:43:49 +01:00
|
|
|
// mid is always in [0, size), that means mid is >= 0 and < size.
|
2017-10-16 14:05:16 +02:00
|
|
|
// mid >= 0: by definition
|
|
|
|
// mid < size: mid = size / 2 + size / 4 + size / 8 ...
|
|
|
|
let cmp = f(unsafe { s.get_unchecked(mid) });
|
|
|
|
base = if cmp == Greater { base } else { mid };
|
|
|
|
size -= half;
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
2017-10-16 14:05:16 +02:00
|
|
|
// base is always in [0, size) because base <= mid.
|
|
|
|
let cmp = f(unsafe { s.get_unchecked(base) });
|
|
|
|
if cmp == Equal { Ok(base) } else { Err(base + (cmp == Less) as usize) }
|
2014-11-02 17:04:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2016-04-07 10:42:53 -07:00
|
|
|
fn len(&self) -> usize {
|
|
|
|
unsafe {
|
|
|
|
mem::transmute::<&[T], Repr<T>>(self).len
|
|
|
|
}
|
|
|
|
}
|
2014-11-02 17:04:32 -08:00
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<[T]>
|
2016-07-19 10:50:52 +02:00
|
|
|
{
|
|
|
|
index.get_mut(self)
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2015-03-21 19:33:27 -04:00
|
|
|
#[inline]
|
|
|
|
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
|
2015-07-28 19:54:13 +02:00
|
|
|
let len = self.len();
|
|
|
|
let ptr = self.as_mut_ptr();
|
2015-09-07 10:16:57 -04:00
|
|
|
|
2015-03-21 19:33:27 -04:00
|
|
|
unsafe {
|
2015-09-07 10:16:57 -04:00
|
|
|
assert!(mid <= len);
|
|
|
|
|
2015-07-28 19:54:13 +02:00
|
|
|
(from_raw_parts_mut(ptr, mid),
|
|
|
|
from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn iter_mut(&mut self) -> IterMut<T> {
|
2014-06-30 13:58:53 -07:00
|
|
|
unsafe {
|
2015-05-15 15:20:42 +02:00
|
|
|
let p = if mem::size_of::<T>() == 0 {
|
|
|
|
1 as *mut _
|
2014-06-30 13:58:53 -07:00
|
|
|
} else {
|
2015-05-15 15:20:42 +02:00
|
|
|
let p = self.as_mut_ptr();
|
|
|
|
assume(!p.is_null());
|
|
|
|
p
|
|
|
|
};
|
|
|
|
|
|
|
|
IterMut {
|
|
|
|
ptr: p,
|
|
|
|
end: slice_offset!(p, self.len() as isize),
|
|
|
|
_marker: marker::PhantomData
|
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 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]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
fn first_mut(&mut self) -> Option<&mut T> {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.is_empty() { None } else { Some(&mut self[0]) }
|
2014-09-22 16:23:00 -07:00
|
|
|
}
|
|
|
|
|
2015-07-11 14:34:57 +03:00
|
|
|
#[inline]
|
|
|
|
fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
|
|
|
|
if self.is_empty() { None } else {
|
|
|
|
let split = self.split_at_mut(1);
|
|
|
|
Some((&mut split.0[0], split.1))
|
|
|
|
}
|
2014-09-22 16:23:00 -07:00
|
|
|
}
|
|
|
|
|
2015-07-11 14:34:57 +03:00
|
|
|
#[inline]
|
|
|
|
fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
|
|
|
|
let len = self.len();
|
|
|
|
if len == 0 { None } else {
|
|
|
|
let split = self.split_at_mut(len - 1);
|
|
|
|
Some((&mut split.1[0], split.0))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn split_mut<P>(&mut self, pred: P) -> SplitMut<T, P>
|
|
|
|
where P: FnMut(&T) -> bool
|
|
|
|
{
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
SplitMut { v: self, pred: pred, finished: false }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2017-04-03 15:25:30 -05:00
|
|
|
#[inline]
|
|
|
|
fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<T, P>
|
|
|
|
where P: FnMut(&T) -> bool
|
|
|
|
{
|
|
|
|
RSplitMut { inner: self.split_mut(pred) }
|
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
#[inline]
|
2017-03-17 15:05:44 +01:00
|
|
|
fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<T, P>
|
|
|
|
where P: FnMut(&T) -> bool
|
2014-12-05 01:00:50 -05:00
|
|
|
{
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
SplitNMut {
|
|
|
|
inner: GenericSplitN {
|
|
|
|
iter: self.split_mut(pred),
|
2017-04-03 15:27:42 -05:00
|
|
|
count: n
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
}
|
2014-09-22 16:23:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-09-03 15:19:08 +05:30
|
|
|
fn rsplitn_mut<P>(&mut self, n: usize, pred: P) -> RSplitNMut<T, P> where
|
2014-12-05 01:00:50 -05:00
|
|
|
P: FnMut(&T) -> bool,
|
|
|
|
{
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
RSplitNMut {
|
|
|
|
inner: GenericSplitN {
|
2017-04-03 15:27:42 -05:00
|
|
|
iter: self.rsplit_mut(pred),
|
|
|
|
count: n
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
}
|
2014-09-22 16:23:00 -07:00
|
|
|
}
|
2017-03-17 15:05:44 +01:00
|
|
|
}
|
2014-09-22 16:23:00 -07:00
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
|
2018-01-02 01:57:46 +02:00
|
|
|
assert!(chunk_size != 0);
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
ChunksMut { v: self, chunk_size: chunk_size }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2015-03-02 22:06:51 -06:00
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn swap(&mut self, a: usize, b: usize) {
|
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) {
|
2015-02-14 16:04:47 -08:00
|
|
|
let mut i: usize = 0;
|
2014-06-30 13:58:53 -07:00
|
|
|
let ln = self.len();
|
2017-05-04 20:28:34 -07:00
|
|
|
|
2017-05-05 18:54:47 -07:00
|
|
|
// For very small types, all the individual reads in the normal
|
|
|
|
// path perform poorly. We can do better, given efficient unaligned
|
|
|
|
// load/store, by loading a larger chunk and reversing a register.
|
|
|
|
|
|
|
|
// Ideally LLVM would do this for us, as it knows better than we do
|
|
|
|
// whether unaligned reads are efficient (since that changes between
|
|
|
|
// different ARM versions, for example) and what the best chunk size
|
|
|
|
// would be. Unfortunately, as of LLVM 4.0 (2017-05) it only unrolls
|
|
|
|
// the loop, so we need to do this ourselves. (Hypothesis: reverse
|
|
|
|
// is troublesome because the sides can be aligned differently --
|
|
|
|
// will be, when the length is odd -- so there's no way of emitting
|
|
|
|
// pre- and postludes to use fully-aligned SIMD in the middle.)
|
|
|
|
|
2017-05-04 20:28:34 -07:00
|
|
|
let fast_unaligned =
|
|
|
|
cfg!(any(target_arch = "x86", target_arch = "x86_64"));
|
|
|
|
|
|
|
|
if fast_unaligned && mem::size_of::<T>() == 1 {
|
2017-05-05 18:54:47 -07:00
|
|
|
// Use the llvm.bswap intrinsic to reverse u8s in a usize
|
2017-05-04 20:28:34 -07:00
|
|
|
let chunk = mem::size_of::<usize>();
|
|
|
|
while i + chunk - 1 < ln / 2 {
|
|
|
|
unsafe {
|
|
|
|
let pa: *mut T = self.get_unchecked_mut(i);
|
|
|
|
let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
|
|
|
|
let va = ptr::read_unaligned(pa as *mut usize);
|
|
|
|
let vb = ptr::read_unaligned(pb as *mut usize);
|
|
|
|
ptr::write_unaligned(pa as *mut usize, vb.swap_bytes());
|
|
|
|
ptr::write_unaligned(pb as *mut usize, va.swap_bytes());
|
|
|
|
}
|
|
|
|
i += chunk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if fast_unaligned && mem::size_of::<T>() == 2 {
|
2017-05-05 18:54:47 -07:00
|
|
|
// Use rotate-by-16 to reverse u16s in a u32
|
2017-05-04 20:28:34 -07:00
|
|
|
let chunk = mem::size_of::<u32>() / 2;
|
|
|
|
while i + chunk - 1 < ln / 2 {
|
|
|
|
unsafe {
|
|
|
|
let pa: *mut T = self.get_unchecked_mut(i);
|
|
|
|
let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
|
|
|
|
let va = ptr::read_unaligned(pa as *mut u32);
|
|
|
|
let vb = ptr::read_unaligned(pb as *mut u32);
|
|
|
|
ptr::write_unaligned(pa as *mut u32, vb.rotate_left(16));
|
|
|
|
ptr::write_unaligned(pb as *mut u32, va.rotate_left(16));
|
|
|
|
}
|
|
|
|
i += chunk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
while i < ln / 2 {
|
2014-09-04 19:54:41 -07:00
|
|
|
// Unsafe swap to avoid the bounds check in safe swap.
|
|
|
|
unsafe {
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
let pa: *mut T = self.get_unchecked_mut(i);
|
|
|
|
let pb: *mut T = self.get_unchecked_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]
|
2016-07-19 10:50:52 +02:00
|
|
|
unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<[T]>
|
2016-07-19 10:50:52 +02:00
|
|
|
{
|
|
|
|
index.get_unchecked_mut(self)
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_mut_ptr(&mut self) -> *mut T {
|
2016-03-01 20:21:55 +01:00
|
|
|
self as *mut [T] as *mut T
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-11-02 17:04:32 -08:00
|
|
|
|
2014-04-30 22:54:25 -07:00
|
|
|
#[inline]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn contains(&self, x: &T) -> bool where T: PartialEq {
|
2017-12-13 09:11:42 -06:00
|
|
|
x.slice_contains(self)
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
|
2014-04-30 22:54:25 -07:00
|
|
|
let n = needle.len();
|
2015-01-12 16:59:18 -05:00
|
|
|
self.len() >= n && needle == &self[..n]
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-01-02 09:12:27 -05:00
|
|
|
fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
|
2014-04-30 22:54:25 -07:00
|
|
|
let (m, n) = (self.len(), needle.len());
|
2015-01-19 11:07:13 -05:00
|
|
|
m >= n && needle == &self[m-n..]
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
2017-08-18 12:20:04 -05:00
|
|
|
fn binary_search(&self, x: &T) -> Result<usize, usize>
|
|
|
|
where T: Ord
|
2017-03-17 15:05:44 +01:00
|
|
|
{
|
2017-08-18 12:20:04 -05:00
|
|
|
self.binary_search_by(|p| p.cmp(x))
|
2014-08-06 20:48:25 -07:00
|
|
|
}
|
2014-11-02 17:04:32 -08:00
|
|
|
|
2017-05-21 03:05:19 -07:00
|
|
|
fn rotate(&mut self, mid: usize) {
|
2017-04-30 23:50:59 -07:00
|
|
|
assert!(mid <= self.len());
|
|
|
|
let k = self.len() - mid;
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let p = self.as_mut_ptr();
|
|
|
|
rotate::ptr_rotate(mid, p.offset(mid as isize), k);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
2016-01-15 10:07:52 -08:00
|
|
|
fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
|
|
|
|
assert!(self.len() == src.len(),
|
|
|
|
"destination and source slices have different lengths");
|
2016-01-18 14:51:56 +01:00
|
|
|
// NOTE: We need to explicitly slice them to the same length
|
|
|
|
// for bounds checking to be elided, and the optimizer will
|
|
|
|
// generate memcpy for simple cases (for example T = u8).
|
|
|
|
let len = self.len();
|
|
|
|
let src = &src[..len];
|
|
|
|
for i in 0..len {
|
|
|
|
self[i].clone_from(&src[i]);
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
2016-02-22 23:06:53 -08:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
|
|
|
|
assert!(self.len() == src.len(),
|
|
|
|
"destination and source slices have different lengths");
|
|
|
|
unsafe {
|
|
|
|
ptr::copy_nonoverlapping(
|
|
|
|
src.as_ptr(), self.as_mut_ptr(), self.len());
|
|
|
|
}
|
|
|
|
}
|
2016-03-22 21:26:57 -04:00
|
|
|
|
2017-08-21 22:20:00 -07:00
|
|
|
#[inline]
|
|
|
|
fn swap_with_slice(&mut self, src: &mut [T]) {
|
|
|
|
assert!(self.len() == src.len(),
|
|
|
|
"destination and source slices have different lengths");
|
|
|
|
unsafe {
|
|
|
|
ptr::swap_nonoverlapping(
|
|
|
|
self.as_mut_ptr(), src.as_mut_ptr(), self.len());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-22 21:26:57 -04:00
|
|
|
#[inline]
|
2017-08-18 12:20:04 -05:00
|
|
|
fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
|
2016-07-11 18:18:11 +05:30
|
|
|
where F: FnMut(&'a Self::Item) -> B,
|
2017-08-18 12:20:04 -05:00
|
|
|
B: Ord
|
2016-03-22 21:26:57 -04:00
|
|
|
{
|
2017-08-18 12:20:04 -05:00
|
|
|
self.binary_search_by(|k| f(k).cmp(b))
|
2016-03-22 21:26:57 -04:00
|
|
|
}
|
2017-03-17 15:05:44 +01:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn sort_unstable(&mut self)
|
|
|
|
where Self::Item: Ord
|
|
|
|
{
|
|
|
|
sort::quicksort(self, |a, b| a.lt(b));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn sort_unstable_by<F>(&mut self, mut compare: F)
|
|
|
|
where F: FnMut(&Self::Item, &Self::Item) -> Ordering
|
|
|
|
{
|
|
|
|
sort::quicksort(self, |a, b| compare(a, b) == Ordering::Less);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn sort_unstable_by_key<B, F>(&mut self, mut f: F)
|
|
|
|
where F: FnMut(&Self::Item) -> B,
|
|
|
|
B: Ord
|
|
|
|
{
|
|
|
|
sort::quicksort(self, |a, b| f(a).lt(&f(b)));
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-19 10:50:52 +02:00
|
|
|
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
|
|
|
|
impl<T, I> ops::Index<I> for [T]
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<[T]>
|
2016-07-19 10:50:52 +02:00
|
|
|
{
|
|
|
|
type Output = I::Output;
|
2015-01-03 09:46:29 -05:00
|
|
|
|
2016-07-19 10:50:52 +02:00
|
|
|
#[inline]
|
|
|
|
fn index(&self, index: I) -> &I::Output {
|
|
|
|
index.index(self)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2015-01-03 09:46:29 -05:00
|
|
|
}
|
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-19 10:50:52 +02:00
|
|
|
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
|
|
|
|
impl<T, I> ops::IndexMut<I> for [T]
|
2017-03-22 18:36:43 +02:00
|
|
|
where I: SliceIndex<[T]>
|
2016-07-19 10:50:52 +02:00
|
|
|
{
|
2015-03-21 19:33:27 -04:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn index_mut(&mut self, index: I) -> &mut I::Output {
|
|
|
|
index.index_mut(self)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2015-01-03 09:46:29 -05:00
|
|
|
}
|
|
|
|
|
2015-11-22 18:44:37 +05:30
|
|
|
#[inline(never)]
|
|
|
|
#[cold]
|
|
|
|
fn slice_index_len_fail(index: usize, len: usize) -> ! {
|
|
|
|
panic!("index {} out of range for slice of length {}", index, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(never)]
|
|
|
|
#[cold]
|
|
|
|
fn slice_index_order_fail(index: usize, end: usize) -> ! {
|
|
|
|
panic!("slice index starts at {} but ends at {}", index, end);
|
|
|
|
}
|
|
|
|
|
2016-07-19 10:50:52 +02:00
|
|
|
/// A helper trait used for indexing operations.
|
|
|
|
#[unstable(feature = "slice_get_slice", issue = "35729")]
|
|
|
|
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
|
2017-03-22 18:36:43 +02:00
|
|
|
pub trait SliceIndex<T: ?Sized> {
|
2016-07-19 10:50:52 +02:00
|
|
|
/// The output type returned by methods.
|
|
|
|
type Output: ?Sized;
|
note work still to be done
In particular, uses of inclusive ranges within the standard library are
still waiting. Slices and collections can be sliced with `usize` and
`Range*<usize>`, but not yet `Range*Inclusive<usize>`.
Also, we need to figure out what to do about `RangeArgument`. Currently
it has `start()` and `end()` methods which are pretty much identical to
`Range::start` and `Range::end`. For the same reason as Range itself,
these methods can't express a range such as `0...255u8` without
overflow. The easiest choice, it seems to me, is either changing the
meaning of `end()` to be inclusive, or adding a new method, say
`last()`, that is inclusive and specifying that `end()` returns `None`
in cases where it would overflow. Changing the semantics would be a
breaking change, but `RangeArgument` is unstable so maybe we should do
it anyway.
2016-01-13 13:12:16 -05:00
|
|
|
|
2016-07-19 10:50:52 +02:00
|
|
|
/// Returns a shared reference to the output at this location, if in
|
|
|
|
/// bounds.
|
2017-03-22 18:36:43 +02:00
|
|
|
fn get(self, slice: &T) -> Option<&Self::Output>;
|
2016-07-19 10:50:52 +02:00
|
|
|
|
|
|
|
/// Returns a mutable reference to the output at this location, if in
|
|
|
|
/// bounds.
|
2017-03-22 18:36:43 +02:00
|
|
|
fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
|
2016-07-19 10:50:52 +02:00
|
|
|
|
|
|
|
/// Returns a shared reference to the output at this location, without
|
|
|
|
/// performing any bounds checking.
|
2017-03-22 18:36:43 +02:00
|
|
|
unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
|
2016-07-19 10:50:52 +02:00
|
|
|
|
|
|
|
/// Returns a mutable reference to the output at this location, without
|
|
|
|
/// performing any bounds checking.
|
2017-03-22 18:36:43 +02:00
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
|
2016-07-19 10:50:52 +02:00
|
|
|
|
|
|
|
/// Returns a shared reference to the output at this location, panicking
|
|
|
|
/// if out of bounds.
|
2017-03-22 18:36:43 +02:00
|
|
|
fn index(self, slice: &T) -> &Self::Output;
|
2016-07-19 10:50:52 +02:00
|
|
|
|
|
|
|
/// Returns a mutable reference to the output at this location, panicking
|
|
|
|
/// if out of bounds.
|
2017-03-22 18:36:43 +02:00
|
|
|
fn index_mut(self, slice: &mut T) -> &mut Self::Output;
|
2016-07-19 10:50:52 +02:00
|
|
|
}
|
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
|
2017-03-22 18:36:43 +02:00
|
|
|
impl<T> SliceIndex<[T]> for usize {
|
2016-07-19 10:50:52 +02:00
|
|
|
type Output = T;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get(self, slice: &[T]) -> Option<&T> {
|
|
|
|
if self < slice.len() {
|
|
|
|
unsafe {
|
|
|
|
Some(self.get_unchecked(slice))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
|
|
|
|
if self < slice.len() {
|
|
|
|
unsafe {
|
|
|
|
Some(self.get_unchecked_mut(slice))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked(self, slice: &[T]) -> &T {
|
|
|
|
&*slice.as_ptr().offset(self as isize)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut T {
|
|
|
|
&mut *slice.as_mut_ptr().offset(self as isize)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index(self, slice: &[T]) -> &T {
|
|
|
|
// NB: use intrinsic indexing
|
|
|
|
&(*slice)[self]
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut T {
|
|
|
|
// NB: use intrinsic indexing
|
|
|
|
&mut (*slice)[self]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
|
2017-03-22 18:36:43 +02:00
|
|
|
impl<T> SliceIndex<[T]> for ops::Range<usize> {
|
2015-01-04 17:43:24 +13:00
|
|
|
type Output = [T];
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
|
|
|
if self.start > self.end || self.end > slice.len() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
unsafe {
|
|
|
|
Some(self.get_unchecked(slice))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
|
|
|
if self.start > self.end || self.end > slice.len() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
unsafe {
|
|
|
|
Some(self.get_unchecked_mut(slice))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
|
|
|
from_raw_parts(slice.as_ptr().offset(self.start as isize), self.end - self.start)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
from_raw_parts_mut(slice.as_mut_ptr().offset(self.start as isize), self.end - self.start)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index(self, slice: &[T]) -> &[T] {
|
|
|
|
if self.start > self.end {
|
|
|
|
slice_index_order_fail(self.start, self.end);
|
|
|
|
} else if self.end > slice.len() {
|
|
|
|
slice_index_len_fail(self.end, slice.len());
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
self.get_unchecked(slice)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
if self.start > self.end {
|
|
|
|
slice_index_order_fail(self.start, self.end);
|
|
|
|
} else if self.end > slice.len() {
|
|
|
|
slice_index_len_fail(self.end, slice.len());
|
2015-11-22 18:44:37 +05:30
|
|
|
}
|
2015-03-21 19:33:27 -04:00
|
|
|
unsafe {
|
2016-07-19 10:50:52 +02:00
|
|
|
self.get_unchecked_mut(slice)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
}
|
2016-03-10 21:36:43 +01:00
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
|
2017-03-22 18:36:43 +02:00
|
|
|
impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
|
2015-01-04 17:43:24 +13:00
|
|
|
type Output = [T];
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
|
|
|
(0..self.end).get(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
|
|
|
(0..self.end).get_mut(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
|
|
|
(0..self.end).get_unchecked(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
(0..self.end).get_unchecked_mut(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index(self, slice: &[T]) -> &[T] {
|
|
|
|
(0..self.end).index(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
(0..self.end).index_mut(slice)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
}
|
2016-03-10 21:36:43 +01:00
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
|
2017-03-22 18:36:43 +02:00
|
|
|
impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
|
2015-01-04 17:43:24 +13:00
|
|
|
type Output = [T];
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
|
|
|
(self.start..slice.len()).get(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
|
|
|
(self.start..slice.len()).get_mut(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
|
|
|
(self.start..slice.len()).get_unchecked(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
(self.start..slice.len()).get_unchecked_mut(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index(self, slice: &[T]) -> &[T] {
|
|
|
|
(self.start..slice.len()).index(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
(self.start..slice.len()).index_mut(slice)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
}
|
2016-03-10 21:36:43 +01:00
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
|
2017-03-22 18:36:43 +02:00
|
|
|
impl<T> SliceIndex<[T]> for ops::RangeFull {
|
2015-01-04 17:43:24 +13:00
|
|
|
type Output = [T];
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
|
|
|
Some(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
|
|
|
Some(slice)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
|
|
|
slice
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
slice
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index(self, slice: &[T]) -> &[T] {
|
|
|
|
slice
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
|
|
|
slice
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
}
|
|
|
|
|
2016-07-19 10:50:52 +02:00
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
2017-03-22 18:36:43 +02:00
|
|
|
impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
|
2016-01-28 11:20:48 -05:00
|
|
|
type Output = [T];
|
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
2017-04-23 21:14:32 -07:00
|
|
|
if self.end == usize::max_value() { None }
|
|
|
|
else { (self.start..self.end + 1).get(slice) }
|
2016-07-19 10:50:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
2017-04-23 21:14:32 -07:00
|
|
|
if self.end == usize::max_value() { None }
|
|
|
|
else { (self.start..self.end + 1).get_mut(slice) }
|
2016-07-19 10:50:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
2017-04-23 21:14:32 -07:00
|
|
|
(self.start..self.end + 1).get_unchecked(slice)
|
2016-01-28 11:20:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
2017-04-23 21:14:32 -07:00
|
|
|
(self.start..self.end + 1).get_unchecked_mut(slice)
|
2016-01-28 11:20:48 -05:00
|
|
|
}
|
|
|
|
|
2015-03-21 19:33:27 -04:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn index(self, slice: &[T]) -> &[T] {
|
2017-04-23 21:14:32 -07:00
|
|
|
assert!(self.end != usize::max_value(),
|
|
|
|
"attempted to index slice up to maximum usize");
|
|
|
|
(self.start..self.end + 1).index(slice)
|
2016-07-19 10:50:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
2017-04-23 21:14:32 -07:00
|
|
|
assert!(self.end != usize::max_value(),
|
|
|
|
"attempted to index slice up to maximum usize");
|
|
|
|
(self.start..self.end + 1).index_mut(slice)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2015-01-02 09:12:27 -05:00
|
|
|
}
|
2016-03-10 21:36:43 +01:00
|
|
|
|
2017-01-29 13:31:47 +00:00
|
|
|
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
2017-03-22 18:36:43 +02:00
|
|
|
impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
|
2016-07-19 10:50:52 +02:00
|
|
|
type Output = [T];
|
|
|
|
|
2015-03-21 19:33:27 -04:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get(self, slice: &[T]) -> Option<&[T]> {
|
2017-11-03 18:17:44 +01:00
|
|
|
(0..=self.end).get(slice)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2016-03-10 21:36:43 +01:00
|
|
|
|
2015-03-21 19:33:27 -04:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
|
2017-11-03 18:17:44 +01:00
|
|
|
(0..=self.end).get_mut(slice)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2016-03-10 21:36:43 +01:00
|
|
|
|
2015-03-21 19:33:27 -04:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
|
2017-11-03 18:17:44 +01:00
|
|
|
(0..=self.end).get_unchecked(slice)
|
2015-03-21 19:33:27 -04:00
|
|
|
}
|
2015-01-02 09:12:27 -05:00
|
|
|
|
2016-01-28 11:20:48 -05:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
|
2017-11-03 18:17:44 +01:00
|
|
|
(0..=self.end).get_unchecked_mut(slice)
|
2016-01-28 11:20:48 -05:00
|
|
|
}
|
2016-07-19 10:50:52 +02:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn index(self, slice: &[T]) -> &[T] {
|
2017-11-03 18:17:44 +01:00
|
|
|
(0..=self.end).index(slice)
|
2016-07-19 10:50:52 +02:00
|
|
|
}
|
|
|
|
|
2016-01-28 11:20:48 -05:00
|
|
|
#[inline]
|
2016-07-19 10:50:52 +02:00
|
|
|
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
|
2017-11-03 18:17:44 +01:00
|
|
|
(0..=self.end).index_mut(slice)
|
2016-01-28 11:20:48 -05:00
|
|
|
}
|
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2014-06-30 13:58:53 -07:00
|
|
|
// Common traits
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-06-30 13:58:53 -07:00
|
|
|
impl<'a, T> Default for &'a [T] {
|
2016-09-11 22:58:01 +05:30
|
|
|
/// Creates an empty slice.
|
2014-06-30 13:58:53 -07:00
|
|
|
fn default() -> &'a [T] { &[] }
|
|
|
|
}
|
|
|
|
|
2015-10-23 14:39:50 +11:00
|
|
|
#[stable(feature = "mut_slice_default", since = "1.5.0")]
|
|
|
|
impl<'a, T> Default for &'a mut [T] {
|
2016-09-11 22:58:01 +05:30
|
|
|
/// Creates a mutable empty slice.
|
2015-10-23 14:39:50 +11:00
|
|
|
fn default() -> &'a mut [T] { &mut [] }
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
|
|
|
// Iterators
|
|
|
|
//
|
|
|
|
|
2015-02-17 10:06:24 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-13 17:55:10 -05:00
|
|
|
impl<'a, T> IntoIterator for &'a [T] {
|
|
|
|
type Item = &'a T;
|
|
|
|
type IntoIter = Iter<'a, T>;
|
|
|
|
|
|
|
|
fn into_iter(self) -> Iter<'a, T> {
|
|
|
|
self.iter()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-17 10:06:24 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-07 22:01:05 -05:00
|
|
|
impl<'a, T> IntoIterator for &'a mut [T] {
|
2015-02-13 17:55:10 -05:00
|
|
|
type Item = &'a mut T;
|
2015-02-06 14:47:55 -08:00
|
|
|
type IntoIter = IterMut<'a, T>;
|
2015-01-07 22:01:05 -05:00
|
|
|
|
|
|
|
fn into_iter(self) -> IterMut<'a, T> {
|
|
|
|
self.iter_mut()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-20 11:14:13 -07:00
|
|
|
#[inline]
|
2015-04-24 12:55:19 -04:00
|
|
|
fn size_from_ptr<T>(_: *const T) -> usize {
|
|
|
|
mem::size_of::<T>()
|
|
|
|
}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
// The shared definition of the `Iter` and `IterMut` iterators
|
2014-06-30 13:58:53 -07:00
|
|
|
macro_rules! iterator {
|
2016-11-23 23:02:30 +01:00
|
|
|
(struct $name:ident -> $ptr:ty, $elem:ty, $mkref:ident) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T> Iterator for $name<'a, T> {
|
|
|
|
type Item = $elem;
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<$elem> {
|
|
|
|
// could be implemented with slices, but this avoids bounds checks
|
2015-05-15 03:14:16 +02:00
|
|
|
unsafe {
|
|
|
|
if mem::size_of::<T>() != 0 {
|
|
|
|
assume(!self.ptr.is_null());
|
|
|
|
assume(!self.end.is_null());
|
|
|
|
}
|
|
|
|
if self.ptr == self.end {
|
|
|
|
None
|
|
|
|
} else {
|
2016-11-23 23:02:30 +01:00
|
|
|
Some($mkref!(self.ptr.post_inc()))
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2016-11-23 23:02:30 +01:00
|
|
|
let exact = ptrdistance(self.ptr, self.end);
|
2014-06-30 13:58:53 -07:00
|
|
|
(exact, Some(exact))
|
|
|
|
}
|
2015-04-22 16:03:56 -04:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn count(self) -> usize {
|
2016-06-23 12:26:15 +02:00
|
|
|
self.len()
|
2015-04-22 16:03:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn nth(&mut self, n: usize) -> Option<$elem> {
|
2015-04-22 18:44:17 -04:00
|
|
|
// Call helper method. Can't put the definition here because mut versus const.
|
|
|
|
self.iter_nth(n)
|
2015-04-22 16:03:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-04-22 18:44:17 -04:00
|
|
|
fn last(mut self) -> Option<$elem> {
|
|
|
|
self.next_back()
|
2015-04-22 16:03:56 -04:00
|
|
|
}
|
2016-11-23 23:02:30 +01:00
|
|
|
|
2017-10-22 22:47:27 -07:00
|
|
|
#[inline]
|
|
|
|
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
|
|
|
|
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
|
2016-11-23 23:02:30 +01:00
|
|
|
{
|
2017-10-22 22:47:27 -07:00
|
|
|
// manual unrolling is needed when there are conditional exits from the loop
|
|
|
|
let mut accum = init;
|
|
|
|
unsafe {
|
|
|
|
while ptrdistance(self.ptr, self.end) >= 4 {
|
|
|
|
accum = f(accum, $mkref!(self.ptr.post_inc()))?;
|
|
|
|
accum = f(accum, $mkref!(self.ptr.post_inc()))?;
|
|
|
|
accum = f(accum, $mkref!(self.ptr.post_inc()))?;
|
|
|
|
accum = f(accum, $mkref!(self.ptr.post_inc()))?;
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
2017-10-22 22:47:27 -07:00
|
|
|
while self.ptr != self.end {
|
|
|
|
accum = f(accum, $mkref!(self.ptr.post_inc()))?;
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
2017-10-22 22:47:27 -07:00
|
|
|
}
|
|
|
|
Try::from_ok(accum)
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
|
|
|
|
2017-10-22 22:47:27 -07:00
|
|
|
#[inline]
|
|
|
|
fn fold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
|
|
|
|
where Fold: FnMut(Acc, Self::Item) -> Acc,
|
2016-11-23 23:02:30 +01:00
|
|
|
{
|
2017-10-22 22:47:27 -07:00
|
|
|
// Let LLVM unroll this, rather than using the default
|
|
|
|
// impl that would force the manual unrolling above
|
|
|
|
let mut accum = init;
|
|
|
|
while let Some(x) = self.next() {
|
|
|
|
accum = f(accum, x);
|
|
|
|
}
|
|
|
|
accum
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T> DoubleEndedIterator for $name<'a, T> {
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<$elem> {
|
|
|
|
// could be implemented with slices, but this avoids bounds checks
|
2015-05-15 03:14:16 +02:00
|
|
|
unsafe {
|
|
|
|
if mem::size_of::<T>() != 0 {
|
|
|
|
assume(!self.ptr.is_null());
|
|
|
|
assume(!self.end.is_null());
|
|
|
|
}
|
|
|
|
if self.end == self.ptr {
|
|
|
|
None
|
|
|
|
} else {
|
2016-11-23 23:02:30 +01:00
|
|
|
Some($mkref!(self.end.pre_dec()))
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-04-08 03:43:18 +02:00
|
|
|
|
2017-10-22 22:47:27 -07:00
|
|
|
#[inline]
|
|
|
|
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
|
|
|
|
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
|
2016-11-23 23:02:30 +01:00
|
|
|
{
|
|
|
|
// manual unrolling is needed when there are conditional exits from the loop
|
2017-10-22 22:47:27 -07:00
|
|
|
let mut accum = init;
|
2016-11-23 23:02:30 +01:00
|
|
|
unsafe {
|
|
|
|
while ptrdistance(self.ptr, self.end) >= 4 {
|
2017-10-22 22:47:27 -07:00
|
|
|
accum = f(accum, $mkref!(self.end.pre_dec()))?;
|
|
|
|
accum = f(accum, $mkref!(self.end.pre_dec()))?;
|
|
|
|
accum = f(accum, $mkref!(self.end.pre_dec()))?;
|
|
|
|
accum = f(accum, $mkref!(self.end.pre_dec()))?;
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
|
|
|
while self.ptr != self.end {
|
2017-10-22 22:47:27 -07:00
|
|
|
accum = f(accum, $mkref!(self.end.pre_dec()))?;
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
|
|
|
}
|
2017-10-22 22:47:27 -07:00
|
|
|
Try::from_ok(accum)
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
|
|
|
|
2017-10-22 22:47:27 -07:00
|
|
|
#[inline]
|
|
|
|
fn rfold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
|
|
|
|
where Fold: FnMut(Acc, Self::Item) -> Acc,
|
2016-11-23 23:02:30 +01:00
|
|
|
{
|
2017-10-22 22:47:27 -07:00
|
|
|
// Let LLVM unroll this, rather than using the default
|
|
|
|
// impl that would force the manual unrolling above
|
|
|
|
let mut accum = init;
|
|
|
|
while let Some(x) = self.next_back() {
|
|
|
|
accum = f(accum, x);
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2017-10-22 22:47:27 -07:00
|
|
|
accum
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-15 14:44:55 +11:00
|
|
|
macro_rules! make_slice {
|
2015-05-11 12:37:31 -07:00
|
|
|
($start: expr, $end: expr) => {{
|
|
|
|
let start = $start;
|
|
|
|
let diff = ($end as usize).wrapping_sub(start as usize);
|
|
|
|
if size_from_ptr(start) == 0 {
|
|
|
|
// use a non-null pointer value
|
|
|
|
unsafe { from_raw_parts(1 as *const _, diff) }
|
2014-11-15 14:44:55 +11:00
|
|
|
} else {
|
2015-05-11 12:37:31 -07:00
|
|
|
let len = diff / size_from_ptr(start);
|
|
|
|
unsafe { from_raw_parts(start, len) }
|
2015-03-13 09:56:18 +01:00
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! make_mut_slice {
|
2015-05-11 12:37:31 -07:00
|
|
|
($start: expr, $end: expr) => {{
|
|
|
|
let start = $start;
|
|
|
|
let diff = ($end as usize).wrapping_sub(start as usize);
|
|
|
|
if size_from_ptr(start) == 0 {
|
|
|
|
// use a non-null pointer value
|
|
|
|
unsafe { from_raw_parts_mut(1 as *mut _, diff) }
|
2015-03-13 09:56:18 +01:00
|
|
|
} else {
|
2015-05-11 12:37:31 -07:00
|
|
|
let len = diff / size_from_ptr(start);
|
|
|
|
unsafe { from_raw_parts_mut(start, len) }
|
2014-11-15 14:44:55 +11:00
|
|
|
}
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// Immutable slice iterator
|
2016-04-08 01:56:45 +02:00
|
|
|
///
|
2016-07-16 21:42:11 -04:00
|
|
|
/// This struct is created by the [`iter`] method on [slices].
|
|
|
|
///
|
2016-04-08 01:56:45 +02:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Basic usage:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// // First, we declare a type which has `iter` method to get the `Iter` struct (&[usize here]):
|
|
|
|
/// let slice = &[1, 2, 3];
|
|
|
|
///
|
|
|
|
/// // Then, we iterate over it:
|
|
|
|
/// for element in slice.iter() {
|
|
|
|
/// println!("{}", element);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2016-07-16 21:42:11 -04:00
|
|
|
///
|
|
|
|
/// [`iter`]: ../../std/primitive.slice.html#method.iter
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-19 21:52:10 +01:00
|
|
|
pub struct Iter<'a, T: 'a> {
|
2014-06-30 13:58:53 -07:00
|
|
|
ptr: *const T,
|
|
|
|
end: *const T,
|
2015-02-12 12:34:04 -05:00
|
|
|
_marker: marker::PhantomData<&'a T>,
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_tuple("Iter")
|
|
|
|
.field(&self.as_slice())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 20:52:18 +08:00
|
|
|
unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {}
|
2015-11-16 19:54:28 +03:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 20:52:18 +08:00
|
|
|
unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
|
|
|
|
|
2014-12-19 21:52:10 +01:00
|
|
|
impl<'a, T> Iter<'a, T> {
|
2014-11-15 14:44:55 +11:00
|
|
|
/// 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.
|
2016-04-08 01:56:45 +02:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Basic usage:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// // First, we declare a type which has the `iter` method to get the `Iter`
|
|
|
|
/// // struct (&[usize here]):
|
|
|
|
/// let slice = &[1, 2, 3];
|
|
|
|
///
|
|
|
|
/// // Then, we get the iterator:
|
|
|
|
/// let mut iter = slice.iter();
|
|
|
|
/// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]":
|
|
|
|
/// println!("{:?}", iter.as_slice());
|
|
|
|
///
|
|
|
|
/// // Next, we move to the second element of the slice:
|
|
|
|
/// iter.next();
|
|
|
|
/// // Now `as_slice` returns "[2, 3]":
|
|
|
|
/// println!("{:?}", iter.as_slice());
|
|
|
|
/// ```
|
2015-09-10 13:26:44 -07:00
|
|
|
#[stable(feature = "iter_to_slice", since = "1.4.0")]
|
2014-11-15 14:44:55 +11:00
|
|
|
pub fn as_slice(&self) -> &'a [T] {
|
2015-05-11 12:37:31 -07:00
|
|
|
make_slice!(self.ptr, self.end)
|
2014-11-15 14:44:55 +11:00
|
|
|
}
|
2015-04-22 18:44:17 -04:00
|
|
|
|
|
|
|
// Helper function for Iter::nth
|
|
|
|
fn iter_nth(&mut self, n: usize) -> Option<&'a T> {
|
|
|
|
match self.as_slice().get(n) {
|
2015-04-24 12:55:19 -04:00
|
|
|
Some(elem_ref) => unsafe {
|
2015-05-11 00:55:21 -07:00
|
|
|
self.ptr = slice_offset!(self.ptr, (n as isize).wrapping_add(1));
|
2015-05-15 15:20:42 +02:00
|
|
|
Some(elem_ref)
|
2015-04-22 18:44:17 -04:00
|
|
|
},
|
|
|
|
None => {
|
|
|
|
self.ptr = self.end;
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 14:44:55 +11:00
|
|
|
}
|
|
|
|
|
2016-11-23 23:02:30 +01:00
|
|
|
iterator!{struct Iter -> *const T, &'a T, make_ref}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-11-22 23:31:31 +01:00
|
|
|
impl<'a, T> ExactSizeIterator for Iter<'a, T> {
|
|
|
|
fn is_empty(&self) -> bool {
|
|
|
|
self.ptr == self.end
|
|
|
|
}
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, T> FusedIterator for Iter<'a, T> {}
|
|
|
|
|
2016-11-04 00:24:59 +01:00
|
|
|
#[unstable(feature = "trusted_len", issue = "37572")]
|
2016-10-20 14:07:06 +02:00
|
|
|
unsafe impl<'a, T> TrustedLen for Iter<'a, T> {}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-19 21:52:10 +01:00
|
|
|
impl<'a, T> Clone for Iter<'a, T> {
|
2015-02-12 12:34:04 -05:00
|
|
|
fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
2017-05-20 08:38:39 +01:00
|
|
|
#[stable(feature = "slice_iter_as_ref", since = "1.13.0")]
|
2016-08-09 20:49:41 -04:00
|
|
|
impl<'a, T> AsRef<[T]> for Iter<'a, T> {
|
|
|
|
fn as_ref(&self) -> &[T] {
|
|
|
|
self.as_slice()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// Mutable slice iterator.
|
2016-04-08 01:56:45 +02:00
|
|
|
///
|
2016-07-16 21:42:11 -04:00
|
|
|
/// This struct is created by the [`iter_mut`] method on [slices].
|
|
|
|
///
|
2016-04-08 01:56:45 +02:00
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Basic usage:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// // First, we declare a type which has `iter_mut` method to get the `IterMut`
|
|
|
|
/// // struct (&[usize here]):
|
|
|
|
/// let mut slice = &mut [1, 2, 3];
|
|
|
|
///
|
|
|
|
/// // Then, we iterate over it and increment each element value:
|
|
|
|
/// for element in slice.iter_mut() {
|
|
|
|
/// *element += 1;
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // We now have "[2, 3, 4]":
|
|
|
|
/// println!("{:?}", slice);
|
|
|
|
/// ```
|
2016-07-16 21:42:11 -04:00
|
|
|
///
|
|
|
|
/// [`iter_mut`]: ../../std/primitive.slice.html#method.iter_mut
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-19 21:52:10 +01:00
|
|
|
pub struct IterMut<'a, T: 'a> {
|
2014-06-30 13:58:53 -07:00
|
|
|
ptr: *mut T,
|
|
|
|
end: *mut T,
|
2015-02-12 12:34:04 -05:00
|
|
|
_marker: marker::PhantomData<&'a mut T>,
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_tuple("IterMut")
|
|
|
|
.field(&make_slice!(self.ptr, self.end))
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 20:52:18 +08:00
|
|
|
unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
|
2015-11-16 19:54:28 +03:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-25 20:52:18 +08:00
|
|
|
unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
|
2015-01-04 17:43:24 +13:00
|
|
|
|
2014-12-19 21:52:10 +01:00
|
|
|
impl<'a, T> IterMut<'a, T> {
|
2014-11-15 14:44:55 +11:00
|
|
|
/// 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.
|
2016-04-08 01:56:45 +02:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Basic usage:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// // First, we declare a type which has `iter_mut` method to get the `IterMut`
|
|
|
|
/// // struct (&[usize here]):
|
|
|
|
/// let mut slice = &mut [1, 2, 3];
|
|
|
|
///
|
|
|
|
/// {
|
|
|
|
/// // Then, we get the iterator:
|
|
|
|
/// let mut iter = slice.iter_mut();
|
|
|
|
/// // We move to next element:
|
|
|
|
/// iter.next();
|
|
|
|
/// // So if we print what `into_slice` method returns here, we have "[2, 3]":
|
|
|
|
/// println!("{:?}", iter.into_slice());
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // Now let's modify a value of the slice:
|
|
|
|
/// {
|
|
|
|
/// // First we get back the iterator:
|
|
|
|
/// let mut iter = slice.iter_mut();
|
|
|
|
/// // We change the value of the first element of the slice returned by the `next` method:
|
|
|
|
/// *iter.next().unwrap() += 1;
|
|
|
|
/// }
|
|
|
|
/// // Now slice is "[2, 2, 3]":
|
|
|
|
/// println!("{:?}", slice);
|
|
|
|
/// ```
|
2015-09-10 13:26:44 -07:00
|
|
|
#[stable(feature = "iter_to_slice", since = "1.4.0")]
|
2014-11-15 14:44:55 +11:00
|
|
|
pub fn into_slice(self) -> &'a mut [T] {
|
2015-05-11 12:37:31 -07:00
|
|
|
make_mut_slice!(self.ptr, self.end)
|
2014-11-15 14:44:55 +11:00
|
|
|
}
|
2015-04-22 18:44:17 -04:00
|
|
|
|
|
|
|
// Helper function for IterMut::nth
|
|
|
|
fn iter_nth(&mut self, n: usize) -> Option<&'a mut T> {
|
2015-05-11 12:37:31 -07:00
|
|
|
match make_mut_slice!(self.ptr, self.end).get_mut(n) {
|
2015-04-24 12:55:19 -04:00
|
|
|
Some(elem_ref) => unsafe {
|
2015-05-11 00:55:21 -07:00
|
|
|
self.ptr = slice_offset!(self.ptr, (n as isize).wrapping_add(1));
|
2015-05-15 15:20:42 +02:00
|
|
|
Some(elem_ref)
|
2015-04-22 18:44:17 -04:00
|
|
|
},
|
|
|
|
None => {
|
|
|
|
self.ptr = self.end;
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 14:44:55 +11:00
|
|
|
}
|
|
|
|
|
2016-11-23 23:02:30 +01:00
|
|
|
iterator!{struct IterMut -> *mut T, &'a mut T, make_ref_mut}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-11-22 23:31:31 +01:00
|
|
|
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
|
|
|
|
fn is_empty(&self) -> bool {
|
|
|
|
self.ptr == self.end
|
|
|
|
}
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, T> FusedIterator for IterMut<'a, T> {}
|
|
|
|
|
2016-11-04 00:24:59 +01:00
|
|
|
#[unstable(feature = "trusted_len", issue = "37572")]
|
2016-10-20 14:07:06 +02:00
|
|
|
unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {}
|
|
|
|
|
2016-11-23 23:02:30 +01:00
|
|
|
|
2016-11-23 23:02:30 +01:00
|
|
|
// Return the number of elements of `T` from `start` to `end`.
|
|
|
|
// Return the arithmetic difference if `T` is zero size.
|
|
|
|
#[inline(always)]
|
|
|
|
fn ptrdistance<T>(start: *const T, end: *const T) -> usize {
|
2017-03-31 13:52:46 +01:00
|
|
|
match start.offset_to(end) {
|
|
|
|
Some(x) => x as usize,
|
|
|
|
None => (end as usize).wrapping_sub(start as usize),
|
|
|
|
}
|
2016-11-23 23:02:30 +01:00
|
|
|
}
|
|
|
|
|
2016-11-23 23:02:30 +01:00
|
|
|
// Extension methods for raw pointers, used by the iterators
|
|
|
|
trait PointerExt : Copy {
|
|
|
|
unsafe fn slice_offset(self, i: isize) -> Self;
|
|
|
|
|
2017-03-22 01:42:23 +01:00
|
|
|
/// Increments `self` by 1, but returns the old value.
|
2016-11-23 23:02:30 +01:00
|
|
|
#[inline(always)]
|
|
|
|
unsafe fn post_inc(&mut self) -> Self {
|
|
|
|
let current = *self;
|
|
|
|
*self = self.slice_offset(1);
|
|
|
|
current
|
|
|
|
}
|
|
|
|
|
2017-03-22 01:42:23 +01:00
|
|
|
/// Decrements `self` by 1, and returns the new value.
|
2016-11-23 23:02:30 +01:00
|
|
|
#[inline(always)]
|
|
|
|
unsafe fn pre_dec(&mut self) -> Self {
|
|
|
|
*self = self.slice_offset(-1);
|
|
|
|
*self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> PointerExt for *const T {
|
|
|
|
#[inline(always)]
|
|
|
|
unsafe fn slice_offset(self, i: isize) -> Self {
|
|
|
|
slice_offset!(self, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> PointerExt for *mut T {
|
|
|
|
#[inline(always)]
|
|
|
|
unsafe fn slice_offset(self, i: isize) -> Self {
|
|
|
|
slice_offset!(self, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
/// An internal abstraction over the splitting iterators, so that
|
|
|
|
/// splitn, splitn_mut etc can be implemented once.
|
2016-03-07 23:55:52 -08:00
|
|
|
#[doc(hidden)]
|
2014-12-29 16:18:41 -05:00
|
|
|
trait SplitIter: DoubleEndedIterator {
|
2017-03-22 01:42:23 +01:00
|
|
|
/// Marks the underlying iterator as complete, extracting the remaining
|
2014-09-22 16:23:00 -07:00
|
|
|
/// portion of the slice.
|
2015-01-05 20:47:21 -05:00
|
|
|
fn finish(&mut self) -> Option<Self::Item>;
|
2014-09-22 16:23:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// An iterator over subslices separated by elements that match a predicate
|
|
|
|
/// function.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`split`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`split`]: ../../std/primitive.slice.html#method.split
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
pub struct Split<'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
|
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for Split<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("Split")
|
|
|
|
.field("v", &self.v)
|
|
|
|
.field("finished", &self.finished)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-29 10:54:55 +03:00
|
|
|
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
impl<'a, T, P> Clone for Split<'a, T, P> where P: Clone + FnMut(&T) -> bool {
|
|
|
|
fn clone(&self) -> Split<'a, T, P> {
|
|
|
|
Split {
|
2014-12-13 22:04:23 -05:00
|
|
|
v: self.v,
|
|
|
|
pred: self.pred.clone(),
|
|
|
|
finished: self.finished,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
type Item = &'a [T];
|
|
|
|
|
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) => {
|
2015-01-12 16:59:18 -05:00
|
|
|
let ret = Some(&self.v[..idx]);
|
2015-01-19 11:07:13 -05:00
|
|
|
self.v = &self.v[idx + 1..];
|
2014-06-30 13:58:53 -07:00
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2014-06-30 13:58:53 -07:00
|
|
|
if self.finished {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
|
|
|
(1, Some(self.v.len() + 1))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T, P> DoubleEndedIterator for Split<'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) => {
|
2015-01-19 11:07:13 -05:00
|
|
|
let ret = Some(&self.v[idx + 1..]);
|
2015-01-12 16:59:18 -05:00
|
|
|
self.v = &self.v[..idx];
|
2014-06-30 13:58:53 -07:00
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T, P> SplitIter for Split<'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) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, T, P> FusedIterator for Split<'a, T, P> where P: FnMut(&T) -> bool {}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
/// An iterator over the subslices of the vector which are separated
|
|
|
|
/// by elements that match `pred`.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`split_mut`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`split_mut`]: ../../std/primitive.slice.html#method.split_mut
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
pub struct SplitMut<'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
|
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("SplitMut")
|
|
|
|
.field("v", &self.v)
|
|
|
|
.field("finished", &self.finished)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T, P> SplitIter for SplitMut<'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 []))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
type Item = &'a mut [T];
|
|
|
|
|
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);
|
2015-01-17 16:15:47 -08:00
|
|
|
self.v = &mut tail[1..];
|
2014-06-30 13:58:53 -07:00
|
|
|
Some(head)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2014-06-30 13:58:53 -07:00
|
|
|
if self.finished {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
|
|
|
// if the predicate doesn't match anything, we yield one slice
|
|
|
|
// if it matches every element, we yield len+1 empty slices.
|
|
|
|
(1, Some(self.v.len() + 1))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where
|
2014-12-05 01:00:50 -05:00
|
|
|
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;
|
2015-01-17 16:15:47 -08:00
|
|
|
Some(&mut tail[1..])
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {}
|
|
|
|
|
2017-04-03 15:25:30 -05:00
|
|
|
/// An iterator over subslices separated by elements that match a predicate
|
|
|
|
/// function, starting from the end of the slice.
|
|
|
|
///
|
|
|
|
/// This struct is created by the [`rsplit`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
#[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`?
|
|
|
|
pub struct RSplit<'a, T:'a, P> where P: FnMut(&T) -> bool {
|
|
|
|
inner: Split<'a, T, P>
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("RSplit")
|
|
|
|
.field("v", &self.inner.v)
|
|
|
|
.field("finished", &self.inner.finished)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
type Item = &'a [T];
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a [T]> {
|
|
|
|
self.inner.next_back()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
self.inner.size_hint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a [T]> {
|
|
|
|
self.inner.next()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> SplitIter for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
#[inline]
|
|
|
|
fn finish(&mut self) -> Option<&'a [T]> {
|
|
|
|
self.inner.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> FusedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {}
|
|
|
|
|
|
|
|
/// An iterator over the subslices of the vector which are separated
|
|
|
|
/// by elements that match `pred`, starting from the end of the slice.
|
|
|
|
///
|
|
|
|
/// This struct is created by the [`rsplit_mut`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
pub struct RSplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool {
|
|
|
|
inner: SplitMut<'a, T, P>
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("RSplitMut")
|
|
|
|
.field("v", &self.inner.v)
|
|
|
|
.field("finished", &self.inner.finished)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> SplitIter for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
#[inline]
|
|
|
|
fn finish(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
self.inner.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
type Item = &'a mut [T];
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
self.inner.next_back()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
self.inner.size_hint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P> where
|
|
|
|
P: FnMut(&T) -> bool,
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a mut [T]> {
|
|
|
|
self.inner.next()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
#[unstable(feature = "slice_rsplit", issue = "41020")]
|
|
|
|
impl<'a, T, P> FusedIterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
/// An private iterator over subslices separated by elements that
|
|
|
|
/// match a predicate function, splitting at most a fixed number of
|
|
|
|
/// times.
|
2016-03-04 18:49:43 -08:00
|
|
|
#[derive(Debug)]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
struct GenericSplitN<I> {
|
2014-09-22 16:23:00 -07:00
|
|
|
iter: I,
|
2015-02-14 16:04:47 -08:00
|
|
|
count: usize,
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
|
|
|
|
2015-01-05 20:47:21 -05:00
|
|
|
impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> {
|
2014-12-29 16:18:41 -05:00
|
|
|
type Item = T;
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
2014-12-29 16:18:41 -05:00
|
|
|
fn next(&mut self) -> Option<T> {
|
2015-04-01 11:28:34 -07:00
|
|
|
match self.count {
|
|
|
|
0 => None,
|
|
|
|
1 => { self.count -= 1; self.iter.finish() }
|
2017-04-03 15:27:42 -05:00
|
|
|
_ => { self.count -= 1; self.iter.next() }
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2014-09-22 16:23:00 -07:00
|
|
|
let (lower, upper_opt) = self.iter.size_hint();
|
2015-04-01 11:28:34 -07:00
|
|
|
(lower, upper_opt.map(|upper| cmp::min(self.count, upper)))
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
/// An iterator over subslices separated by elements that match a predicate
|
|
|
|
/// function, limited to a given number of splits.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`splitn`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`splitn`]: ../../std/primitive.slice.html#method.splitn
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
|
|
|
|
inner: GenericSplitN<Split<'a, T, P>>
|
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitN<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("SplitN")
|
|
|
|
.field("inner", &self.inner)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
/// An iterator over subslices separated by elements that match a
|
|
|
|
/// predicate function, limited to a given number of splits, starting
|
|
|
|
/// from the end of the slice.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`rsplitn`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`rsplitn`]: ../../std/primitive.slice.html#method.rsplitn
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
|
2017-04-03 15:27:42 -05:00
|
|
|
inner: GenericSplitN<RSplit<'a, T, P>>
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitN<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("RSplitN")
|
|
|
|
.field("inner", &self.inner)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
/// An iterator over subslices separated by elements that match a predicate
|
|
|
|
/// function, limited to a given number of splits.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`splitn_mut`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`splitn_mut`]: ../../std/primitive.slice.html#method.splitn_mut
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
|
|
|
|
inner: GenericSplitN<SplitMut<'a, T, P>>
|
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitNMut<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("SplitNMut")
|
|
|
|
.field("inner", &self.inner)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
/// An iterator over subslices separated by elements that match a
|
|
|
|
/// predicate function, limited to a given number of splits, starting
|
|
|
|
/// from the end of the slice.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`rsplitn_mut`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`rsplitn_mut`]: ../../std/primitive.slice.html#method.rsplitn_mut
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
|
2017-04-03 15:27:42 -05:00
|
|
|
inner: GenericSplitN<RSplitMut<'a, T, P>>
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
}
|
|
|
|
|
2016-03-04 18:49:43 -08:00
|
|
|
#[stable(feature = "core_impl_debug", since = "1.9.0")]
|
|
|
|
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitNMut<'a, T, P> where P: FnMut(&T) -> bool {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("RSplitNMut")
|
|
|
|
.field("inner", &self.inner)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
macro_rules! forward_iterator {
|
|
|
|
($name:ident: $elem:ident, $iter_of:ty) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, $elem, P> Iterator for $name<'a, $elem, P> where
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
P: FnMut(&T) -> bool
|
|
|
|
{
|
2014-12-29 16:18:41 -05:00
|
|
|
type Item = $iter_of;
|
|
|
|
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<$iter_of> {
|
|
|
|
self.inner.next()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
self.inner.size_hint()
|
|
|
|
}
|
|
|
|
}
|
2016-08-13 14:42:36 -04:00
|
|
|
|
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P>
|
|
|
|
where P: FnMut(&T) -> bool {}
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
forward_iterator! { SplitN: T, &'a [T] }
|
|
|
|
forward_iterator! { RSplitN: T, &'a [T] }
|
|
|
|
forward_iterator! { SplitNMut: T, &'a mut [T] }
|
|
|
|
forward_iterator! { RSplitNMut: T, &'a mut [T] }
|
|
|
|
|
2014-09-22 16:23:00 -07:00
|
|
|
/// An iterator over overlapping subslices of length `size`.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`windows`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`windows`]: ../../std/primitive.slice.html#method.windows
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2016-03-04 18:49:43 -08:00
|
|
|
#[derive(Debug)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-08-27 21:46:52 -04:00
|
|
|
pub struct Windows<'a, T:'a> {
|
|
|
|
v: &'a [T],
|
2015-02-14 16:04:47 -08:00
|
|
|
size: usize
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
|
|
|
|
2017-09-29 10:54:55 +03:00
|
|
|
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
2015-03-02 17:50:47 +11:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<'a, T> Clone for Windows<'a, T> {
|
|
|
|
fn clone(&self) -> Windows<'a, T> {
|
|
|
|
Windows {
|
|
|
|
v: self.v,
|
|
|
|
size: self.size,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T> Iterator for Windows<'a, T> {
|
|
|
|
type Item = &'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 {
|
2015-01-12 16:59:18 -05:00
|
|
|
let ret = Some(&self.v[..self.size]);
|
2015-01-07 11:58:31 -05:00
|
|
|
self.v = &self.v[1..];
|
2014-06-30 13:58:53 -07:00
|
|
|
ret
|
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2014-06-30 13:58:53 -07:00
|
|
|
if self.size > self.v.len() {
|
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
2015-02-10 21:32:00 -06:00
|
|
|
let size = self.v.len() - self.size + 1;
|
|
|
|
(size, Some(size))
|
|
|
|
}
|
|
|
|
}
|
2015-08-07 00:10:31 -07:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn count(self) -> usize {
|
2016-06-23 12:26:15 +02:00
|
|
|
self.len()
|
2015-08-07 00:10:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
|
|
|
let (end, overflow) = self.size.overflowing_add(n);
|
|
|
|
if end > self.v.len() || overflow {
|
|
|
|
self.v = &[];
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let nth = &self.v[n..end];
|
|
|
|
self.v = &self.v[n+1..];
|
|
|
|
Some(nth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn last(self) -> Option<Self::Item> {
|
|
|
|
if self.size > self.v.len() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let start = self.v.len() - self.size;
|
|
|
|
Some(&self.v[start..])
|
|
|
|
}
|
|
|
|
}
|
2015-02-10 21:32:00 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
|
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a [T]> {
|
|
|
|
if self.size > self.v.len() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let ret = Some(&self.v[self.v.len()-self.size..]);
|
|
|
|
self.v = &self.v[..self.v.len()-1];
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<'a, T> ExactSizeIterator for Windows<'a, T> {}
|
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, T> FusedIterator for Windows<'a, T> {}
|
|
|
|
|
2018-01-03 00:58:56 +02:00
|
|
|
#[doc(hidden)]
|
|
|
|
unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
|
|
|
|
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
|
|
|
|
from_raw_parts(self.v.as_ptr().offset(i as isize), self.size)
|
|
|
|
}
|
|
|
|
fn may_have_side_effect() -> bool { false }
|
|
|
|
}
|
|
|
|
|
2018-01-02 01:46:50 +02:00
|
|
|
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
|
2014-09-22 16:23:00 -07:00
|
|
|
/// 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.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`chunks`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`chunks`]: ../../std/primitive.slice.html#method.chunks
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2016-03-04 18:49:43 -08:00
|
|
|
#[derive(Debug)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-08-27 21:46:52 -04:00
|
|
|
pub struct Chunks<'a, T:'a> {
|
|
|
|
v: &'a [T],
|
2018-01-02 01:46:50 +02:00
|
|
|
chunk_size: usize
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
|
|
|
|
2017-09-29 10:54:55 +03:00
|
|
|
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
2015-03-02 17:50:47 +11:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<'a, T> Clone for Chunks<'a, T> {
|
|
|
|
fn clone(&self) -> Chunks<'a, T> {
|
|
|
|
Chunks {
|
|
|
|
v: self.v,
|
2018-01-02 01:46:50 +02:00
|
|
|
chunk_size: self.chunk_size,
|
2015-03-02 17:50:47 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T> Iterator for Chunks<'a, T> {
|
|
|
|
type Item = &'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]> {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.v.is_empty() {
|
2014-06-30 13:58:53 -07:00
|
|
|
None
|
|
|
|
} else {
|
2018-01-02 01:46:50 +02:00
|
|
|
let chunksz = cmp::min(self.v.len(), self.chunk_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]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.v.is_empty() {
|
2014-06-30 13:58:53 -07:00
|
|
|
(0, Some(0))
|
|
|
|
} else {
|
2018-01-02 01:46:50 +02: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
|
|
|
}
|
2015-08-07 00:10:31 -07:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn count(self) -> usize {
|
2016-06-23 12:26:15 +02:00
|
|
|
self.len()
|
2015-08-07 00:10:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
2018-01-02 01:46:50 +02:00
|
|
|
let (start, overflow) = n.overflowing_mul(self.chunk_size);
|
2015-08-07 00:10:31 -07:00
|
|
|
if start >= self.v.len() || overflow {
|
|
|
|
self.v = &[];
|
|
|
|
None
|
|
|
|
} else {
|
2018-01-02 01:46:50 +02:00
|
|
|
let end = match start.checked_add(self.chunk_size) {
|
2015-08-07 00:10:31 -07:00
|
|
|
Some(sum) => cmp::min(self.v.len(), sum),
|
|
|
|
None => self.v.len(),
|
|
|
|
};
|
|
|
|
let nth = &self.v[start..end];
|
|
|
|
self.v = &self.v[end..];
|
|
|
|
Some(nth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn last(self) -> Option<Self::Item> {
|
|
|
|
if self.v.is_empty() {
|
|
|
|
None
|
|
|
|
} else {
|
2018-01-02 01:46:50 +02:00
|
|
|
let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
|
2015-08-07 00:10:31 -07:00
|
|
|
Some(&self.v[start..])
|
|
|
|
}
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T> DoubleEndedIterator 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]> {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.v.is_empty() {
|
2014-06-30 13:58:53 -07:00
|
|
|
None
|
|
|
|
} else {
|
2018-01-02 01:46:50 +02:00
|
|
|
let remainder = self.v.len() % self.chunk_size;
|
|
|
|
let chunksz = if remainder != 0 { remainder } else { self.chunk_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
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-12 17:08:53 -05:00
|
|
|
impl<'a, T> ExactSizeIterator for Chunks<'a, T> {}
|
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, T> FusedIterator for Chunks<'a, T> {}
|
|
|
|
|
2018-01-03 00:58:56 +02:00
|
|
|
#[doc(hidden)]
|
|
|
|
unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
|
|
|
|
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
|
|
|
|
let start = i * self.size;
|
|
|
|
let end = cmp::min(start + self.size, self.v.len());
|
|
|
|
from_raw_parts(self.v.as_ptr().offset(start as isize), end - start)
|
|
|
|
}
|
|
|
|
fn may_have_side_effect() -> bool { false }
|
|
|
|
}
|
|
|
|
|
2018-01-02 01:46:50 +02:00
|
|
|
/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
|
2014-09-22 16:23:00 -07:00
|
|
|
/// 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.
|
2016-12-30 13:50:11 -05:00
|
|
|
///
|
|
|
|
/// This struct is created by the [`chunks_mut`] method on [slices].
|
|
|
|
///
|
|
|
|
/// [`chunks_mut`]: ../../std/primitive.slice.html#method.chunks_mut
|
|
|
|
/// [slices]: ../../std/primitive.slice.html
|
2016-03-04 18:49:43 -08:00
|
|
|
#[derive(Debug)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
Second pass stabilization: slice
This commit takes a second pass through the `slice` module to
stabilize its API. The changes are as follows:
**Stable**:
* `as_mut_slice`
* `as_ptr`, `as_mut_ptr`
* `binary_search_by` (was: `binary_search`)
* `binary_search` (was: `binary_search_elem`)
* `chunks`, `chunks_mut`
* `contains`
* `ends_with`
* `first`, `first_mut` (was: `head`)
* `get_unchecked`, `get_unchecked_mut` (was: `unsafe_get`)
* `get`
* `is_empty`
* `iter`, `iter_mut`
* `len`
* `reverse`
* `sort_by`
* `sort`
* `split_at`, `split_at_mut`
* `split_mut`, `splitn_mut`, `rsplitn_mut`
* `split`, `splitn`, `rsplitn`
* `starts_with`
* `swap`
* `to_vec`
* `windows`
**Deprecated**:
* `head`, `head_mut` (renamed as above)
* `unsafe_get`, `unsafe_mut` (renamed as above)
* `binary_search_elem` (renamed as above)
* `partitioned`, deprecated in favor of a new, more
general iterator consumer called `partition`.
* `BinarySearchResult`, deprecated in favor of `Result<uint, uint>`
[breaking-change]
2014-12-17 20:50:16 -08:00
|
|
|
pub struct ChunksMut<'a, T:'a> {
|
2014-08-27 21:46:52 -04:00
|
|
|
v: &'a mut [T],
|
2015-02-14 16:04:47 -08:00
|
|
|
chunk_size: usize
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T> Iterator for ChunksMut<'a, T> {
|
|
|
|
type Item = &'a mut [T];
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a mut [T]> {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.v.is_empty() {
|
2014-06-30 13:58:53 -07:00
|
|
|
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]
|
2015-02-14 16:04:47 -08:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.v.is_empty() {
|
2014-06-30 13:58:53 -07:00
|
|
|
(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
|
|
|
}
|
2015-08-07 00:10:31 -07:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn count(self) -> usize {
|
2016-06-23 12:26:15 +02:00
|
|
|
self.len()
|
2015-08-07 00:10:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
|
|
|
|
let (start, overflow) = n.overflowing_mul(self.chunk_size);
|
|
|
|
if start >= self.v.len() || overflow {
|
|
|
|
self.v = &mut [];
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let end = match start.checked_add(self.chunk_size) {
|
|
|
|
Some(sum) => cmp::min(self.v.len(), sum),
|
|
|
|
None => self.v.len(),
|
|
|
|
};
|
|
|
|
let tmp = mem::replace(&mut self.v, &mut []);
|
|
|
|
let (head, tail) = tmp.split_at_mut(end);
|
|
|
|
let (_, nth) = head.split_at_mut(start);
|
|
|
|
self.v = tail;
|
|
|
|
Some(nth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn last(self) -> Option<Self::Item> {
|
|
|
|
if self.v.is_empty() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
|
|
|
|
Some(&mut self.v[start..])
|
|
|
|
}
|
|
|
|
}
|
2014-06-30 13:58:53 -07:00
|
|
|
}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, T> DoubleEndedIterator for ChunksMut<'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]> {
|
2015-03-24 16:53:34 -07:00
|
|
|
if self.v.is_empty() {
|
2014-06-30 13:58:53 -07:00
|
|
|
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
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-12 17:08:53 -05:00
|
|
|
impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
impl<'a, T> FusedIterator for ChunksMut<'a, T> {}
|
|
|
|
|
2018-01-03 00:58:56 +02:00
|
|
|
#[doc(hidden)]
|
|
|
|
unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
|
|
|
|
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
|
|
|
|
let start = i * self.chunk_size;
|
|
|
|
let end = cmp::min(start + self.chunk_size, self.v.len());
|
|
|
|
from_raw_parts_mut(self.v.as_mut_ptr().offset(start as isize), end - start)
|
|
|
|
}
|
|
|
|
fn may_have_side_effect() -> bool { false }
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
|
|
|
// Free functions
|
|
|
|
//
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2015-02-04 01:00:38 +02:00
|
|
|
/// Forms a slice from a pointer and a length.
|
|
|
|
///
|
|
|
|
/// The `len` argument is the number of **elements**, not the number of bytes.
|
|
|
|
///
|
2015-10-23 11:42:14 -04:00
|
|
|
/// # Safety
|
2015-07-08 13:04:41 -04:00
|
|
|
///
|
2015-02-04 01:00:38 +02:00
|
|
|
/// This function is unsafe as there is no guarantee that the given pointer is
|
|
|
|
/// valid for `len` elements, nor whether the lifetime inferred is a suitable
|
|
|
|
/// lifetime for the returned slice.
|
|
|
|
///
|
2017-04-28 12:25:02 +03:00
|
|
|
/// `p` must be non-null, even for zero-length slices, because non-zero bits
|
|
|
|
/// are required to distinguish between a zero-length slice within `Some()`
|
|
|
|
/// from `None`. `p` can be a bogus non-dereferencable pointer, such as `0x1`,
|
|
|
|
/// for zero-length slices, though.
|
2015-07-08 13:04:41 -04:00
|
|
|
///
|
2015-02-04 01:00:38 +02:00
|
|
|
/// # Caveat
|
|
|
|
///
|
|
|
|
/// The lifetime for the returned slice is inferred from its usage. To
|
|
|
|
/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
|
|
|
|
/// source lifetime is safe in the context, such as by providing a helper
|
|
|
|
/// function taking the lifetime of a host value for the slice, or by explicit
|
|
|
|
/// annotation.
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2015-02-04 01:00:38 +02:00
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-02-04 01:00:38 +02:00
|
|
|
/// use std::slice;
|
|
|
|
///
|
|
|
|
/// // manifest a slice out of thin air!
|
2015-02-14 16:04:47 -08:00
|
|
|
/// let ptr = 0x1234 as *const usize;
|
2015-02-04 01:00:38 +02:00
|
|
|
/// let amt = 10;
|
|
|
|
/// unsafe {
|
|
|
|
/// let slice = slice::from_raw_parts(ptr, amt);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
2015-03-10 13:45:08 -07:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-14 16:04:47 -08:00
|
|
|
pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
|
2016-04-07 10:42:53 -07:00
|
|
|
mem::transmute(Repr { data: p, len: len })
|
2015-02-04 01:00:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Performs the same functionality as `from_raw_parts`, except that a mutable
|
|
|
|
/// slice is returned.
|
|
|
|
///
|
|
|
|
/// This function is unsafe for the same reasons as `from_raw_parts`, as well
|
|
|
|
/// as not being able to provide a non-aliasing guarantee of the returned
|
2017-04-28 12:25:02 +03:00
|
|
|
/// mutable slice. `p` must be non-null even for zero-length slices as with
|
|
|
|
/// `from_raw_parts`.
|
2015-02-04 01:00:38 +02:00
|
|
|
#[inline]
|
2015-03-10 13:45:08 -07:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-14 16:04:47 -08:00
|
|
|
pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
|
2016-04-07 10:42:53 -07:00
|
|
|
mem::transmute(Repr { data: p, len: len })
|
2015-07-24 03:04:55 +02:00
|
|
|
}
|
|
|
|
|
2017-10-15 13:15:41 +00:00
|
|
|
/// Converts a reference to T into a slice of length 1 (without copying).
|
2017-11-01 21:56:17 +00:00
|
|
|
#[unstable(feature = "from_ref", issue = "45703")]
|
2017-10-15 13:15:41 +00:00
|
|
|
pub fn from_ref<T>(s: &T) -> &[T] {
|
|
|
|
unsafe {
|
|
|
|
from_raw_parts(s, 1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts a reference to T into a slice of length 1 (without copying).
|
2017-11-01 21:56:17 +00:00
|
|
|
#[unstable(feature = "from_ref", issue = "45703")]
|
2017-10-15 13:15:41 +00:00
|
|
|
pub fn from_ref_mut<T>(s: &mut T) -> &mut [T] {
|
|
|
|
unsafe {
|
|
|
|
from_raw_parts_mut(s, 1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-21 02:38:03 +01:00
|
|
|
// This function is public only because there is no other way to unit test heapsort.
|
|
|
|
#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "0")]
|
|
|
|
#[doc(hidden)]
|
|
|
|
pub fn heapsort<T, F>(v: &mut [T], mut is_less: F)
|
|
|
|
where F: FnMut(&T, &T) -> bool
|
|
|
|
{
|
|
|
|
sort::heapsort(v, &mut is_less);
|
|
|
|
}
|
|
|
|
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
2016-04-05 14:06:20 +02:00
|
|
|
// Comparison traits
|
2014-06-30 13:58:53 -07:00
|
|
|
//
|
2014-04-30 22:54:25 -07:00
|
|
|
|
2016-04-05 14:06:20 +02:00
|
|
|
extern {
|
2017-03-22 01:42:23 +01:00
|
|
|
/// Calls implementation provided memcmp.
|
2016-04-05 14:06:20 +02:00
|
|
|
///
|
|
|
|
/// Interprets the data as u8.
|
|
|
|
///
|
2017-03-22 01:42:23 +01:00
|
|
|
/// Returns 0 for equal, < 0 for less than and > 0 for greater
|
2016-04-05 14:06:20 +02:00
|
|
|
/// than.
|
|
|
|
// FIXME(#32610): Return type should be c_int
|
|
|
|
fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32;
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
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 {
|
2016-04-05 14:06:20 +02:00
|
|
|
SlicePartialEq::equal(self, other)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ne(&self, other: &[B]) -> bool {
|
|
|
|
SlicePartialEq::not_equal(self, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<T: Eq> Eq for [T] {}
|
|
|
|
|
2017-02-16 09:18:18 -08:00
|
|
|
/// Implements comparison of vectors lexicographically.
|
2016-04-05 14:06:20 +02:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<T: Ord> Ord for [T] {
|
|
|
|
fn cmp(&self, other: &[T]) -> Ordering {
|
|
|
|
SliceOrd::compare(self, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-16 09:18:18 -08:00
|
|
|
/// Implements comparison of vectors lexicographically.
|
2016-04-05 14:06:20 +02:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl<T: PartialOrd> PartialOrd for [T] {
|
|
|
|
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
|
|
|
|
SlicePartialOrd::partial_compare(self, other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-06 12:19:19 +02:00
|
|
|
#[doc(hidden)]
|
2016-04-05 14:06:20 +02:00
|
|
|
// intermediate trait for specialization of slice's PartialEq
|
|
|
|
trait SlicePartialEq<B> {
|
|
|
|
fn equal(&self, other: &[B]) -> bool;
|
2016-09-06 01:04:07 -04:00
|
|
|
|
|
|
|
fn not_equal(&self, other: &[B]) -> bool { !self.equal(other) }
|
2016-04-05 14:06:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Generic slice equality
|
|
|
|
impl<A, B> SlicePartialEq<B> for [A]
|
|
|
|
where A: PartialEq<B>
|
|
|
|
{
|
|
|
|
default fn equal(&self, other: &[B]) -> bool {
|
Improve PartialEq for slices
Exploiting the fact that getting the length of the slices is known, we
can use a counted loop instead of iterators, which means that we only
need a single counter, instead of having to increment and check one
pointer for each iterator.
Benchmarks comparing vectors with 100,000 elements:
Before:
```
running 8 tests
test eq1_u8 ... bench: 66,757 ns/iter (+/- 113)
test eq2_u16 ... bench: 111,267 ns/iter (+/- 149)
test eq3_u32 ... bench: 126,282 ns/iter (+/- 111)
test eq4_u64 ... bench: 126,418 ns/iter (+/- 155)
test ne1_u8 ... bench: 88,990 ns/iter (+/- 161)
test ne2_u16 ... bench: 89,126 ns/iter (+/- 265)
test ne3_u32 ... bench: 96,901 ns/iter (+/- 92)
test ne4_u64 ... bench: 96,750 ns/iter (+/- 137)
```
After:
```
running 8 tests
test eq1_u8 ... bench: 46,413 ns/iter (+/- 521)
test eq2_u16 ... bench: 46,500 ns/iter (+/- 74)
test eq3_u32 ... bench: 50,059 ns/iter (+/- 92)
test eq4_u64 ... bench: 54,001 ns/iter (+/- 92)
test ne1_u8 ... bench: 47,595 ns/iter (+/- 53)
test ne2_u16 ... bench: 47,521 ns/iter (+/- 59)
test ne3_u32 ... bench: 44,889 ns/iter (+/- 74)
test ne4_u64 ... bench: 47,775 ns/iter (+/- 68)
```
2015-07-08 14:49:55 +02:00
|
|
|
if self.len() != other.len() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for i in 0..self.len() {
|
|
|
|
if !self[i].eq(&other[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
true
|
2014-10-29 20:11:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-05 14:06:20 +02:00
|
|
|
// Use memcmp for bytewise equality when the types allow
|
|
|
|
impl<A> SlicePartialEq<A> for [A]
|
|
|
|
where A: PartialEq<A> + BytewiseEquality
|
|
|
|
{
|
|
|
|
fn equal(&self, other: &[A]) -> bool {
|
|
|
|
if self.len() != other.len() {
|
|
|
|
return false;
|
|
|
|
}
|
2016-05-26 11:23:42 -07:00
|
|
|
if self.as_ptr() == other.as_ptr() {
|
|
|
|
return true;
|
|
|
|
}
|
2016-04-05 14:06:20 +02:00
|
|
|
unsafe {
|
|
|
|
let size = mem::size_of_val(self);
|
|
|
|
memcmp(self.as_ptr() as *const u8,
|
|
|
|
other.as_ptr() as *const u8, size) == 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-06 12:19:19 +02:00
|
|
|
#[doc(hidden)]
|
2016-04-05 14:06:20 +02:00
|
|
|
// intermediate trait for specialization of slice's PartialOrd
|
|
|
|
trait SlicePartialOrd<B> {
|
|
|
|
fn partial_compare(&self, other: &[B]) -> Option<Ordering>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<A> SlicePartialOrd<A> for [A]
|
|
|
|
where A: PartialOrd
|
|
|
|
{
|
|
|
|
default fn partial_compare(&self, other: &[A]) -> Option<Ordering> {
|
Improve PartialOrd for slices
Reusing the same idea as in #26884, we can exploit the fact that the
length of slices is known, hence we can use a counted loop instead of
iterators, which means that we only need a single counter, instead of
having to increment and check one pointer for each iterator.
Using the generic implementation of the boolean comparison operators
(`lt`, `le`, `gt`, `ge`) provides further speedup for simple
types. This happens because the loop scans elements checking for
equality and dispatches to element comparison or length comparison
depending on the result of the prefix comparison.
```
test u8_cmp ... bench: 14,043 ns/iter (+/- 1,732)
test u8_lt ... bench: 16,156 ns/iter (+/- 1,864)
test u8_partial_cmp ... bench: 16,250 ns/iter (+/- 2,608)
test u16_cmp ... bench: 15,764 ns/iter (+/- 1,420)
test u16_lt ... bench: 19,833 ns/iter (+/- 2,826)
test u16_partial_cmp ... bench: 19,811 ns/iter (+/- 2,240)
test u32_cmp ... bench: 15,792 ns/iter (+/- 3,409)
test u32_lt ... bench: 18,577 ns/iter (+/- 2,075)
test u32_partial_cmp ... bench: 18,603 ns/iter (+/- 5,666)
test u64_cmp ... bench: 16,337 ns/iter (+/- 2,511)
test u64_lt ... bench: 18,074 ns/iter (+/- 7,914)
test u64_partial_cmp ... bench: 17,909 ns/iter (+/- 1,105)
```
```
test u8_cmp ... bench: 6,511 ns/iter (+/- 982)
test u8_lt ... bench: 6,671 ns/iter (+/- 919)
test u8_partial_cmp ... bench: 7,118 ns/iter (+/- 1,623)
test u16_cmp ... bench: 6,689 ns/iter (+/- 921)
test u16_lt ... bench: 6,712 ns/iter (+/- 947)
test u16_partial_cmp ... bench: 6,725 ns/iter (+/- 780)
test u32_cmp ... bench: 7,704 ns/iter (+/- 1,294)
test u32_lt ... bench: 7,611 ns/iter (+/- 3,062)
test u32_partial_cmp ... bench: 7,640 ns/iter (+/- 1,149)
test u64_cmp ... bench: 7,517 ns/iter (+/- 2,164)
test u64_lt ... bench: 7,579 ns/iter (+/- 1,048)
test u64_partial_cmp ... bench: 7,629 ns/iter (+/- 1,195)
```
2015-09-15 23:20:18 +02:00
|
|
|
let l = cmp::min(self.len(), other.len());
|
2015-09-16 16:09:23 +02:00
|
|
|
|
|
|
|
// Slice to the loop iteration range to enable bound check
|
|
|
|
// elimination in the compiler
|
Remove boundary checks in slice comparison operators
In order to get rid of all range checks, the compiler needs to
explicitly see that the slices it iterates over are as long as the
loop variable upper bound.
This further improves the performance of slice comparison:
```
test u8_cmp ... bench: 4,761 ns/iter (+/- 1,203)
test u8_lt ... bench: 4,579 ns/iter (+/- 649)
test u8_partial_cmp ... bench: 4,768 ns/iter (+/- 761)
test u16_cmp ... bench: 4,607 ns/iter (+/- 580)
test u16_lt ... bench: 4,681 ns/iter (+/- 567)
test u16_partial_cmp ... bench: 4,607 ns/iter (+/- 967)
test u32_cmp ... bench: 4,448 ns/iter (+/- 891)
test u32_lt ... bench: 4,546 ns/iter (+/- 992)
test u32_partial_cmp ... bench: 4,415 ns/iter (+/- 646)
test u64_cmp ... bench: 4,380 ns/iter (+/- 1,184)
test u64_lt ... bench: 5,684 ns/iter (+/- 602)
test u64_partial_cmp ... bench: 4,663 ns/iter (+/- 1,158)
```
2015-09-16 15:27:14 +02:00
|
|
|
let lhs = &self[..l];
|
|
|
|
let rhs = &other[..l];
|
Improve PartialOrd for slices
Reusing the same idea as in #26884, we can exploit the fact that the
length of slices is known, hence we can use a counted loop instead of
iterators, which means that we only need a single counter, instead of
having to increment and check one pointer for each iterator.
Using the generic implementation of the boolean comparison operators
(`lt`, `le`, `gt`, `ge`) provides further speedup for simple
types. This happens because the loop scans elements checking for
equality and dispatches to element comparison or length comparison
depending on the result of the prefix comparison.
```
test u8_cmp ... bench: 14,043 ns/iter (+/- 1,732)
test u8_lt ... bench: 16,156 ns/iter (+/- 1,864)
test u8_partial_cmp ... bench: 16,250 ns/iter (+/- 2,608)
test u16_cmp ... bench: 15,764 ns/iter (+/- 1,420)
test u16_lt ... bench: 19,833 ns/iter (+/- 2,826)
test u16_partial_cmp ... bench: 19,811 ns/iter (+/- 2,240)
test u32_cmp ... bench: 15,792 ns/iter (+/- 3,409)
test u32_lt ... bench: 18,577 ns/iter (+/- 2,075)
test u32_partial_cmp ... bench: 18,603 ns/iter (+/- 5,666)
test u64_cmp ... bench: 16,337 ns/iter (+/- 2,511)
test u64_lt ... bench: 18,074 ns/iter (+/- 7,914)
test u64_partial_cmp ... bench: 17,909 ns/iter (+/- 1,105)
```
```
test u8_cmp ... bench: 6,511 ns/iter (+/- 982)
test u8_lt ... bench: 6,671 ns/iter (+/- 919)
test u8_partial_cmp ... bench: 7,118 ns/iter (+/- 1,623)
test u16_cmp ... bench: 6,689 ns/iter (+/- 921)
test u16_lt ... bench: 6,712 ns/iter (+/- 947)
test u16_partial_cmp ... bench: 6,725 ns/iter (+/- 780)
test u32_cmp ... bench: 7,704 ns/iter (+/- 1,294)
test u32_lt ... bench: 7,611 ns/iter (+/- 3,062)
test u32_partial_cmp ... bench: 7,640 ns/iter (+/- 1,149)
test u64_cmp ... bench: 7,517 ns/iter (+/- 2,164)
test u64_lt ... bench: 7,579 ns/iter (+/- 1,048)
test u64_partial_cmp ... bench: 7,629 ns/iter (+/- 1,195)
```
2015-09-15 23:20:18 +02:00
|
|
|
|
|
|
|
for i in 0..l {
|
2016-04-05 14:06:20 +02:00
|
|
|
match lhs[i].partial_cmp(&rhs[i]) {
|
|
|
|
Some(Ordering::Equal) => (),
|
Improve PartialOrd for slices
Reusing the same idea as in #26884, we can exploit the fact that the
length of slices is known, hence we can use a counted loop instead of
iterators, which means that we only need a single counter, instead of
having to increment and check one pointer for each iterator.
Using the generic implementation of the boolean comparison operators
(`lt`, `le`, `gt`, `ge`) provides further speedup for simple
types. This happens because the loop scans elements checking for
equality and dispatches to element comparison or length comparison
depending on the result of the prefix comparison.
```
test u8_cmp ... bench: 14,043 ns/iter (+/- 1,732)
test u8_lt ... bench: 16,156 ns/iter (+/- 1,864)
test u8_partial_cmp ... bench: 16,250 ns/iter (+/- 2,608)
test u16_cmp ... bench: 15,764 ns/iter (+/- 1,420)
test u16_lt ... bench: 19,833 ns/iter (+/- 2,826)
test u16_partial_cmp ... bench: 19,811 ns/iter (+/- 2,240)
test u32_cmp ... bench: 15,792 ns/iter (+/- 3,409)
test u32_lt ... bench: 18,577 ns/iter (+/- 2,075)
test u32_partial_cmp ... bench: 18,603 ns/iter (+/- 5,666)
test u64_cmp ... bench: 16,337 ns/iter (+/- 2,511)
test u64_lt ... bench: 18,074 ns/iter (+/- 7,914)
test u64_partial_cmp ... bench: 17,909 ns/iter (+/- 1,105)
```
```
test u8_cmp ... bench: 6,511 ns/iter (+/- 982)
test u8_lt ... bench: 6,671 ns/iter (+/- 919)
test u8_partial_cmp ... bench: 7,118 ns/iter (+/- 1,623)
test u16_cmp ... bench: 6,689 ns/iter (+/- 921)
test u16_lt ... bench: 6,712 ns/iter (+/- 947)
test u16_partial_cmp ... bench: 6,725 ns/iter (+/- 780)
test u32_cmp ... bench: 7,704 ns/iter (+/- 1,294)
test u32_lt ... bench: 7,611 ns/iter (+/- 3,062)
test u32_partial_cmp ... bench: 7,640 ns/iter (+/- 1,149)
test u64_cmp ... bench: 7,517 ns/iter (+/- 2,164)
test u64_lt ... bench: 7,579 ns/iter (+/- 1,048)
test u64_partial_cmp ... bench: 7,629 ns/iter (+/- 1,195)
```
2015-09-15 23:20:18 +02:00
|
|
|
non_eq => return non_eq,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-05 14:06:20 +02:00
|
|
|
self.len().partial_cmp(&other.len())
|
2014-10-29 20:11:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-08 12:19:50 +01:00
|
|
|
impl<A> SlicePartialOrd<A> for [A]
|
|
|
|
where A: Ord
|
|
|
|
{
|
|
|
|
default fn partial_compare(&self, other: &[A]) -> Option<Ordering> {
|
2017-02-08 16:01:32 +01:00
|
|
|
Some(SliceOrd::compare(self, other))
|
2017-02-08 12:19:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-06 12:19:19 +02:00
|
|
|
#[doc(hidden)]
|
2016-04-05 14:06:20 +02:00
|
|
|
// intermediate trait for specialization of slice's Ord
|
|
|
|
trait SliceOrd<B> {
|
|
|
|
fn compare(&self, other: &[B]) -> Ordering;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<A> SliceOrd<A> for [A]
|
|
|
|
where A: Ord
|
|
|
|
{
|
|
|
|
default fn compare(&self, other: &[A]) -> Ordering {
|
Improve PartialOrd for slices
Reusing the same idea as in #26884, we can exploit the fact that the
length of slices is known, hence we can use a counted loop instead of
iterators, which means that we only need a single counter, instead of
having to increment and check one pointer for each iterator.
Using the generic implementation of the boolean comparison operators
(`lt`, `le`, `gt`, `ge`) provides further speedup for simple
types. This happens because the loop scans elements checking for
equality and dispatches to element comparison or length comparison
depending on the result of the prefix comparison.
```
test u8_cmp ... bench: 14,043 ns/iter (+/- 1,732)
test u8_lt ... bench: 16,156 ns/iter (+/- 1,864)
test u8_partial_cmp ... bench: 16,250 ns/iter (+/- 2,608)
test u16_cmp ... bench: 15,764 ns/iter (+/- 1,420)
test u16_lt ... bench: 19,833 ns/iter (+/- 2,826)
test u16_partial_cmp ... bench: 19,811 ns/iter (+/- 2,240)
test u32_cmp ... bench: 15,792 ns/iter (+/- 3,409)
test u32_lt ... bench: 18,577 ns/iter (+/- 2,075)
test u32_partial_cmp ... bench: 18,603 ns/iter (+/- 5,666)
test u64_cmp ... bench: 16,337 ns/iter (+/- 2,511)
test u64_lt ... bench: 18,074 ns/iter (+/- 7,914)
test u64_partial_cmp ... bench: 17,909 ns/iter (+/- 1,105)
```
```
test u8_cmp ... bench: 6,511 ns/iter (+/- 982)
test u8_lt ... bench: 6,671 ns/iter (+/- 919)
test u8_partial_cmp ... bench: 7,118 ns/iter (+/- 1,623)
test u16_cmp ... bench: 6,689 ns/iter (+/- 921)
test u16_lt ... bench: 6,712 ns/iter (+/- 947)
test u16_partial_cmp ... bench: 6,725 ns/iter (+/- 780)
test u32_cmp ... bench: 7,704 ns/iter (+/- 1,294)
test u32_lt ... bench: 7,611 ns/iter (+/- 3,062)
test u32_partial_cmp ... bench: 7,640 ns/iter (+/- 1,149)
test u64_cmp ... bench: 7,517 ns/iter (+/- 2,164)
test u64_lt ... bench: 7,579 ns/iter (+/- 1,048)
test u64_partial_cmp ... bench: 7,629 ns/iter (+/- 1,195)
```
2015-09-15 23:20:18 +02:00
|
|
|
let l = cmp::min(self.len(), other.len());
|
2015-09-16 16:09:23 +02:00
|
|
|
|
|
|
|
// Slice to the loop iteration range to enable bound check
|
|
|
|
// elimination in the compiler
|
Remove boundary checks in slice comparison operators
In order to get rid of all range checks, the compiler needs to
explicitly see that the slices it iterates over are as long as the
loop variable upper bound.
This further improves the performance of slice comparison:
```
test u8_cmp ... bench: 4,761 ns/iter (+/- 1,203)
test u8_lt ... bench: 4,579 ns/iter (+/- 649)
test u8_partial_cmp ... bench: 4,768 ns/iter (+/- 761)
test u16_cmp ... bench: 4,607 ns/iter (+/- 580)
test u16_lt ... bench: 4,681 ns/iter (+/- 567)
test u16_partial_cmp ... bench: 4,607 ns/iter (+/- 967)
test u32_cmp ... bench: 4,448 ns/iter (+/- 891)
test u32_lt ... bench: 4,546 ns/iter (+/- 992)
test u32_partial_cmp ... bench: 4,415 ns/iter (+/- 646)
test u64_cmp ... bench: 4,380 ns/iter (+/- 1,184)
test u64_lt ... bench: 5,684 ns/iter (+/- 602)
test u64_partial_cmp ... bench: 4,663 ns/iter (+/- 1,158)
```
2015-09-16 15:27:14 +02:00
|
|
|
let lhs = &self[..l];
|
|
|
|
let rhs = &other[..l];
|
Improve PartialOrd for slices
Reusing the same idea as in #26884, we can exploit the fact that the
length of slices is known, hence we can use a counted loop instead of
iterators, which means that we only need a single counter, instead of
having to increment and check one pointer for each iterator.
Using the generic implementation of the boolean comparison operators
(`lt`, `le`, `gt`, `ge`) provides further speedup for simple
types. This happens because the loop scans elements checking for
equality and dispatches to element comparison or length comparison
depending on the result of the prefix comparison.
```
test u8_cmp ... bench: 14,043 ns/iter (+/- 1,732)
test u8_lt ... bench: 16,156 ns/iter (+/- 1,864)
test u8_partial_cmp ... bench: 16,250 ns/iter (+/- 2,608)
test u16_cmp ... bench: 15,764 ns/iter (+/- 1,420)
test u16_lt ... bench: 19,833 ns/iter (+/- 2,826)
test u16_partial_cmp ... bench: 19,811 ns/iter (+/- 2,240)
test u32_cmp ... bench: 15,792 ns/iter (+/- 3,409)
test u32_lt ... bench: 18,577 ns/iter (+/- 2,075)
test u32_partial_cmp ... bench: 18,603 ns/iter (+/- 5,666)
test u64_cmp ... bench: 16,337 ns/iter (+/- 2,511)
test u64_lt ... bench: 18,074 ns/iter (+/- 7,914)
test u64_partial_cmp ... bench: 17,909 ns/iter (+/- 1,105)
```
```
test u8_cmp ... bench: 6,511 ns/iter (+/- 982)
test u8_lt ... bench: 6,671 ns/iter (+/- 919)
test u8_partial_cmp ... bench: 7,118 ns/iter (+/- 1,623)
test u16_cmp ... bench: 6,689 ns/iter (+/- 921)
test u16_lt ... bench: 6,712 ns/iter (+/- 947)
test u16_partial_cmp ... bench: 6,725 ns/iter (+/- 780)
test u32_cmp ... bench: 7,704 ns/iter (+/- 1,294)
test u32_lt ... bench: 7,611 ns/iter (+/- 3,062)
test u32_partial_cmp ... bench: 7,640 ns/iter (+/- 1,149)
test u64_cmp ... bench: 7,517 ns/iter (+/- 2,164)
test u64_lt ... bench: 7,579 ns/iter (+/- 1,048)
test u64_partial_cmp ... bench: 7,629 ns/iter (+/- 1,195)
```
2015-09-15 23:20:18 +02:00
|
|
|
|
|
|
|
for i in 0..l {
|
2016-04-05 14:06:20 +02:00
|
|
|
match lhs[i].cmp(&rhs[i]) {
|
|
|
|
Ordering::Equal => (),
|
Improve PartialOrd for slices
Reusing the same idea as in #26884, we can exploit the fact that the
length of slices is known, hence we can use a counted loop instead of
iterators, which means that we only need a single counter, instead of
having to increment and check one pointer for each iterator.
Using the generic implementation of the boolean comparison operators
(`lt`, `le`, `gt`, `ge`) provides further speedup for simple
types. This happens because the loop scans elements checking for
equality and dispatches to element comparison or length comparison
depending on the result of the prefix comparison.
```
test u8_cmp ... bench: 14,043 ns/iter (+/- 1,732)
test u8_lt ... bench: 16,156 ns/iter (+/- 1,864)
test u8_partial_cmp ... bench: 16,250 ns/iter (+/- 2,608)
test u16_cmp ... bench: 15,764 ns/iter (+/- 1,420)
test u16_lt ... bench: 19,833 ns/iter (+/- 2,826)
test u16_partial_cmp ... bench: 19,811 ns/iter (+/- 2,240)
test u32_cmp ... bench: 15,792 ns/iter (+/- 3,409)
test u32_lt ... bench: 18,577 ns/iter (+/- 2,075)
test u32_partial_cmp ... bench: 18,603 ns/iter (+/- 5,666)
test u64_cmp ... bench: 16,337 ns/iter (+/- 2,511)
test u64_lt ... bench: 18,074 ns/iter (+/- 7,914)
test u64_partial_cmp ... bench: 17,909 ns/iter (+/- 1,105)
```
```
test u8_cmp ... bench: 6,511 ns/iter (+/- 982)
test u8_lt ... bench: 6,671 ns/iter (+/- 919)
test u8_partial_cmp ... bench: 7,118 ns/iter (+/- 1,623)
test u16_cmp ... bench: 6,689 ns/iter (+/- 921)
test u16_lt ... bench: 6,712 ns/iter (+/- 947)
test u16_partial_cmp ... bench: 6,725 ns/iter (+/- 780)
test u32_cmp ... bench: 7,704 ns/iter (+/- 1,294)
test u32_lt ... bench: 7,611 ns/iter (+/- 3,062)
test u32_partial_cmp ... bench: 7,640 ns/iter (+/- 1,149)
test u64_cmp ... bench: 7,517 ns/iter (+/- 2,164)
test u64_lt ... bench: 7,579 ns/iter (+/- 1,048)
test u64_partial_cmp ... bench: 7,629 ns/iter (+/- 1,195)
```
2015-09-15 23:20:18 +02:00
|
|
|
non_eq => return non_eq,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-05 14:06:20 +02:00
|
|
|
self.len().cmp(&other.len())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// memcmp compares a sequence of unsigned bytes lexicographically.
|
|
|
|
// this matches the order we want for [u8], but no others (not even [i8]).
|
|
|
|
impl SliceOrd<u8> for [u8] {
|
|
|
|
#[inline]
|
|
|
|
fn compare(&self, other: &[u8]) -> Ordering {
|
|
|
|
let order = unsafe {
|
|
|
|
memcmp(self.as_ptr(), other.as_ptr(),
|
|
|
|
cmp::min(self.len(), other.len()))
|
|
|
|
};
|
|
|
|
if order == 0 {
|
|
|
|
self.len().cmp(&other.len())
|
|
|
|
} else if order < 0 {
|
|
|
|
Less
|
|
|
|
} else {
|
|
|
|
Greater
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-06 12:19:19 +02:00
|
|
|
#[doc(hidden)]
|
2016-04-05 14:06:20 +02:00
|
|
|
/// Trait implemented for types that can be compared for equality using
|
|
|
|
/// their bytewise representation
|
|
|
|
trait BytewiseEquality { }
|
|
|
|
|
|
|
|
macro_rules! impl_marker_for {
|
|
|
|
($traitname:ident, $($ty:ty)*) => {
|
|
|
|
$(
|
|
|
|
impl $traitname for $ty { }
|
|
|
|
)*
|
2014-10-29 20:11:16 -05:00
|
|
|
}
|
|
|
|
}
|
2016-04-05 14:06:20 +02:00
|
|
|
|
|
|
|
impl_marker_for!(BytewiseEquality,
|
|
|
|
u8 i8 u16 i16 u32 i32 u64 i64 usize isize char bool);
|
2016-04-21 21:35:39 +02:00
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
|
|
|
|
unsafe fn get_unchecked(&mut self, i: usize) -> &'a T {
|
|
|
|
&*self.ptr.offset(i as isize)
|
|
|
|
}
|
2016-10-17 10:58:21 +02:00
|
|
|
fn may_have_side_effect() -> bool { false }
|
2016-04-21 21:35:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
|
|
|
|
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut T {
|
|
|
|
&mut *self.ptr.offset(i as isize)
|
|
|
|
}
|
2016-10-17 10:58:21 +02:00
|
|
|
fn may_have_side_effect() -> bool { false }
|
2016-04-21 21:35:39 +02:00
|
|
|
}
|
2017-12-13 09:11:42 -06:00
|
|
|
|
|
|
|
trait SliceContains: Sized {
|
|
|
|
fn slice_contains(&self, x: &[Self]) -> bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> SliceContains for T where T: PartialEq {
|
|
|
|
default fn slice_contains(&self, x: &[Self]) -> bool {
|
|
|
|
x.iter().any(|y| *y == *self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SliceContains for u8 {
|
|
|
|
fn slice_contains(&self, x: &[Self]) -> bool {
|
|
|
|
memchr::memchr(*self, x).is_some()
|
|
|
|
}
|
|
|
|
}
|
2017-12-18 10:22:53 -08:00
|
|
|
|
|
|
|
impl SliceContains for i8 {
|
|
|
|
fn slice_contains(&self, x: &[Self]) -> bool {
|
|
|
|
let byte = *self as u8;
|
|
|
|
let bytes: &[u8] = unsafe { from_raw_parts(x.as_ptr() as *const u8, x.len()) };
|
|
|
|
memchr::memchr(byte, bytes).is_some()
|
|
|
|
}
|
|
|
|
}
|