2015-01-11 17:02:51 -05:00
|
|
|
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
2013-07-10 16:06:09 +02:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
|
// except according to those terms.
|
2013-07-09 16:55:04 +02:00
|
|
|
|
|
|
|
|
//! A doubly-linked list with owned nodes.
|
|
|
|
|
//!
|
2016-12-11 14:11:08 +03:00
|
|
|
//! The `LinkedList` allows pushing and popping elements at either end
|
|
|
|
|
//! in constant time.
|
|
|
|
|
//!
|
|
|
|
|
//! Almost always it is better to use `Vec` or [`VecDeque`] instead of
|
|
|
|
|
//! [`LinkedList`]. In general, array-based containers are faster,
|
|
|
|
|
//! more memory efficient and make better use of CPU cache.
|
|
|
|
|
//!
|
|
|
|
|
//! [`LinkedList`]: ../linked_list/struct.LinkedList.html
|
|
|
|
|
//! [`VecDeque`]: ../vec_deque/struct.VecDeque.html
|
2013-07-09 16:55:04 +02:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#![stable(feature = "rust1", since = "1.0.0")]
|
2015-01-04 16:35:20 -08:00
|
|
|
|
2014-12-22 09:04:23 -08:00
|
|
|
use core::cmp::Ordering;
|
2014-06-07 15:01:44 +02:00
|
|
|
use core::fmt;
|
2015-02-17 20:48:07 -08:00
|
|
|
use core::hash::{Hasher, Hash};
|
2016-08-13 14:42:36 -04:00
|
|
|
use core::iter::{FromIterator, FusedIterator};
|
2016-07-01 22:28:36 -04:00
|
|
|
use core::marker::PhantomData;
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 18:50:12 -07:00
|
|
|
use core::mem;
|
2016-02-15 22:10:01 -05:00
|
|
|
use core::ops::{BoxPlace, InPlace, Place, Placer};
|
|
|
|
|
use core::ptr::{self, Shared};
|
2012-09-19 16:52:32 -07:00
|
|
|
|
2017-06-13 15:52:59 -07:00
|
|
|
use boxed::{Box, IntermediateBox};
|
2016-04-08 23:36:54 -04:00
|
|
|
use super::SpecExtend;
|
|
|
|
|
|
2016-12-11 14:11:08 +03:00
|
|
|
/// A doubly-linked list with owned nodes.
|
|
|
|
|
///
|
|
|
|
|
/// The `LinkedList` allows pushing and popping elements at either end
|
|
|
|
|
/// in constant time.
|
|
|
|
|
///
|
|
|
|
|
/// Almost always it is better to use `Vec` or `VecDeque` instead of
|
|
|
|
|
/// `LinkedList`. In general, array-based containers are faster,
|
|
|
|
|
/// more memory efficient and make better use of CPU cache.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-17 23:44:55 -08:00
|
|
|
pub struct LinkedList<T> {
|
2016-07-01 22:28:36 -04:00
|
|
|
head: Option<Shared<Node<T>>>,
|
|
|
|
|
tail: Option<Shared<Node<T>>>,
|
|
|
|
|
len: usize,
|
|
|
|
|
marker: PhantomData<Box<Node<T>>>,
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
}
|
|
|
|
|
|
2013-07-09 16:55:04 +02:00
|
|
|
struct Node<T> {
|
2016-07-01 22:28:36 -04:00
|
|
|
next: Option<Shared<Node<T>>>,
|
|
|
|
|
prev: Option<Shared<Node<T>>>,
|
|
|
|
|
element: T,
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
2012-09-19 16:52:32 -07:00
|
|
|
|
2017-04-13 20:11:29 +02:00
|
|
|
/// An iterator over the elements of a `LinkedList`.
|
|
|
|
|
///
|
|
|
|
|
/// This `struct` is created by the [`iter`] method on [`LinkedList`]. See its
|
|
|
|
|
/// documentation for more.
|
|
|
|
|
///
|
|
|
|
|
/// [`iter`]: struct.LinkedList.html#method.iter
|
|
|
|
|
/// [`LinkedList`]: struct.LinkedList.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-24 11:23:48 +13:00
|
|
|
pub struct Iter<'a, T: 'a> {
|
2016-07-01 22:28:36 -04:00
|
|
|
head: Option<Shared<Node<T>>>,
|
|
|
|
|
tail: Option<Shared<Node<T>>>,
|
|
|
|
|
len: usize,
|
|
|
|
|
marker: PhantomData<&'a Node<T>>,
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
|
|
|
|
|
2017-01-21 00:33:38 +01:00
|
|
|
#[stable(feature = "collection_debug", since = "1.17.0")]
|
2017-01-11 23:12:49 +01:00
|
|
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-01-21 00:33:38 +01:00
|
|
|
f.debug_tuple("Iter")
|
2017-04-17 18:06:43 +02:00
|
|
|
.field(&self.len)
|
2017-01-11 23:12:49 +01:00
|
|
|
.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")]
|
2014-12-19 21:52:10 +01:00
|
|
|
impl<'a, T> Clone for Iter<'a, T> {
|
2016-07-01 22:28:36 -04:00
|
|
|
fn clone(&self) -> Self {
|
|
|
|
|
Iter { ..*self }
|
2014-12-30 19:07:53 -05:00
|
|
|
}
|
2014-01-28 00:20:50 +11:00
|
|
|
}
|
|
|
|
|
|
2017-04-13 20:11:29 +02:00
|
|
|
/// A mutable iterator over the elements of a `LinkedList`.
|
|
|
|
|
///
|
|
|
|
|
/// This `struct` is created by the [`iter_mut`] method on [`LinkedList`]. See its
|
|
|
|
|
/// documentation for more.
|
|
|
|
|
///
|
|
|
|
|
/// [`iter_mut`]: struct.LinkedList.html#method.iter_mut
|
|
|
|
|
/// [`LinkedList`]: struct.LinkedList.html
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-24 11:23:48 +13:00
|
|
|
pub struct IterMut<'a, T: 'a> {
|
2015-02-17 23:44:55 -08:00
|
|
|
list: &'a mut LinkedList<T>,
|
2016-07-01 22:28:36 -04:00
|
|
|
head: Option<Shared<Node<T>>>,
|
|
|
|
|
tail: Option<Shared<Node<T>>>,
|
|
|
|
|
len: usize,
|
2014-08-27 21:46:52 -04:00
|
|
|
}
|
|
|
|
|
|
2017-01-21 00:33:38 +01:00
|
|
|
#[stable(feature = "collection_debug", since = "1.17.0")]
|
2017-01-11 23:12:49 +01:00
|
|
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-01-21 00:33:38 +01:00
|
|
|
f.debug_tuple("IterMut")
|
2017-04-17 18:06:43 +02:00
|
|
|
.field(&self.list)
|
|
|
|
|
.field(&self.len)
|
2017-01-11 23:12:49 +01:00
|
|
|
.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-13 20:11:29 +02:00
|
|
|
/// An owning iterator over the elements of a `LinkedList`.
|
|
|
|
|
///
|
2017-04-21 16:09:28 +02:00
|
|
|
/// This `struct` is created by the [`into_iter`] method on [`LinkedList`][`LinkedList`]
|
2017-04-13 20:11:29 +02:00
|
|
|
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
|
|
|
|
///
|
|
|
|
|
/// [`into_iter`]: struct.LinkedList.html#method.into_iter
|
|
|
|
|
/// [`LinkedList`]: struct.LinkedList.html
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
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 IntoIter<T> {
|
2015-11-24 11:23:48 +13:00
|
|
|
list: LinkedList<T>,
|
2012-08-27 14:22:25 -07:00
|
|
|
}
|
2012-06-30 00:21:15 -04:00
|
|
|
|
2017-01-21 00:33:38 +01:00
|
|
|
#[stable(feature = "collection_debug", since = "1.17.0")]
|
2017-01-11 23:12:49 +01:00
|
|
|
impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-01-21 00:33:38 +01:00
|
|
|
f.debug_tuple("IntoIter")
|
2017-04-17 18:06:43 +02:00
|
|
|
.field(&self.list)
|
2017-01-11 23:12:49 +01:00
|
|
|
.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-21 19:31:40 +02:00
|
|
|
impl<T> Node<T> {
|
2016-07-01 22:28:36 -04:00
|
|
|
fn new(element: T) -> Self {
|
2015-11-24 11:23:48 +13:00
|
|
|
Node {
|
|
|
|
|
next: None,
|
2016-07-01 22:28:36 -04:00
|
|
|
prev: None,
|
2017-08-06 22:54:09 -07:00
|
|
|
element,
|
2015-11-24 11:23:48 +13:00
|
|
|
}
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
2015-06-06 14:26:40 +02:00
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
fn into_element(self: Box<Self>) -> T {
|
|
|
|
|
self.element
|
2015-06-06 14:26:40 +02:00
|
|
|
}
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// private methods
|
2015-02-17 23:44:55 -08:00
|
|
|
impl<T> LinkedList<T> {
|
2016-07-01 22:28:36 -04:00
|
|
|
/// Adds the given node to the front of the list.
|
2013-07-21 19:31:40 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn push_front_node(&mut self, mut node: Box<Node<T>>) {
|
|
|
|
|
unsafe {
|
|
|
|
|
node.next = self.head;
|
|
|
|
|
node.prev = None;
|
2017-07-14 12:47:06 +02:00
|
|
|
let node = Some(Shared::from(Box::into_unique(node)));
|
2016-07-01 22:28:36 -04:00
|
|
|
|
|
|
|
|
match self.head {
|
|
|
|
|
None => self.tail = node,
|
2017-04-04 12:31:38 -04:00
|
|
|
Some(mut head) => head.as_mut().prev = node,
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
2016-07-01 22:28:36 -04:00
|
|
|
|
|
|
|
|
self.head = node;
|
|
|
|
|
self.len += 1;
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
/// Removes and returns the node at the front of the list.
|
2013-07-21 19:31:40 +02:00
|
|
|
#[inline]
|
2014-05-05 18:56:44 -07:00
|
|
|
fn pop_front_node(&mut self) -> Option<Box<Node<T>>> {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.head.map(|node| unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
let node = Box::from_raw(node.as_ptr());
|
2016-07-01 22:28:36 -04:00
|
|
|
self.head = node.next;
|
|
|
|
|
|
|
|
|
|
match self.head {
|
|
|
|
|
None => self.tail = None,
|
2017-04-04 12:31:38 -04:00
|
|
|
Some(mut head) => head.as_mut().prev = None,
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
2016-07-01 22:28:36 -04:00
|
|
|
|
|
|
|
|
self.len -= 1;
|
|
|
|
|
node
|
2013-11-20 15:46:49 -08:00
|
|
|
})
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
|
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
/// Adds the given node to the back of the list.
|
2013-07-21 19:31:40 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn push_back_node(&mut self, mut node: Box<Node<T>>) {
|
|
|
|
|
unsafe {
|
|
|
|
|
node.next = None;
|
|
|
|
|
node.prev = self.tail;
|
2017-07-14 12:47:06 +02:00
|
|
|
let node = Some(Shared::from(Box::into_unique(node)));
|
2016-07-01 22:28:36 -04:00
|
|
|
|
|
|
|
|
match self.tail {
|
|
|
|
|
None => self.head = node,
|
2017-04-04 12:31:38 -04:00
|
|
|
Some(mut tail) => tail.as_mut().next = node,
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
2016-07-01 22:28:36 -04:00
|
|
|
|
|
|
|
|
self.tail = node;
|
|
|
|
|
self.len += 1;
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
/// Removes and returns the node at the back of the list.
|
2013-07-21 19:31:40 +02:00
|
|
|
#[inline]
|
2014-05-05 18:56:44 -07:00
|
|
|
fn pop_back_node(&mut self) -> Option<Box<Node<T>>> {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.tail.map(|node| unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
let node = Box::from_raw(node.as_ptr());
|
2016-07-01 22:28:36 -04:00
|
|
|
self.tail = node.prev;
|
|
|
|
|
|
|
|
|
|
match self.tail {
|
|
|
|
|
None => self.head = None,
|
2017-04-04 12:31:38 -04:00
|
|
|
Some(mut tail) => tail.as_mut().next = None,
|
2016-07-01 22:28:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.len -= 1;
|
|
|
|
|
node
|
|
|
|
|
})
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
2017-11-25 18:35:30 +01:00
|
|
|
|
|
|
|
|
/// Unlinks the specified node from the current list.
|
|
|
|
|
///
|
|
|
|
|
/// Warning: this will not check that the provided node belongs to the current list.
|
|
|
|
|
#[inline]
|
|
|
|
|
unsafe fn unlink_node(&mut self, mut node: Shared<Node<T>>) {
|
|
|
|
|
let node = node.as_mut();
|
|
|
|
|
|
|
|
|
|
match node.prev {
|
|
|
|
|
Some(mut prev) => prev.as_mut().next = node.next.clone(),
|
|
|
|
|
// this node is the head node
|
|
|
|
|
None => self.head = node.next.clone(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
match node.next {
|
|
|
|
|
Some(mut next) => next.as_mut().prev = node.prev.clone(),
|
|
|
|
|
// this node is the tail node
|
|
|
|
|
None => self.tail = node.prev.clone(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.len -= 1;
|
|
|
|
|
}
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-17 23:44:55 -08:00
|
|
|
impl<T> Default for LinkedList<T> {
|
2016-09-11 17:00:09 +05:30
|
|
|
/// Creates an empty `LinkedList<T>`.
|
2014-06-09 00:30:04 -07:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn default() -> Self {
|
|
|
|
|
Self::new()
|
2015-11-24 11:23:48 +13:00
|
|
|
}
|
2014-06-09 00:30:04 -07:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 23:44:55 -08:00
|
|
|
impl<T> LinkedList<T> {
|
|
|
|
|
/// Creates an empty `LinkedList`.
|
2016-07-16 17:27:55 +02:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::collections::LinkedList;
|
|
|
|
|
///
|
|
|
|
|
/// let list: LinkedList<u32> = LinkedList::new();
|
|
|
|
|
/// ```
|
2013-07-10 15:27:15 +02:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
pub fn new() -> Self {
|
2015-11-24 11:23:48 +13:00
|
|
|
LinkedList {
|
2016-07-01 22:28:36 -04:00
|
|
|
head: None,
|
|
|
|
|
tail: None,
|
|
|
|
|
len: 0,
|
|
|
|
|
marker: PhantomData,
|
2015-11-24 11:23:48 +13:00
|
|
|
}
|
2013-07-10 15:27:15 +02:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
|
2015-01-01 16:30:11 +08:00
|
|
|
/// Moves all elements from `other` to the end of the list.
|
2013-07-09 16:55:04 +02:00
|
|
|
///
|
2015-01-01 16:30:11 +08:00
|
|
|
/// This reuses all the nodes from `other` and moves them into `self`. After
|
|
|
|
|
/// this operation, `other` becomes empty.
|
|
|
|
|
///
|
|
|
|
|
/// This operation should compute in O(1) time and O(1) memory.
|
2014-07-17 16:46:27 -04:00
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
/// # Examples
|
2014-07-17 16:46:27 -04:00
|
|
|
///
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2014-07-17 16:46:27 -04:00
|
|
|
///
|
2016-07-28 22:09:31 -04:00
|
|
|
/// let mut list1 = LinkedList::new();
|
|
|
|
|
/// list1.push_back('a');
|
2014-07-17 16:46:27 -04:00
|
|
|
///
|
2016-07-28 22:09:31 -04:00
|
|
|
/// let mut list2 = LinkedList::new();
|
|
|
|
|
/// list2.push_back('b');
|
|
|
|
|
/// list2.push_back('c');
|
2014-07-17 16:46:27 -04:00
|
|
|
///
|
2016-07-28 22:09:31 -04:00
|
|
|
/// list1.append(&mut list2);
|
|
|
|
|
///
|
|
|
|
|
/// let mut iter = list1.iter();
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&'a'));
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&'b'));
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&'c'));
|
|
|
|
|
/// assert!(iter.next().is_none());
|
|
|
|
|
///
|
|
|
|
|
/// assert!(list2.is_empty());
|
2014-07-17 16:46:27 -04:00
|
|
|
/// ```
|
2015-03-31 13:47:57 -07:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
pub fn append(&mut self, other: &mut Self) {
|
|
|
|
|
match self.tail {
|
|
|
|
|
None => mem::swap(self, other),
|
2017-04-04 12:31:38 -04:00
|
|
|
Some(mut tail) => {
|
|
|
|
|
if let Some(mut other_head) = other.head.take() {
|
2016-12-20 09:54:00 +05:30
|
|
|
unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
tail.as_mut().next = Some(other_head);
|
|
|
|
|
other_head.as_mut().prev = Some(tail);
|
2016-12-20 09:54:00 +05:30
|
|
|
}
|
2016-07-01 22:28:36 -04:00
|
|
|
|
2016-12-20 09:54:00 +05:30
|
|
|
self.tail = other.tail.take();
|
|
|
|
|
self.len += mem::replace(&mut other.len, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Provides a forward iterator.
|
2016-07-16 17:27:55 +02:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::collections::LinkedList;
|
|
|
|
|
///
|
|
|
|
|
/// let mut list: LinkedList<u32> = LinkedList::new();
|
|
|
|
|
///
|
|
|
|
|
/// list.push_back(0);
|
|
|
|
|
/// list.push_back(1);
|
|
|
|
|
/// list.push_back(2);
|
|
|
|
|
///
|
|
|
|
|
/// let mut iter = list.iter();
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&0));
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&1));
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&2));
|
|
|
|
|
/// assert_eq!(iter.next(), None);
|
|
|
|
|
/// ```
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-30 19:07:53 -05:00
|
|
|
pub fn iter(&self) -> Iter<T> {
|
2015-11-24 11:23:48 +13:00
|
|
|
Iter {
|
2016-07-01 22:28:36 -04:00
|
|
|
head: self.head,
|
|
|
|
|
tail: self.tail,
|
|
|
|
|
len: self.len,
|
|
|
|
|
marker: PhantomData,
|
2015-11-24 11:23:48 +13:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-08-04 22:48:39 +12:00
|
|
|
/// Provides a forward iterator with mutable references.
|
2016-07-16 17:27:55 +02:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::collections::LinkedList;
|
|
|
|
|
///
|
|
|
|
|
/// let mut list: LinkedList<u32> = LinkedList::new();
|
|
|
|
|
///
|
|
|
|
|
/// list.push_back(0);
|
|
|
|
|
/// list.push_back(1);
|
|
|
|
|
/// list.push_back(2);
|
|
|
|
|
///
|
|
|
|
|
/// for element in list.iter_mut() {
|
|
|
|
|
/// *element += 10;
|
|
|
|
|
/// }
|
|
|
|
|
///
|
|
|
|
|
/// let mut iter = list.iter();
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&10));
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&11));
|
|
|
|
|
/// assert_eq!(iter.next(), Some(&12));
|
|
|
|
|
/// assert_eq!(iter.next(), None);
|
|
|
|
|
/// ```
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-30 19:07:53 -05:00
|
|
|
pub fn iter_mut(&mut self) -> IterMut<T> {
|
2015-06-06 14:26:40 +02:00
|
|
|
IterMut {
|
2016-07-01 22:28:36 -04:00
|
|
|
head: self.head,
|
|
|
|
|
tail: self.tail,
|
|
|
|
|
len: self.len,
|
2015-11-24 11:23:48 +13:00
|
|
|
list: self,
|
2013-07-12 04:23:15 +02:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap)
This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also
deprecates related functions like rsplit, rev_components, and rev_str_components. In every case,
these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this
more concrete, a translation table for all functional changes necessary follows:
* container.rev_iter() -> container.iter().rev()
* container.mut_rev_iter() -> container.mut_iter().rev()
* container.move_rev_iter() -> container.move_iter().rev()
* sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev()
* path.rev_components() -> path.components().rev()
* path.rev_str_components() -> path.str_components().rev()
In terms of the type system, this change also deprecates any specialized reversed iterator types (except
in treemap), opting instead to use Rev directly if any type annotations are needed. However, since
methods directly returning reversed iterators are now discouraged, the need for such annotations should
be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in
the original reversed name and surround it with Rev<>:
* RevComponents<'a> -> Rev<Components<'a>>
* RevStrComponents<'a> -> Rev<StrComponents<'a>>
* RevItems<'a, T> -> Rev<Items<'a, T>>
* etc.
The reasoning behind this change is that it makes the standard API much simpler without reducing readability,
performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries
(all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two
characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice
like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft
goes away.
[breaking-change]
2014-04-20 23:59:12 -05:00
|
|
|
|
2015-02-17 23:44:55 -08:00
|
|
|
/// Returns `true` if the `LinkedList` is empty.
|
2014-10-30 13:43:24 -07:00
|
|
|
///
|
|
|
|
|
/// This operation should compute in O(1) time.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
/// assert!(dl.is_empty());
|
|
|
|
|
///
|
|
|
|
|
/// dl.push_front("foo");
|
|
|
|
|
/// assert!(!dl.is_empty());
|
|
|
|
|
/// ```
|
2014-10-30 13:43:24 -07:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-30 13:43:24 -07:00
|
|
|
pub fn is_empty(&self) -> bool {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.head.is_none()
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 23:44:55 -08:00
|
|
|
/// Returns the length of the `LinkedList`.
|
2014-10-30 13:43:24 -07:00
|
|
|
///
|
|
|
|
|
/// This operation should compute in O(1) time.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-01-31 17:23:42 +01:00
|
|
|
/// dl.push_front(2);
|
2015-01-11 17:02:51 -05:00
|
|
|
/// assert_eq!(dl.len(), 1);
|
|
|
|
|
///
|
|
|
|
|
/// dl.push_front(1);
|
|
|
|
|
/// assert_eq!(dl.len(), 2);
|
|
|
|
|
///
|
|
|
|
|
/// dl.push_back(3);
|
|
|
|
|
/// assert_eq!(dl.len(), 3);
|
|
|
|
|
/// ```
|
2014-10-30 13:43:24 -07:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
pub fn len(&self) -> usize {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.len
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 23:44:55 -08:00
|
|
|
/// Removes all elements from the `LinkedList`.
|
2014-10-30 13:43:24 -07:00
|
|
|
///
|
|
|
|
|
/// This operation should compute in O(n) time.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-01-31 17:23:42 +01:00
|
|
|
/// dl.push_front(2);
|
2015-01-11 17:02:51 -05:00
|
|
|
/// dl.push_front(1);
|
|
|
|
|
/// assert_eq!(dl.len(), 2);
|
2015-01-31 17:23:42 +01:00
|
|
|
/// assert_eq!(dl.front(), Some(&1));
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// dl.clear();
|
|
|
|
|
/// assert_eq!(dl.len(), 0);
|
|
|
|
|
/// assert_eq!(dl.front(), None);
|
|
|
|
|
/// ```
|
2014-10-30 13:43:24 -07:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-30 13:43:24 -07:00
|
|
|
pub fn clear(&mut self) {
|
2016-07-01 22:28:36 -04:00
|
|
|
*self = Self::new();
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
2016-04-14 16:07:53 +02:00
|
|
|
/// Returns `true` if the `LinkedList` contains an element equal to the
|
|
|
|
|
/// given value.
|
2016-07-16 17:27:55 +02:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::collections::LinkedList;
|
|
|
|
|
///
|
|
|
|
|
/// let mut list: LinkedList<u32> = LinkedList::new();
|
|
|
|
|
///
|
|
|
|
|
/// list.push_back(0);
|
|
|
|
|
/// list.push_back(1);
|
|
|
|
|
/// list.push_back(2);
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(list.contains(&0), true);
|
|
|
|
|
/// assert_eq!(list.contains(&10), false);
|
|
|
|
|
/// ```
|
2016-08-11 14:08:24 -07:00
|
|
|
#[stable(feature = "linked_list_contains", since = "1.12.0")]
|
2016-04-14 16:07:53 +02:00
|
|
|
pub fn contains(&self, x: &T) -> bool
|
|
|
|
|
where T: PartialEq<T>
|
|
|
|
|
{
|
|
|
|
|
self.iter().any(|e| e == x)
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-30 13:43:24 -07:00
|
|
|
/// Provides a reference to the front element, or `None` if the list is
|
|
|
|
|
/// empty.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
/// assert_eq!(dl.front(), None);
|
|
|
|
|
///
|
|
|
|
|
/// dl.push_front(1);
|
2015-01-31 17:23:42 +01:00
|
|
|
/// assert_eq!(dl.front(), Some(&1));
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2014-10-30 13:43:24 -07:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-06 12:24:47 -05:00
|
|
|
pub fn front(&self) -> Option<&T> {
|
2017-04-04 12:31:38 -04:00
|
|
|
unsafe {
|
|
|
|
|
self.head.as_ref().map(|node| &node.as_ref().element)
|
|
|
|
|
}
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Provides a mutable reference to the front element, or `None` if the list
|
|
|
|
|
/// is empty.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
/// assert_eq!(dl.front(), None);
|
|
|
|
|
///
|
|
|
|
|
/// dl.push_front(1);
|
2015-01-31 17:23:42 +01:00
|
|
|
/// assert_eq!(dl.front(), Some(&1));
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// match dl.front_mut() {
|
|
|
|
|
/// None => {},
|
2015-01-31 17:23:42 +01:00
|
|
|
/// Some(x) => *x = 5,
|
2015-01-11 17:02:51 -05:00
|
|
|
/// }
|
2015-01-31 17:23:42 +01:00
|
|
|
/// assert_eq!(dl.front(), Some(&5));
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2014-10-30 13:43:24 -07:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-06 12:24:47 -05:00
|
|
|
pub fn front_mut(&mut self) -> Option<&mut T> {
|
2017-04-04 12:31:38 -04:00
|
|
|
unsafe {
|
|
|
|
|
self.head.as_mut().map(|node| &mut node.as_mut().element)
|
|
|
|
|
}
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Provides a reference to the back element, or `None` if the list is
|
|
|
|
|
/// empty.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
/// assert_eq!(dl.back(), None);
|
|
|
|
|
///
|
|
|
|
|
/// dl.push_back(1);
|
2015-01-31 17:23:42 +01:00
|
|
|
/// assert_eq!(dl.back(), Some(&1));
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2014-10-30 13:43:24 -07:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-06 12:24:47 -05:00
|
|
|
pub fn back(&self) -> Option<&T> {
|
2017-04-04 12:31:38 -04:00
|
|
|
unsafe {
|
|
|
|
|
self.tail.as_ref().map(|node| &node.as_ref().element)
|
|
|
|
|
}
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Provides a mutable reference to the back element, or `None` if the list
|
|
|
|
|
/// is empty.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
/// assert_eq!(dl.back(), None);
|
|
|
|
|
///
|
|
|
|
|
/// dl.push_back(1);
|
2015-01-31 17:23:42 +01:00
|
|
|
/// assert_eq!(dl.back(), Some(&1));
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// match dl.back_mut() {
|
|
|
|
|
/// None => {},
|
2015-01-31 17:23:42 +01:00
|
|
|
/// Some(x) => *x = 5,
|
2015-01-11 17:02:51 -05:00
|
|
|
/// }
|
2015-01-31 17:23:42 +01:00
|
|
|
/// assert_eq!(dl.back(), Some(&5));
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2014-10-30 13:43:24 -07:00
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-06 12:24:47 -05:00
|
|
|
pub fn back_mut(&mut self) -> Option<&mut T> {
|
2017-04-04 12:31:38 -04:00
|
|
|
unsafe {
|
|
|
|
|
self.tail.as_mut().map(|node| &mut node.as_mut().element)
|
|
|
|
|
}
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Adds an element first in the list.
|
|
|
|
|
///
|
|
|
|
|
/// This operation should compute in O(1) time.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut dl = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-01-31 17:23:42 +01:00
|
|
|
/// dl.push_front(2);
|
|
|
|
|
/// assert_eq!(dl.front().unwrap(), &2);
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// dl.push_front(1);
|
|
|
|
|
/// assert_eq!(dl.front().unwrap(), &1);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-30 13:43:24 -07:00
|
|
|
pub fn push_front(&mut self, elt: T) {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.push_front_node(box Node::new(elt));
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Removes the first element and returns it, or `None` if the list is
|
|
|
|
|
/// empty.
|
|
|
|
|
///
|
|
|
|
|
/// This operation should compute in O(1) time.
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut d = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
/// assert_eq!(d.pop_front(), None);
|
|
|
|
|
///
|
2015-01-31 17:23:42 +01:00
|
|
|
/// d.push_front(1);
|
2015-01-11 17:02:51 -05:00
|
|
|
/// d.push_front(3);
|
|
|
|
|
/// assert_eq!(d.pop_front(), Some(3));
|
|
|
|
|
/// assert_eq!(d.pop_front(), Some(1));
|
|
|
|
|
/// assert_eq!(d.pop_front(), None);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-30 13:43:24 -07:00
|
|
|
pub fn pop_front(&mut self) -> Option<T> {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.pop_front_node().map(Node::into_element)
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Appends an element to the back of a list
|
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
/// # Examples
|
2014-10-30 13:43:24 -07:00
|
|
|
///
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2014-10-30 13:43:24 -07:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut d = LinkedList::new();
|
2015-01-25 22:05:03 +01:00
|
|
|
/// d.push_back(1);
|
2014-11-06 12:24:47 -05:00
|
|
|
/// d.push_back(3);
|
2014-10-30 13:43:24 -07:00
|
|
|
/// assert_eq!(3, *d.back().unwrap());
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-06 12:24:47 -05:00
|
|
|
pub fn push_back(&mut self, elt: T) {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.push_back_node(box Node::new(elt));
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Removes the last element from a list and returns it, or `None` if
|
|
|
|
|
/// it is empty.
|
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
/// # Examples
|
2014-10-30 13:43:24 -07:00
|
|
|
///
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2014-10-30 13:43:24 -07:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut d = LinkedList::new();
|
2014-11-06 12:24:47 -05:00
|
|
|
/// assert_eq!(d.pop_back(), None);
|
2015-01-25 22:05:03 +01:00
|
|
|
/// d.push_back(1);
|
2014-11-06 12:24:47 -05:00
|
|
|
/// d.push_back(3);
|
|
|
|
|
/// assert_eq!(d.pop_back(), Some(3));
|
2014-10-30 13:43:24 -07:00
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-06 12:24:47 -05:00
|
|
|
pub fn pop_back(&mut self) -> Option<T> {
|
2016-07-01 22:28:36 -04:00
|
|
|
self.pop_back_node().map(Node::into_element)
|
2014-10-30 13:43:24 -07:00
|
|
|
}
|
2015-01-01 16:30:11 +08:00
|
|
|
|
|
|
|
|
/// Splits the list into two at the given index. Returns everything after the given index,
|
|
|
|
|
/// including the index.
|
|
|
|
|
///
|
2017-04-13 21:30:59 +02:00
|
|
|
/// This operation should compute in O(n) time.
|
|
|
|
|
///
|
2015-02-12 17:11:08 -05:00
|
|
|
/// # Panics
|
|
|
|
|
///
|
|
|
|
|
/// Panics if `at > len`.
|
|
|
|
|
///
|
2015-01-11 17:02:51 -05:00
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut d = LinkedList::new();
|
2015-01-11 17:02:51 -05:00
|
|
|
///
|
2015-01-31 17:23:42 +01:00
|
|
|
/// d.push_front(1);
|
2015-01-11 17:02:51 -05:00
|
|
|
/// d.push_front(2);
|
|
|
|
|
/// d.push_front(3);
|
|
|
|
|
///
|
|
|
|
|
/// let mut splitted = d.split_off(2);
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(splitted.pop_front(), Some(1));
|
|
|
|
|
/// assert_eq!(splitted.pop_front(), None);
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-17 23:44:55 -08:00
|
|
|
pub fn split_off(&mut self, at: usize) -> LinkedList<T> {
|
2015-01-01 16:30:11 +08:00
|
|
|
let len = self.len();
|
2015-02-12 17:11:08 -05:00
|
|
|
assert!(at <= len, "Cannot split off at a nonexistent index");
|
2015-01-01 16:30:11 +08:00
|
|
|
if at == 0 {
|
2016-07-01 22:28:36 -04:00
|
|
|
return mem::replace(self, Self::new());
|
2015-02-12 17:11:08 -05:00
|
|
|
} else if at == len {
|
2016-07-01 22:28:36 -04:00
|
|
|
return Self::new();
|
2015-01-01 16:30:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Below, we iterate towards the `i-1`th node, either from the start or the end,
|
|
|
|
|
// depending on which would be faster.
|
2016-07-01 22:28:36 -04:00
|
|
|
let split_node = if at - 1 <= len - 1 - (at - 1) {
|
2015-01-01 16:30:11 +08:00
|
|
|
let mut iter = self.iter_mut();
|
|
|
|
|
// instead of skipping using .skip() (which creates a new struct),
|
|
|
|
|
// we skip manually so we can access the head field without
|
|
|
|
|
// depending on implementation details of Skip
|
2015-01-26 15:46:12 -05:00
|
|
|
for _ in 0..at - 1 {
|
2015-01-01 16:30:11 +08:00
|
|
|
iter.next();
|
|
|
|
|
}
|
|
|
|
|
iter.head
|
2015-11-24 11:23:48 +13:00
|
|
|
} else {
|
2015-01-01 16:30:11 +08:00
|
|
|
// better off starting from the end
|
|
|
|
|
let mut iter = self.iter_mut();
|
2015-01-26 16:05:07 -05:00
|
|
|
for _ in 0..len - 1 - (at - 1) {
|
2015-01-01 16:30:11 +08:00
|
|
|
iter.next_back();
|
|
|
|
|
}
|
|
|
|
|
iter.tail
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-06 14:26:39 +02:00
|
|
|
// The split node is the new tail node of the first part and owns
|
|
|
|
|
// the head of the second part.
|
2016-07-01 22:28:36 -04:00
|
|
|
let second_part_head;
|
2015-06-06 14:26:39 +02:00
|
|
|
|
|
|
|
|
unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
second_part_head = split_node.unwrap().as_mut().next.take();
|
|
|
|
|
if let Some(mut head) = second_part_head {
|
|
|
|
|
head.as_mut().prev = None;
|
2015-06-06 14:26:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let second_part = LinkedList {
|
2016-07-01 22:28:36 -04:00
|
|
|
head: second_part_head,
|
|
|
|
|
tail: self.tail,
|
|
|
|
|
len: len - at,
|
|
|
|
|
marker: PhantomData,
|
2015-01-01 16:30:11 +08:00
|
|
|
};
|
|
|
|
|
|
2015-06-06 14:26:39 +02:00
|
|
|
// Fix the tail ptr of the first part
|
2016-07-01 22:28:36 -04:00
|
|
|
self.tail = split_node;
|
|
|
|
|
self.len = at;
|
2015-01-01 16:30:11 +08:00
|
|
|
|
2015-06-06 14:26:39 +02:00
|
|
|
second_part
|
2015-01-01 16:30:11 +08:00
|
|
|
}
|
2016-02-15 22:10:01 -05:00
|
|
|
|
2017-11-25 21:14:37 +01:00
|
|
|
/// Creates an iterator which uses a closure to determine if an element should be removed.
|
2017-11-25 18:35:30 +01:00
|
|
|
///
|
2017-11-25 21:14:37 +01:00
|
|
|
/// If the closure returns true, then the element is removed and yielded.
|
|
|
|
|
/// If the closure returns false, it will try again, and call the closure on the next element,
|
|
|
|
|
/// seeing if it passes the test.
|
|
|
|
|
///
|
|
|
|
|
/// Note that `drain_filter` lets you mutate every element in the filter closure, regardless of
|
|
|
|
|
/// whether you choose to keep or remove it.
|
2017-11-25 18:35:30 +01:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
2017-11-25 21:14:37 +01:00
|
|
|
/// Splitting a list into evens and odds, reusing the original list:
|
2017-11-25 18:35:30 +01:00
|
|
|
///
|
2017-11-25 21:14:37 +01:00
|
|
|
/// ```
|
|
|
|
|
/// #![feature(drain_filter)]
|
2017-11-25 18:35:30 +01:00
|
|
|
/// use std::collections::LinkedList;
|
|
|
|
|
///
|
2017-11-25 21:14:37 +01:00
|
|
|
/// let mut numbers: LinkedList<u32> = LinkedList::new();
|
|
|
|
|
/// numbers.extend(&[1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]);
|
|
|
|
|
///
|
|
|
|
|
/// let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::<LinkedList<_>>();
|
|
|
|
|
/// let odds = numbers;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(evens.into_iter().collect::<Vec<_>>(), vec![2, 4, 6, 8, 14]);
|
|
|
|
|
/// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 9, 11, 13, 15]);
|
2017-11-25 18:35:30 +01:00
|
|
|
/// ```
|
2017-11-25 21:14:37 +01:00
|
|
|
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
|
|
|
|
|
pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<T, F>
|
|
|
|
|
where F: FnMut(&mut T) -> bool
|
2017-11-25 18:35:30 +01:00
|
|
|
{
|
2017-11-25 21:14:37 +01:00
|
|
|
// avoid borrow issues.
|
|
|
|
|
let it = self.head;
|
|
|
|
|
let old_len = self.len;
|
2017-11-25 18:35:30 +01:00
|
|
|
|
2017-11-25 21:14:37 +01:00
|
|
|
DrainFilter {
|
|
|
|
|
list: self,
|
|
|
|
|
it: it,
|
|
|
|
|
pred: filter,
|
|
|
|
|
idx: 0,
|
|
|
|
|
old_len: old_len,
|
2017-11-25 18:35:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-15 22:10:01 -05:00
|
|
|
/// Returns a place for insertion at the front of the list.
|
|
|
|
|
///
|
2017-04-04 15:39:44 -04:00
|
|
|
/// Using this method with placement syntax is equivalent to
|
|
|
|
|
/// [`push_front`](#method.push_front), but may be more efficient.
|
2016-02-15 22:10:01 -05:00
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// #![feature(collection_placement)]
|
|
|
|
|
/// #![feature(placement_in_syntax)]
|
|
|
|
|
///
|
|
|
|
|
/// use std::collections::LinkedList;
|
|
|
|
|
///
|
|
|
|
|
/// let mut list = LinkedList::new();
|
|
|
|
|
/// list.front_place() <- 2;
|
|
|
|
|
/// list.front_place() <- 4;
|
|
|
|
|
/// assert!(list.iter().eq(&[4, 2]));
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "method name and placement protocol are subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
pub fn front_place(&mut self) -> FrontPlace<T> {
|
2016-12-20 09:54:00 +05:30
|
|
|
FrontPlace {
|
|
|
|
|
list: self,
|
|
|
|
|
node: IntermediateBox::make_place(),
|
|
|
|
|
}
|
2016-02-15 22:10:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns a place for insertion at the back of the list.
|
|
|
|
|
///
|
|
|
|
|
/// Using this method with placement syntax is equivalent to [`push_back`](#method.push_back),
|
|
|
|
|
/// but may be more efficient.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// #![feature(collection_placement)]
|
|
|
|
|
/// #![feature(placement_in_syntax)]
|
|
|
|
|
///
|
|
|
|
|
/// use std::collections::LinkedList;
|
|
|
|
|
///
|
|
|
|
|
/// let mut list = LinkedList::new();
|
|
|
|
|
/// list.back_place() <- 2;
|
|
|
|
|
/// list.back_place() <- 4;
|
|
|
|
|
/// assert!(list.iter().eq(&[2, 4]));
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "method name and placement protocol are subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
pub fn back_place(&mut self) -> BackPlace<T> {
|
2016-12-20 09:54:00 +05:30
|
|
|
BackPlace {
|
|
|
|
|
list: self,
|
|
|
|
|
node: IntermediateBox::make_place(),
|
|
|
|
|
}
|
2016-02-15 22:10:01 -05:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-12-28 17:47:10 -05:00
|
|
|
unsafe impl<#[may_dangle] T> Drop for LinkedList<T> {
|
2013-09-16 21:18:07 -04:00
|
|
|
fn drop(&mut self) {
|
2016-07-01 22:28:36 -04:00
|
|
|
while let Some(_) = self.pop_front_node() {}
|
2013-08-04 18:38:06 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<'a, T> Iterator for Iter<'a, T> {
|
|
|
|
|
type Item = &'a T;
|
2015-01-01 23:15:35 -05:00
|
|
|
|
2013-07-09 16:55:04 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
|
|
|
|
if self.len == 0 {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
self.head.map(|node| unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
// Need an unbound lifetime to get 'a
|
|
|
|
|
let node = &*node.as_ptr();
|
2016-07-01 22:28:36 -04:00
|
|
|
self.len -= 1;
|
|
|
|
|
self.head = node.next;
|
|
|
|
|
&node.element
|
|
|
|
|
})
|
2013-07-12 03:24:59 +02:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2015-02-04 21:17:19 -05:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2016-07-01 22:28:36 -04:00
|
|
|
(self.len, Some(self.len))
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn next_back(&mut self) -> Option<&'a T> {
|
|
|
|
|
if self.len == 0 {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
self.tail.map(|node| unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
// Need an unbound lifetime to get 'a
|
|
|
|
|
let node = &*node.as_ptr();
|
2016-07-01 22:28:36 -04:00
|
|
|
self.len -= 1;
|
|
|
|
|
self.tail = node.prev;
|
|
|
|
|
&node.element
|
2015-06-06 14:26:39 +02:00
|
|
|
})
|
|
|
|
|
}
|
2013-07-12 03:24:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
|
2013-09-01 18:20:24 +02:00
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
|
impl<'a, T> FusedIterator for Iter<'a, T> {}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<'a, T> Iterator for IterMut<'a, T> {
|
|
|
|
|
type Item = &'a mut T;
|
|
|
|
|
|
2013-07-09 16:55:04 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn next(&mut self) -> Option<&'a mut T> {
|
|
|
|
|
if self.len == 0 {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
self.head.map(|node| unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
// Need an unbound lifetime to get 'a
|
|
|
|
|
let node = &mut *node.as_ptr();
|
2016-07-01 22:28:36 -04:00
|
|
|
self.len -= 1;
|
|
|
|
|
self.head = node.next;
|
|
|
|
|
&mut node.element
|
2015-06-06 14:26:39 +02:00
|
|
|
})
|
|
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2015-02-04 21:17:19 -05:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2016-07-01 22:28:36 -04:00
|
|
|
(self.len, Some(self.len))
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
|
2013-07-09 16:55:04 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn next_back(&mut self) -> Option<&'a mut T> {
|
|
|
|
|
if self.len == 0 {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
self.tail.map(|node| unsafe {
|
2017-04-04 12:31:38 -04:00
|
|
|
// Need an unbound lifetime to get 'a
|
|
|
|
|
let node = &mut *node.as_ptr();
|
2016-07-01 22:28:36 -04:00
|
|
|
self.len -= 1;
|
|
|
|
|
self.tail = node.prev;
|
|
|
|
|
&mut node.element
|
2015-06-06 14:26:39 +02:00
|
|
|
})
|
|
|
|
|
}
|
2013-01-24 15:40:46 -08:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
|
2013-07-21 19:31:40 +02:00
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
|
impl<'a, T> FusedIterator for IterMut<'a, T> {}
|
|
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<'a, T> IterMut<'a, T> {
|
|
|
|
|
/// Inserts the given element just after the element most recently returned by `.next()`.
|
2014-12-23 16:27:27 -06:00
|
|
|
/// The inserted element does not appear in the iteration.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2015-07-27 10:50:19 -04:00
|
|
|
/// #![feature(linked_list_extras)]
|
|
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2014-12-23 16:27:27 -06:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect();
|
2014-12-23 16:27:27 -06:00
|
|
|
///
|
|
|
|
|
/// {
|
|
|
|
|
/// let mut it = list.iter_mut();
|
|
|
|
|
/// assert_eq!(it.next().unwrap(), &1);
|
|
|
|
|
/// // insert `2` after `1`
|
|
|
|
|
/// it.insert_next(2);
|
|
|
|
|
/// }
|
|
|
|
|
/// {
|
2015-02-12 16:45:07 -05:00
|
|
|
/// let vec: Vec<_> = list.into_iter().collect();
|
2015-02-24 21:15:45 +03:00
|
|
|
/// assert_eq!(vec, [1, 2, 3, 4]);
|
2014-12-23 16:27:27 -06:00
|
|
|
/// }
|
|
|
|
|
/// ```
|
2013-07-21 19:31:40 +02:00
|
|
|
#[inline]
|
2015-06-09 14:39:23 -07:00
|
|
|
#[unstable(feature = "linked_list_extras",
|
2015-08-12 22:19:51 -07:00
|
|
|
reason = "this is probably better handled by a cursor type -- we'll see",
|
|
|
|
|
issue = "27794")]
|
2016-07-01 22:28:36 -04:00
|
|
|
pub fn insert_next(&mut self, element: T) {
|
|
|
|
|
match self.head {
|
|
|
|
|
None => self.list.push_back(element),
|
2017-04-04 12:31:38 -04:00
|
|
|
Some(mut head) => unsafe {
|
|
|
|
|
let mut prev = match head.as_ref().prev {
|
2016-07-01 22:28:36 -04:00
|
|
|
None => return self.list.push_front(element),
|
|
|
|
|
Some(prev) => prev,
|
|
|
|
|
};
|
|
|
|
|
|
2017-07-14 12:47:06 +02:00
|
|
|
let node = Some(Shared::from(Box::into_unique(box Node {
|
2016-07-01 22:28:36 -04:00
|
|
|
next: Some(head),
|
|
|
|
|
prev: Some(prev),
|
2017-08-06 22:54:09 -07:00
|
|
|
element,
|
2016-07-01 22:28:36 -04:00
|
|
|
})));
|
|
|
|
|
|
2017-04-04 12:31:38 -04:00
|
|
|
prev.as_mut().next = node;
|
|
|
|
|
head.as_mut().prev = node;
|
2016-07-01 22:28:36 -04:00
|
|
|
|
|
|
|
|
self.list.len += 1;
|
2016-12-20 09:54:00 +05:30
|
|
|
},
|
2016-07-01 22:28:36 -04:00
|
|
|
}
|
2013-07-21 19:31:40 +02:00
|
|
|
}
|
2013-07-10 03:49:32 +02:00
|
|
|
|
2014-12-23 16:27:27 -06:00
|
|
|
/// Provides a reference to the next element, without changing the iterator.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
2015-01-11 17:02:51 -05:00
|
|
|
/// ```
|
2015-07-27 10:50:19 -04:00
|
|
|
/// #![feature(linked_list_extras)]
|
|
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// use std::collections::LinkedList;
|
2014-12-23 16:27:27 -06:00
|
|
|
///
|
2015-02-17 23:44:55 -08:00
|
|
|
/// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect();
|
2014-12-23 16:27:27 -06:00
|
|
|
///
|
|
|
|
|
/// let mut it = list.iter_mut();
|
|
|
|
|
/// assert_eq!(it.next().unwrap(), &1);
|
|
|
|
|
/// assert_eq!(it.peek_next().unwrap(), &2);
|
|
|
|
|
/// // We just peeked at 2, so it was not consumed from the iterator.
|
|
|
|
|
/// assert_eq!(it.next().unwrap(), &2);
|
|
|
|
|
/// ```
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2015-06-09 14:39:23 -07:00
|
|
|
#[unstable(feature = "linked_list_extras",
|
2015-08-12 22:19:51 -07:00
|
|
|
reason = "this is probably better handled by a cursor type -- we'll see",
|
|
|
|
|
issue = "27794")]
|
2016-07-01 22:28:36 -04:00
|
|
|
pub fn peek_next(&mut self) -> Option<&mut T> {
|
|
|
|
|
if self.len == 0 {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
2017-04-04 12:31:38 -04:00
|
|
|
unsafe {
|
|
|
|
|
self.head.as_mut().map(|node| &mut node.as_mut().element)
|
|
|
|
|
}
|
2015-06-06 14:26:39 +02:00
|
|
|
}
|
2013-07-10 03:49:32 +02:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
2013-01-24 15:40:46 -08:00
|
|
|
|
2017-11-25 21:14:37 +01:00
|
|
|
/// An iterator produced by calling `drain_filter` on LinkedList.
|
|
|
|
|
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
|
|
|
|
|
pub struct DrainFilter<'a, T: 'a, F: 'a>
|
|
|
|
|
where F: FnMut(&mut T) -> bool,
|
|
|
|
|
{
|
|
|
|
|
list: &'a mut LinkedList<T>,
|
|
|
|
|
it: Option<Shared<Node<T>>>,
|
|
|
|
|
pred: F,
|
|
|
|
|
idx: usize,
|
|
|
|
|
old_len: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
|
|
|
|
|
impl<'a, T, F> Iterator for DrainFilter<'a, T, F>
|
|
|
|
|
where F: FnMut(&mut T) -> bool,
|
|
|
|
|
{
|
|
|
|
|
type Item = T;
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<T> {
|
|
|
|
|
while let Some(mut node) = self.it {
|
|
|
|
|
unsafe {
|
|
|
|
|
self.it = node.as_ref().next;
|
|
|
|
|
self.idx += 1;
|
|
|
|
|
|
|
|
|
|
if (self.pred)(&mut node.as_mut().element) {
|
|
|
|
|
self.list.unlink_node(node);
|
|
|
|
|
return Some(Box::from_raw(node.as_ptr()).element);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
|
(0, Some(self.old_len - self.idx))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
|
|
|
|
|
impl<'a, T: 'a + fmt::Debug, F> fmt::Debug for DrainFilter<'a, T, F>
|
|
|
|
|
where F: FnMut(&mut T) -> bool
|
|
|
|
|
{
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
f.debug_tuple("DrainFilter")
|
|
|
|
|
.field(&self.list)
|
|
|
|
|
.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T> Iterator for IntoIter<T> {
|
|
|
|
|
type Item = T;
|
2015-01-01 23:15:35 -05:00
|
|
|
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn next(&mut self) -> Option<T> {
|
2015-11-24 11:23:48 +13:00
|
|
|
self.list.pop_front()
|
|
|
|
|
}
|
2013-07-14 23:03:54 +02:00
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-04 21:17:19 -05:00
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
2016-07-01 22:28:36 -04:00
|
|
|
(self.list.len, Some(self.list.len))
|
2012-07-17 19:03:54 -04:00
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
2013-01-24 15:40:46 -08:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T> DoubleEndedIterator for IntoIter<T> {
|
2013-07-14 23:03:54 +02:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn next_back(&mut self) -> Option<T> {
|
2015-11-24 11:23:48 +13:00
|
|
|
self.list.pop_back()
|
|
|
|
|
}
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
2013-01-24 15:40:46 -08:00
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T> ExactSizeIterator for IntoIter<T> {}
|
2015-03-23 08:51:13 -04:00
|
|
|
|
2016-08-13 14:42:36 -04:00
|
|
|
#[unstable(feature = "fused", issue = "35602")]
|
|
|
|
|
impl<T> FusedIterator for IntoIter<T> {}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T> FromIterator<T> for LinkedList<T> {
|
|
|
|
|
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
|
|
|
|
let mut list = Self::new();
|
|
|
|
|
list.extend(iter);
|
|
|
|
|
list
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 10:06:24 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-17 23:44:55 -08:00
|
|
|
impl<T> IntoIterator for LinkedList<T> {
|
2015-02-13 17:55:10 -05:00
|
|
|
type Item = T;
|
|
|
|
|
type IntoIter = IntoIter<T>;
|
|
|
|
|
|
2015-04-17 14:31:30 -07:00
|
|
|
/// Consumes the list into an iterator yielding elements by value.
|
|
|
|
|
#[inline]
|
2015-02-13 17:55:10 -05:00
|
|
|
fn into_iter(self) -> IntoIter<T> {
|
2015-11-24 11:23:48 +13:00
|
|
|
IntoIter { list: self }
|
2015-02-13 17:55:10 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 10:06:24 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-17 23:44:55 -08:00
|
|
|
impl<'a, T> IntoIterator for &'a LinkedList<T> {
|
2015-02-13 17:55:10 -05:00
|
|
|
type Item = &'a T;
|
2015-02-06 14:47:55 -08:00
|
|
|
type IntoIter = Iter<'a, T>;
|
2015-01-07 22:01:05 -05:00
|
|
|
|
|
|
|
|
fn into_iter(self) -> Iter<'a, T> {
|
|
|
|
|
self.iter()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-17 23:44:55 -08:00
|
|
|
impl<'a, T> IntoIterator for &'a mut LinkedList<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
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
fn into_iter(self) -> IterMut<'a, T> {
|
2015-01-07 22:01:05 -05:00
|
|
|
self.iter_mut()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T> Extend<T> for LinkedList<T> {
|
|
|
|
|
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
|
|
|
|
|
<Self as SpecExtend<I>>::spec_extend(self, iter);
|
2016-04-08 23:36:54 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<I: IntoIterator> SpecExtend<I> for LinkedList<I::Item> {
|
|
|
|
|
default fn spec_extend(&mut self, iter: I) {
|
2015-11-24 11:23:48 +13:00
|
|
|
for elt in iter {
|
|
|
|
|
self.push_back(elt);
|
|
|
|
|
}
|
2013-07-30 02:06:49 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-08 23:36:54 -04:00
|
|
|
impl<T> SpecExtend<LinkedList<T>> for LinkedList<T> {
|
|
|
|
|
fn spec_extend(&mut self, ref mut other: LinkedList<T>) {
|
|
|
|
|
self.append(other);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 12:38:42 +02:00
|
|
|
#[stable(feature = "extend_ref", since = "1.2.0")]
|
|
|
|
|
impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> {
|
2015-11-24 11:23:48 +13:00
|
|
|
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
|
2015-06-03 12:38:42 +02:00
|
|
|
self.extend(iter.into_iter().cloned());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T: PartialEq> PartialEq for LinkedList<T> {
|
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
|
self.len() == other.len() && self.iter().eq(other)
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
2013-07-14 23:03:54 +02:00
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
fn ne(&self, other: &Self) -> bool {
|
|
|
|
|
self.len() != other.len() || self.iter().ne(other)
|
2013-08-08 22:07:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T: Eq> Eq for LinkedList<T> {}
|
2014-08-01 16:05:03 -04:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T: PartialOrd> PartialOrd for LinkedList<T> {
|
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
|
|
|
self.iter().partial_cmp(other)
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T: Ord> Ord for LinkedList<T> {
|
2014-08-01 16:22:48 -04:00
|
|
|
#[inline]
|
2016-07-01 22:28:36 -04:00
|
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
|
|
|
self.iter().cmp(other)
|
2014-08-01 16:22:48 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T: Clone> Clone for LinkedList<T> {
|
|
|
|
|
fn clone(&self) -> Self {
|
2015-02-13 07:33:44 +00:00
|
|
|
self.iter().cloned().collect()
|
2013-07-09 16:55:04 +02:00
|
|
|
}
|
2014-02-05 08:52:54 -08:00
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T: fmt::Debug> fmt::Debug for LinkedList<T> {
|
2014-06-07 15:01:44 +02:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-07-01 22:28:36 -04:00
|
|
|
f.debug_list().entries(self).finish()
|
2014-06-07 15:01:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-07-01 22:28:36 -04:00
|
|
|
impl<T: Hash> Hash for LinkedList<T> {
|
2015-02-17 20:48:07 -08:00
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
|
self.len().hash(state);
|
|
|
|
|
for elt in self {
|
|
|
|
|
elt.hash(state);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-11 19:44:02 -05:00
|
|
|
|
2016-02-15 22:10:01 -05:00
|
|
|
unsafe fn finalize<T>(node: IntermediateBox<Node<T>>) -> Box<Node<T>> {
|
|
|
|
|
let mut node = node.finalize();
|
|
|
|
|
ptr::write(&mut node.next, None);
|
2016-07-01 22:28:36 -04:00
|
|
|
ptr::write(&mut node.prev, None);
|
2016-02-15 22:10:01 -05:00
|
|
|
node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A place for insertion at the front of a `LinkedList`.
|
|
|
|
|
///
|
|
|
|
|
/// See [`LinkedList::front_place`](struct.LinkedList.html#method.front_place) for details.
|
|
|
|
|
#[must_use = "places do nothing unless written to with `<-` syntax"]
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "struct name and placement protocol are subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
pub struct FrontPlace<'a, T: 'a> {
|
|
|
|
|
list: &'a mut LinkedList<T>,
|
|
|
|
|
node: IntermediateBox<Node<T>>,
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-21 00:33:38 +01:00
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "struct name and placement protocol are subject to change",
|
|
|
|
|
issue = "30172")]
|
2017-01-11 23:12:49 +01:00
|
|
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for FrontPlace<'a, T> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-01-21 00:33:38 +01:00
|
|
|
f.debug_tuple("FrontPlace")
|
2017-04-17 18:06:43 +02:00
|
|
|
.field(&self.list)
|
2017-01-11 23:12:49 +01:00
|
|
|
.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-15 22:10:01 -05:00
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "placement protocol is subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
impl<'a, T> Placer<T> for FrontPlace<'a, T> {
|
|
|
|
|
type Place = Self;
|
|
|
|
|
|
|
|
|
|
fn make_place(self) -> Self {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "placement protocol is subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
impl<'a, T> Place<T> for FrontPlace<'a, T> {
|
|
|
|
|
fn pointer(&mut self) -> *mut T {
|
2016-07-01 22:28:36 -04:00
|
|
|
unsafe { &mut (*self.node.pointer()).element }
|
2016-02-15 22:10:01 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "placement protocol is subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
impl<'a, T> InPlace<T> for FrontPlace<'a, T> {
|
|
|
|
|
type Owner = ();
|
|
|
|
|
|
|
|
|
|
unsafe fn finalize(self) {
|
|
|
|
|
let FrontPlace { list, node } = self;
|
|
|
|
|
list.push_front_node(finalize(node));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A place for insertion at the back of a `LinkedList`.
|
|
|
|
|
///
|
|
|
|
|
/// See [`LinkedList::back_place`](struct.LinkedList.html#method.back_place) for details.
|
|
|
|
|
#[must_use = "places do nothing unless written to with `<-` syntax"]
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "struct name and placement protocol are subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
pub struct BackPlace<'a, T: 'a> {
|
|
|
|
|
list: &'a mut LinkedList<T>,
|
|
|
|
|
node: IntermediateBox<Node<T>>,
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-21 00:33:38 +01:00
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "struct name and placement protocol are subject to change",
|
|
|
|
|
issue = "30172")]
|
2017-01-11 23:12:49 +01:00
|
|
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for BackPlace<'a, T> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-01-21 00:33:38 +01:00
|
|
|
f.debug_tuple("BackPlace")
|
2017-04-17 18:06:43 +02:00
|
|
|
.field(&self.list)
|
2017-01-11 23:12:49 +01:00
|
|
|
.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-15 22:10:01 -05:00
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "placement protocol is subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
impl<'a, T> Placer<T> for BackPlace<'a, T> {
|
|
|
|
|
type Place = Self;
|
|
|
|
|
|
|
|
|
|
fn make_place(self) -> Self {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "placement protocol is subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
impl<'a, T> Place<T> for BackPlace<'a, T> {
|
|
|
|
|
fn pointer(&mut self) -> *mut T {
|
2016-07-01 22:28:36 -04:00
|
|
|
unsafe { &mut (*self.node.pointer()).element }
|
2016-02-15 22:10:01 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "collection_placement",
|
|
|
|
|
reason = "placement protocol is subject to change",
|
|
|
|
|
issue = "30172")]
|
|
|
|
|
impl<'a, T> InPlace<T> for BackPlace<'a, T> {
|
|
|
|
|
type Owner = ();
|
|
|
|
|
|
|
|
|
|
unsafe fn finalize(self) {
|
|
|
|
|
let BackPlace { list, node } = self;
|
|
|
|
|
list.push_back_node(finalize(node));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-31 15:17:50 -05:00
|
|
|
// Ensure that `LinkedList` and its read-only iterators are covariant in their type parameters.
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
fn assert_covariance() {
|
2016-12-20 09:54:00 +05:30
|
|
|
fn a<'a>(x: LinkedList<&'static str>) -> LinkedList<&'a str> {
|
|
|
|
|
x
|
|
|
|
|
}
|
|
|
|
|
fn b<'i, 'a>(x: Iter<'i, &'static str>) -> Iter<'i, &'a str> {
|
|
|
|
|
x
|
|
|
|
|
}
|
|
|
|
|
fn c<'a>(x: IntoIter<&'static str>) -> IntoIter<&'a str> {
|
|
|
|
|
x
|
|
|
|
|
}
|
2015-12-31 15:17:50 -05:00
|
|
|
}
|
|
|
|
|
|
2016-07-01 22:28:36 -04:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe impl<T: Send> Send for LinkedList<T> {}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe impl<T: Sync> Sync for LinkedList<T> {}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
|
|
|
|
|
|
2015-03-11 19:44:02 -05:00
|
|
|
#[cfg(test)]
|
2015-04-24 17:30:41 +02:00
|
|
|
mod tests {
|
2015-03-11 19:44:02 -05:00
|
|
|
use std::thread;
|
|
|
|
|
use std::vec::Vec;
|
|
|
|
|
|
2017-11-01 12:32:13 -07:00
|
|
|
use rand::{thread_rng, Rng};
|
|
|
|
|
|
2015-03-11 19:44:02 -05:00
|
|
|
use super::{LinkedList, Node};
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
|
|
|
|
|
v.iter().cloned().collect()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn check_links<T>(list: &LinkedList<T>) {
|
2016-07-01 22:28:36 -04:00
|
|
|
unsafe {
|
|
|
|
|
let mut len = 0;
|
|
|
|
|
let mut last_ptr: Option<&Node<T>> = None;
|
|
|
|
|
let mut node_ptr: &Node<T>;
|
|
|
|
|
match list.head {
|
|
|
|
|
None => {
|
2017-11-26 00:30:33 +01:00
|
|
|
// tail node should also be None.
|
|
|
|
|
assert!(list.tail.is_none());
|
2016-07-01 22:28:36 -04:00
|
|
|
assert_eq!(0, list.len);
|
|
|
|
|
return;
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|
2017-04-04 12:31:38 -04:00
|
|
|
Some(node) => node_ptr = &*node.as_ptr(),
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|
2016-07-01 22:28:36 -04:00
|
|
|
loop {
|
|
|
|
|
match (last_ptr, node_ptr.prev) {
|
|
|
|
|
(None, None) => {}
|
|
|
|
|
(None, _) => panic!("prev link for head"),
|
|
|
|
|
(Some(p), Some(pptr)) => {
|
2017-04-04 12:31:38 -04:00
|
|
|
assert_eq!(p as *const Node<T>, pptr.as_ptr() as *const Node<T>);
|
2016-07-01 22:28:36 -04:00
|
|
|
}
|
|
|
|
|
_ => panic!("prev link is none, not good"),
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|
2016-07-01 22:28:36 -04:00
|
|
|
match node_ptr.next {
|
|
|
|
|
Some(next) => {
|
|
|
|
|
last_ptr = Some(node_ptr);
|
2017-04-04 12:31:38 -04:00
|
|
|
node_ptr = &*next.as_ptr();
|
2016-07-01 22:28:36 -04:00
|
|
|
len += 1;
|
|
|
|
|
}
|
|
|
|
|
None => {
|
|
|
|
|
len += 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|
|
|
|
|
}
|
2017-11-26 00:30:33 +01:00
|
|
|
|
|
|
|
|
// verify that the tail node points to the last node.
|
|
|
|
|
let tail = list.tail.as_ref().expect("some tail node").as_ref();
|
|
|
|
|
assert_eq!(tail as *const Node<T>, node_ptr as *const Node<T>);
|
|
|
|
|
// check that len matches interior links.
|
2016-07-01 22:28:36 -04:00
|
|
|
assert_eq!(len, list.len);
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_append() {
|
|
|
|
|
// Empty to empty
|
|
|
|
|
{
|
|
|
|
|
let mut m = LinkedList::<i32>::new();
|
|
|
|
|
let mut n = LinkedList::new();
|
|
|
|
|
m.append(&mut n);
|
|
|
|
|
check_links(&m);
|
|
|
|
|
assert_eq!(m.len(), 0);
|
|
|
|
|
assert_eq!(n.len(), 0);
|
|
|
|
|
}
|
|
|
|
|
// Non-empty to empty
|
|
|
|
|
{
|
|
|
|
|
let mut m = LinkedList::new();
|
|
|
|
|
let mut n = LinkedList::new();
|
|
|
|
|
n.push_back(2);
|
|
|
|
|
m.append(&mut n);
|
|
|
|
|
check_links(&m);
|
|
|
|
|
assert_eq!(m.len(), 1);
|
|
|
|
|
assert_eq!(m.pop_back(), Some(2));
|
|
|
|
|
assert_eq!(n.len(), 0);
|
|
|
|
|
check_links(&m);
|
|
|
|
|
}
|
|
|
|
|
// Empty to non-empty
|
|
|
|
|
{
|
|
|
|
|
let mut m = LinkedList::new();
|
|
|
|
|
let mut n = LinkedList::new();
|
|
|
|
|
m.push_back(2);
|
|
|
|
|
m.append(&mut n);
|
|
|
|
|
check_links(&m);
|
|
|
|
|
assert_eq!(m.len(), 1);
|
|
|
|
|
assert_eq!(m.pop_back(), Some(2));
|
|
|
|
|
check_links(&m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Non-empty to non-empty
|
2015-11-24 11:23:48 +13:00
|
|
|
let v = vec![1, 2, 3, 4, 5];
|
|
|
|
|
let u = vec![9, 8, 1, 2, 3, 4, 5];
|
2015-03-11 19:44:02 -05:00
|
|
|
let mut m = list_from(&v);
|
|
|
|
|
let mut n = list_from(&u);
|
|
|
|
|
m.append(&mut n);
|
|
|
|
|
check_links(&m);
|
|
|
|
|
let mut sum = v;
|
2016-03-07 15:42:29 -08:00
|
|
|
sum.extend_from_slice(&u);
|
2015-03-11 19:44:02 -05:00
|
|
|
assert_eq!(sum.len(), m.len());
|
|
|
|
|
for elt in sum {
|
|
|
|
|
assert_eq!(m.pop_front(), Some(elt))
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(n.len(), 0);
|
|
|
|
|
// let's make sure it's working properly, since we
|
|
|
|
|
// did some direct changes to private members
|
|
|
|
|
n.push_back(3);
|
|
|
|
|
assert_eq!(n.len(), 1);
|
|
|
|
|
assert_eq!(n.pop_front(), Some(3));
|
|
|
|
|
check_links(&n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_insert_prev() {
|
2015-11-24 11:23:48 +13:00
|
|
|
let mut m = list_from(&[0, 2, 4, 6, 8]);
|
2015-03-11 19:44:02 -05:00
|
|
|
let len = m.len();
|
|
|
|
|
{
|
|
|
|
|
let mut it = m.iter_mut();
|
|
|
|
|
it.insert_next(-2);
|
|
|
|
|
loop {
|
|
|
|
|
match it.next() {
|
|
|
|
|
None => break,
|
|
|
|
|
Some(elt) => {
|
|
|
|
|
it.insert_next(*elt + 1);
|
|
|
|
|
match it.peek_next() {
|
|
|
|
|
Some(x) => assert_eq!(*x, *elt + 2),
|
|
|
|
|
None => assert_eq!(8, *elt),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
it.insert_next(0);
|
|
|
|
|
it.insert_next(1);
|
|
|
|
|
}
|
|
|
|
|
check_links(&m);
|
|
|
|
|
assert_eq!(m.len(), 3 + len * 2);
|
2015-11-24 11:23:48 +13:00
|
|
|
assert_eq!(m.into_iter().collect::<Vec<_>>(),
|
|
|
|
|
[-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]);
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2016-09-07 05:34:15 +00:00
|
|
|
#[cfg_attr(target_os = "emscripten", ignore)]
|
2015-03-11 19:44:02 -05:00
|
|
|
fn test_send() {
|
2015-11-24 11:23:48 +13:00
|
|
|
let n = list_from(&[1, 2, 3]);
|
2015-03-11 19:44:02 -05:00
|
|
|
thread::spawn(move || {
|
2016-12-20 09:54:00 +05:30
|
|
|
check_links(&n);
|
|
|
|
|
let a: &[_] = &[&1, &2, &3];
|
2017-03-24 09:31:26 +01:00
|
|
|
assert_eq!(a, &*n.iter().collect::<Vec<_>>());
|
2016-12-20 09:54:00 +05:30
|
|
|
})
|
2015-11-24 11:23:48 +13:00
|
|
|
.join()
|
|
|
|
|
.ok()
|
|
|
|
|
.unwrap();
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_fuzz() {
|
|
|
|
|
for _ in 0..25 {
|
|
|
|
|
fuzz_test(3);
|
|
|
|
|
fuzz_test(16);
|
|
|
|
|
fuzz_test(189);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-04 17:18:27 -07:00
|
|
|
#[test]
|
|
|
|
|
fn test_26021() {
|
|
|
|
|
// There was a bug in split_off that failed to null out the RHS's head's prev ptr.
|
|
|
|
|
// This caused the RHS's dtor to walk up into the LHS at drop and delete all of
|
|
|
|
|
// its nodes.
|
|
|
|
|
//
|
|
|
|
|
// https://github.com/rust-lang/rust/issues/26021
|
|
|
|
|
let mut v1 = LinkedList::new();
|
2016-03-10 22:03:12 +05:30
|
|
|
v1.push_front(1);
|
|
|
|
|
v1.push_front(1);
|
|
|
|
|
v1.push_front(1);
|
|
|
|
|
v1.push_front(1);
|
2015-06-04 17:18:27 -07:00
|
|
|
let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption
|
|
|
|
|
assert_eq!(v1.len(), 3);
|
|
|
|
|
|
|
|
|
|
assert_eq!(v1.iter().len(), 3);
|
|
|
|
|
assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-06 14:26:39 +02:00
|
|
|
#[test]
|
|
|
|
|
fn test_split_off() {
|
|
|
|
|
let mut v1 = LinkedList::new();
|
2016-03-10 22:03:12 +05:30
|
|
|
v1.push_front(1);
|
|
|
|
|
v1.push_front(1);
|
|
|
|
|
v1.push_front(1);
|
|
|
|
|
v1.push_front(1);
|
2015-06-06 14:26:39 +02:00
|
|
|
|
|
|
|
|
// test all splits
|
|
|
|
|
for ix in 0..1 + v1.len() {
|
|
|
|
|
let mut a = v1.clone();
|
|
|
|
|
let b = a.split_off(ix);
|
|
|
|
|
check_links(&a);
|
|
|
|
|
check_links(&b);
|
|
|
|
|
a.extend(b);
|
|
|
|
|
assert_eq!(v1, a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-11 19:44:02 -05:00
|
|
|
#[cfg(test)]
|
|
|
|
|
fn fuzz_test(sz: i32) {
|
|
|
|
|
let mut m: LinkedList<_> = LinkedList::new();
|
|
|
|
|
let mut v = vec![];
|
|
|
|
|
for i in 0..sz {
|
|
|
|
|
check_links(&m);
|
2015-04-10 11:39:53 -07:00
|
|
|
let r: u8 = thread_rng().next_u32() as u8;
|
2015-03-11 19:44:02 -05:00
|
|
|
match r % 6 {
|
|
|
|
|
0 => {
|
|
|
|
|
m.pop_back();
|
|
|
|
|
v.pop();
|
|
|
|
|
}
|
|
|
|
|
1 => {
|
|
|
|
|
if !v.is_empty() {
|
|
|
|
|
m.pop_front();
|
|
|
|
|
v.remove(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-11-24 11:23:48 +13:00
|
|
|
2 | 4 => {
|
2015-03-11 19:44:02 -05:00
|
|
|
m.push_front(-i);
|
|
|
|
|
v.insert(0, -i);
|
|
|
|
|
}
|
|
|
|
|
3 | 5 | _ => {
|
|
|
|
|
m.push_back(i);
|
|
|
|
|
v.push(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
check_links(&m);
|
|
|
|
|
|
|
|
|
|
let mut i = 0;
|
2015-06-10 17:22:20 +01:00
|
|
|
for (a, &b) in m.into_iter().zip(&v) {
|
2015-03-11 19:44:02 -05:00
|
|
|
i += 1;
|
|
|
|
|
assert_eq!(a, b);
|
|
|
|
|
}
|
|
|
|
|
assert_eq!(i, v.len());
|
|
|
|
|
}
|
2017-11-25 18:35:30 +01:00
|
|
|
|
|
|
|
|
#[test]
|
2017-11-25 21:14:37 +01:00
|
|
|
fn drain_filter_test() {
|
2017-11-25 18:35:30 +01:00
|
|
|
let mut m: LinkedList<u32> = LinkedList::new();
|
|
|
|
|
m.extend(&[1, 2, 3, 4, 5, 6]);
|
2017-11-25 21:14:37 +01:00
|
|
|
let deleted = m.drain_filter(|v| *v < 4).collect::<Vec<_>>();
|
2017-11-25 18:35:30 +01:00
|
|
|
|
|
|
|
|
check_links(&m);
|
|
|
|
|
|
2017-11-25 21:14:37 +01:00
|
|
|
assert_eq!(deleted, &[1, 2, 3]);
|
2017-11-25 18:35:30 +01:00
|
|
|
assert_eq!(m.into_iter().collect::<Vec<_>>(), &[4, 5, 6]);
|
|
|
|
|
}
|
2017-11-25 21:14:37 +01:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn drain_to_empty_test() {
|
|
|
|
|
let mut m: LinkedList<u32> = LinkedList::new();
|
|
|
|
|
m.extend(&[1, 2, 3, 4, 5, 6]);
|
|
|
|
|
let deleted = m.drain_filter(|_| true).collect::<Vec<_>>();
|
|
|
|
|
|
|
|
|
|
check_links(&m);
|
|
|
|
|
|
|
|
|
|
assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]);
|
|
|
|
|
assert_eq!(m.into_iter().collect::<Vec<_>>(), &[]);
|
|
|
|
|
}
|
2015-03-11 19:44:02 -05:00
|
|
|
}
|