Bug 1716518 - Upgrade slab to v0.4.3.

Differential Revision: https://phabricator.services.mozilla.com/D117861

Depends on D117860
This commit is contained in:
Mike Hommey 2021-06-15 09:25:23 +00:00
Родитель 44e5a3d825
Коммит 4c2c284417
10 изменённых файлов: 1218 добавлений и 95 удалений

4
Cargo.lock сгенерированный
Просмотреть файл

@ -4675,9 +4675,9 @@ version = "0.0.1"
[[package]]
name = "slab"
version = "0.4.1"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
[[package]]
name = "smallbitvec"

2
third_party/rust/slab/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{"CHANGELOG.md":"a3e1912aae6f72659729ba4b2e303aa46bfbe1110fe9133386ac3ac3b1c5a1ea","Cargo.toml":"f07494b6213d2ad4b56d1ea9d6579305175de381c1016fa169fc9e84e5ffab9d","LICENSE":"45f522cacecb1023856e46df79ca625dfc550c94910078bd8aec6e02880b3d42","README.md":"ba0e174bd812dba6f93c38595c44187083dfafa408b308492b652182513218f6","src/lib.rs":"4736c1ce76fe28644d70dcc097404d19423578d0c85ae0b47d71c3a79e9c0649","tests/slab.rs":"c166c080b2534ffd5a5de4317f40072603678b2ca996a694c583eafadeb99a8c"},"package":"5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"}
{"files":{"CHANGELOG.md":"4d27de4c0d2c80d7a82af217a2759d14ac08a554c928a334924ca840455d0cd9","Cargo.toml":"0afd491c025731bfbc992ff89fb4e520c8efb84829a5713684c0934cbd948db9","LICENSE":"8ce0830173fdac609dfb4ea603fdc002c2f4af0dc9b1a005653f5da9cf534b18","README.md":"3a9d020510c4ba182d34d459ae2eea9354435964f7014d12ca99cd6334f79cba","src/lib.rs":"ea971740ac2b424da695b4eac6aee81ce6471f40e3186e8f5993bcd31a7f64d2","src/serde.rs":"ecdee6b2e7794746415391efe4687534b1e12b2f27eb02b873efdc030cc669b6","tests/serde.rs":"4e7e737e2a1845a01410b1ad288067de14accd941d72db172b31564623aa587f","tests/slab.rs":"daf451850527c1faf98b7745eab3eb39f18733f36815b01fd82b998127323124"},"package":"f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"}

17
third_party/rust/slab/CHANGELOG.md поставляемый
Просмотреть файл

@ -1,3 +1,20 @@
# 0.4.3 (February 6, 2021)
* Add no_std support for Rust 1.36 and above (#71).
* Add `get2_mut` and `get2_unchecked_mut` methods (#65).
* Make `shrink_to_fit()` remove trailing vacant entries (#62).
* Implement `FromIterator<(usize, T)>` (#62).
* Implement `IntoIterator<Item = (usize, T)>` (#62).
* Provide `size_hint()` of the iterators (#62).
* Make all iterators reversible (#62).
* Add `key_of()` method (#61)
* Add `compact()` method (#60)
* Add support for serde (#85)
# 0.4.2 (January 11, 2019)
* Add `Slab::drain` (#56).
# 0.4.1 (July 15, 2018)
* Improve `reserve` and `reserve_exact` (#37).

29
third_party/rust/slab/Cargo.toml поставляемый
Просмотреть файл

@ -3,7 +3,7 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
@ -12,13 +12,28 @@
[package]
name = "slab"
version = "0.4.1"
version = "0.4.3"
authors = ["Carl Lerche <me@carllerche.com>"]
description = "Pre-allocated storage for a uniform data type"
homepage = "https://github.com/carllerche/slab"
documentation = "https://docs.rs/slab"
homepage = "https://github.com/tokio-rs/slab"
documentation = "https://docs.rs/slab/0.4.3/slab/"
readme = "README.md"
keywords = ["slab", "allocator"]
categories = ["memory-management", "data-structures"]
keywords = ["slab", "allocator", "no_std"]
categories = ["memory-management", "data-structures", "no-std"]
license = "MIT"
repository = "https://github.com/carllerche/slab"
repository = "https://github.com/tokio-rs/slab"
[dependencies.serde]
version = "1.0.95"
features = ["alloc"]
optional = true
default-features = false
[dev-dependencies.serde]
version = "1"
features = ["derive"]
[dev-dependencies.serde_test]
version = "1"
[features]
default = ["std"]
std = []

2
third_party/rust/slab/LICENSE поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
Copyright (c) 2018 Carl Lerche
Copyright (c) 2019 Carl Lerche
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated

13
third_party/rust/slab/README.md поставляемый
Просмотреть файл

@ -2,10 +2,15 @@
Pre-allocated storage for a uniform data type.
[![Crates.io](https://img.shields.io/crates/v/slab.svg?maxAge=2592000)](https://crates.io/crates/slab)
[![Build Status](https://travis-ci.org/carllerche/slab.svg?branch=master)](https://travis-ci.org/carllerche/slab)
[![Crates.io][crates-badge]][crates-url]
[![Build Status][ci-badge]][ci-url]
[Documentation](https://docs.rs/slab)
[crates-badge]: https://img.shields.io/crates/v/slab
[crates-url]: https://crates.io/crates/slab
[ci-badge]: https://img.shields.io/github/workflow/status/tokio-rs/slab/CI/master
[ci-url]: https://github.com/tokio-rs/slab/actions
[Documentation](https://docs.rs/slab/0.4.3/slab/)
## Usage
@ -13,7 +18,7 @@ To use `slab`, first add this to your `Cargo.toml`:
```toml
[dependencies]
slab = "0.4"
slab = "0.4.3"
```
Next, add this to your crate:

684
third_party/rust/slab/src/lib.rs поставляемый
Просмотреть файл

@ -1,3 +1,7 @@
#![warn(missing_docs, missing_debug_implementations)]
#![cfg_attr(test, warn(unreachable_pub))]
#![cfg_attr(not(feature = "std"), no_std)]
//! Pre-allocated storage for a uniform data type.
//!
//! `Slab` provides pre-allocated storage for a single data type. If many values
@ -98,13 +102,26 @@
//!
//! [`Slab::with_capacity`]: struct.Slab.html#with_capacity
#![deny(warnings, missing_docs, missing_debug_implementations)]
#![doc(html_root_url = "https://docs.rs/slab/0.4.1")]
#![crate_name = "slab"]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(feature = "std")]
extern crate core;
use std::{fmt, mem};
use std::iter::IntoIterator;
use std::ops;
#[cfg(feature = "serde")]
mod serde;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use alloc::vec;
use core::iter::FromIterator;
use core::{fmt, mem, ops, slice};
#[cfg(feature = "std")]
use std::vec;
/// Pre-allocated storage for a uniform data type
///
@ -158,18 +175,27 @@ pub struct VacantEntry<'a, T: 'a> {
key: usize,
}
/// A consuming iterator over the values stored in a `Slab`
pub struct IntoIter<T> {
entries: vec::IntoIter<Entry<T>>,
curr: usize,
}
/// An iterator over the values stored in the `Slab`
pub struct Iter<'a, T: 'a> {
entries: std::slice::Iter<'a, Entry<T>>,
entries: slice::Iter<'a, Entry<T>>,
curr: usize,
}
/// A mutable iterator over the values stored in the `Slab`
pub struct IterMut<'a, T: 'a> {
entries: std::slice::IterMut<'a, Entry<T>>,
entries: slice::IterMut<'a, Entry<T>>,
curr: usize,
}
/// A draining iterator for `Slab`
pub struct Drain<'a, T: 'a>(vec::Drain<'a, Entry<T>>);
#[derive(Clone)]
enum Entry<T> {
Vacant(usize),
@ -270,7 +296,7 @@ impl<T> Slab<T> {
if self.capacity() - self.len >= additional {
return;
}
let need_add = self.len + additional - self.entries.len();
let need_add = additional - (self.entries.len() - self.len);
self.entries.reserve(need_add);
}
@ -304,16 +330,19 @@ impl<T> Slab<T> {
if self.capacity() - self.len >= additional {
return;
}
let need_add = self.len + additional - self.entries.len();
let need_add = additional - (self.entries.len() - self.len);
self.entries.reserve_exact(need_add);
}
/// Shrink the capacity of the slab as much as possible.
/// Shrink the capacity of the slab as much as possible without invalidating keys.
///
/// It will drop down as close as possible to the length but the allocator
/// may still inform the vector that there is space for a few more elements.
/// Also, since values are not moved, the slab cannot shrink past any stored
/// values.
/// Because values cannot be moved to a different index, the slab cannot
/// shrink past any stored values.
/// It will drop down as close as possible to the length but the allocator may
/// still inform the underlying vector that there is space for a few more elements.
///
/// This function can take O(n) time even when the capacity cannot be reduced
/// or the allocation is shrunk in place. Repeated calls run in O(1) though.
///
/// # Examples
///
@ -325,33 +354,171 @@ impl<T> Slab<T> {
/// slab.insert(i);
/// }
///
/// assert_eq!(slab.capacity(), 10);
/// slab.shrink_to_fit();
/// assert!(slab.capacity() >= 3);
/// assert!(slab.capacity() >= 3 && slab.capacity() < 10);
/// ```
///
/// In this case, even though two values are removed, the slab cannot shrink
/// past the last value.
/// The slab cannot shrink past the last present value even if previous
/// values are removed:
///
/// ```
/// # use slab::*;
/// let mut slab = Slab::with_capacity(10);
///
/// for i in 0..3 {
/// for i in 0..4 {
/// slab.insert(i);
/// }
///
/// slab.remove(0);
/// slab.remove(1);
/// slab.remove(3);
///
/// assert_eq!(slab.capacity(), 10);
/// slab.shrink_to_fit();
/// assert!(slab.capacity() >= 3);
/// assert!(slab.capacity() >= 3 && slab.capacity() < 10);
/// ```
pub fn shrink_to_fit(&mut self) {
// Remove all vacant entries after the last occupied one, so that
// the capacity can be reduced to what is actually needed.
// If the slab is empty the vector can simply be cleared, but that
// optimization would not affect time complexity when T: Drop.
let len_before = self.entries.len();
while let Some(&Entry::Vacant(_)) = self.entries.last() {
self.entries.pop();
}
// Removing entries breaks the list of vacant entries,
// so it must be repaired
if self.entries.len() != len_before {
// Some vacant entries were removed, so the list now likely¹
// either contains references to the removed entries, or has an
// invalid end marker. Fix this by recreating the list.
self.recreate_vacant_list();
// ¹: If the removed entries formed the tail of the list, with the
// most recently popped entry being the head of them, (so that its
// index is now the end marker) the list is still valid.
// Checking for that unlikely scenario of this infrequently called
// is not worth the code complexity.
}
self.entries.shrink_to_fit();
}
/// Iterate through all entries to recreate and repair the vacant list.
/// self.len must be correct and is not modified.
fn recreate_vacant_list(&mut self) {
self.next = self.entries.len();
// We can stop once we've found all vacant entries
let mut remaining_vacant = self.entries.len() - self.len;
// Iterate in reverse order so that lower keys are at the start of
// the vacant list. This way future shrinks are more likely to be
// able to remove vacant entries.
for (i, entry) in self.entries.iter_mut().enumerate().rev() {
if remaining_vacant == 0 {
break;
}
if let Entry::Vacant(ref mut next) = *entry {
*next = self.next;
self.next = i;
remaining_vacant -= 1;
}
}
}
/// Reduce the capacity as much as possible, changing the key for elements when necessary.
///
/// To allow updating references to the elements which must be moved to a new key,
/// this function takes a closure which is called before moving each element.
/// The second and third parameters to the closure are the current key and
/// new key respectively.
/// In case changing the key for one element turns out not to be possible,
/// the move can be cancelled by returning `false` from the closure.
/// In that case no further attempts at relocating elements is made.
/// If the closure unwinds, the slab will be left in a consistent state,
/// but the value that the closure panicked on might be removed.
///
/// # Examples
///
/// ```
/// # use slab::*;
///
/// let mut slab = Slab::with_capacity(10);
/// let a = slab.insert('a');
/// slab.insert('b');
/// slab.insert('c');
/// slab.remove(a);
/// slab.compact(|&mut value, from, to| {
/// assert_eq!((value, from, to), ('c', 2, 0));
/// true
/// });
/// assert!(slab.capacity() >= 2 && slab.capacity() < 10);
/// ```
///
/// The value is not moved when the closure returns `Err`:
///
/// ```
/// # use slab::*;
///
/// let mut slab = Slab::with_capacity(100);
/// let a = slab.insert('a');
/// let b = slab.insert('b');
/// slab.remove(a);
/// slab.compact(|&mut value, from, to| false);
/// assert_eq!(slab.iter().next(), Some((b, &'b')));
/// ```
pub fn compact<F>(&mut self, mut rekey: F)
where
F: FnMut(&mut T, usize, usize) -> bool,
{
// If the closure unwinds, we need to restore a valid list of vacant entries
struct CleanupGuard<'a, T: 'a> {
slab: &'a mut Slab<T>,
decrement: bool,
}
impl<'a, T: 'a> Drop for CleanupGuard<'a, T> {
fn drop(&mut self) {
if self.decrement {
// Value was popped and not pushed back on
self.slab.len -= 1;
}
self.slab.recreate_vacant_list();
}
}
let mut guard = CleanupGuard {
slab: self,
decrement: true,
};
let mut occupied_until = 0;
// While there are vacant entries
while guard.slab.entries.len() > guard.slab.len {
// Find a value that needs to be moved,
// by popping entries until we find an occopied one.
// (entries cannot be empty because 0 is not greater than anything)
if let Some(Entry::Occupied(mut value)) = guard.slab.entries.pop() {
// Found one, now find a vacant entry to move it to
while let Some(&Entry::Occupied(_)) = guard.slab.entries.get(occupied_until) {
occupied_until += 1;
}
// Let the caller try to update references to the key
if !rekey(&mut value, guard.slab.entries.len(), occupied_until) {
// Changing the key failed, so push the entry back on at its old index.
guard.slab.entries.push(Entry::Occupied(value));
guard.decrement = false;
guard.slab.entries.shrink_to_fit();
return;
// Guard drop handles cleanup
}
// Put the value in its new spot
guard.slab.entries[occupied_until] = Entry::Occupied(value);
// ... and mark it as occupied (this is optional)
occupied_until += 1;
}
}
guard.slab.next = guard.slab.len;
guard.slab.entries.shrink_to_fit();
// Normal cleanup is not necessary
mem::forget(guard);
}
/// Clear the slab of all values.
///
/// # Examples
@ -516,11 +683,62 @@ impl<T> Slab<T> {
}
}
/// Return two mutable references to the values associated with the two
/// given keys simultaneously.
///
/// If any one of the given keys is not associated with a value, then `None`
/// is returned.
///
/// This function can be used to get two mutable references out of one slab,
/// so that you can manipulate both of them at the same time, eg. swap them.
///
/// # Examples
///
/// ```
/// # use slab::*;
/// use std::mem;
///
/// let mut slab = Slab::new();
/// let key1 = slab.insert(1);
/// let key2 = slab.insert(2);
/// let (value1, value2) = slab.get2_mut(key1, key2).unwrap();
/// mem::swap(value1, value2);
/// assert_eq!(slab[key1], 2);
/// assert_eq!(slab[key2], 1);
/// ```
pub fn get2_mut(&mut self, key1: usize, key2: usize) -> Option<(&mut T, &mut T)> {
assert!(key1 != key2);
let (entry1, entry2);
if key1 > key2 {
let (slice1, slice2) = self.entries.split_at_mut(key1);
entry1 = slice2.get_mut(0);
entry2 = slice1.get_mut(key2);
} else {
let (slice1, slice2) = self.entries.split_at_mut(key2);
entry1 = slice1.get_mut(key1);
entry2 = slice2.get_mut(0);
}
match (entry1, entry2) {
(
Some(&mut Entry::Occupied(ref mut val1)),
Some(&mut Entry::Occupied(ref mut val2)),
) => Some((val1, val2)),
_ => None,
}
}
/// Return a reference to the value associated with the given key without
/// performing bounds checking.
///
/// This function should be used with care.
///
/// # Safety
///
/// The key must be within bounds.
///
/// # Examples
///
/// ```
@ -544,6 +762,10 @@ impl<T> Slab<T> {
///
/// This function should be used with care.
///
/// # Safety
///
/// The key must be within bounds.
///
/// # Examples
///
/// ```
@ -565,6 +787,93 @@ impl<T> Slab<T> {
}
}
/// Return two mutable references to the values associated with the two
/// given keys simultaneously without performing bounds checking and safety
/// condition checking.
///
/// This function should be used with care.
///
/// # Safety
///
/// - Both keys must be within bounds.
/// - The condition `key1 != key2` must hold.
///
/// # Examples
///
/// ```
/// # use slab::*;
/// use std::mem;
///
/// let mut slab = Slab::new();
/// let key1 = slab.insert(1);
/// let key2 = slab.insert(2);
/// let (value1, value2) = unsafe { slab.get2_unchecked_mut(key1, key2) };
/// mem::swap(value1, value2);
/// assert_eq!(slab[key1], 2);
/// assert_eq!(slab[key2], 1);
/// ```
pub unsafe fn get2_unchecked_mut(&mut self, key1: usize, key2: usize) -> (&mut T, &mut T) {
let ptr1 = self.entries.get_unchecked_mut(key1) as *mut Entry<T>;
let ptr2 = self.entries.get_unchecked_mut(key2) as *mut Entry<T>;
match (&mut *ptr1, &mut *ptr2) {
(&mut Entry::Occupied(ref mut val1), &mut Entry::Occupied(ref mut val2)) => {
(val1, val2)
}
_ => unreachable!(),
}
}
/// Get the key for an element in the slab.
///
/// The reference must point to an element owned by the slab.
/// Otherwise this function will panic.
/// This is a constant-time operation because the key can be calculated
/// from the reference with pointer arithmetic.
///
/// # Panics
///
/// This function will panic if the reference does not point to an element
/// of the slab.
///
/// # Examples
///
/// ```
/// # use slab::*;
///
/// let mut slab = Slab::new();
/// let key = slab.insert(String::from("foo"));
/// let value = &slab[key];
/// assert_eq!(slab.key_of(value), key);
/// ```
///
/// Values are not compared, so passing a reference to a different locaton
/// will result in a panic:
///
/// ```should_panic
/// # use slab::*;
///
/// let mut slab = Slab::new();
/// let key = slab.insert(0);
/// let bad = &0;
/// slab.key_of(bad); // this will panic
/// unreachable!();
/// ```
pub fn key_of(&self, present_element: &T) -> usize {
let element_ptr = present_element as *const T as usize;
let base_ptr = self.entries.as_ptr() as usize;
// Use wrapping subtraction in case the reference is bad
let byte_offset = element_ptr.wrapping_sub(base_ptr);
// The division rounds away any offset of T inside Entry
// The size of Entry<T> is never zero even if T is due to Vacant(usize)
let key = byte_offset / mem::size_of::<Entry<T>>();
// Prevent returning unspecified (but out of bounds) values
if key >= self.entries.len() {
panic!("The reference points to a value outside this slab");
}
// The reference cannot point to a vacant entry, because then it would not be valid
key
}
/// Insert a value in the slab, returning key assigned to the value.
///
/// The returned key can later be used to retrieve or remove the value using indexed
@ -628,16 +937,11 @@ impl<T> Slab<T> {
self.entries.push(Entry::Occupied(val));
self.next = key + 1;
} else {
let prev = mem::replace(
&mut self.entries[key],
Entry::Occupied(val));
match prev {
Entry::Vacant(next) => {
self.next = next;
}
self.next = match self.entries.get(key) {
Some(&Entry::Vacant(next)) => next,
_ => unreachable!(),
}
};
self.entries[key] = Entry::Occupied(val);
}
}
@ -662,23 +966,23 @@ impl<T> Slab<T> {
/// assert!(!slab.contains(hello));
/// ```
pub fn remove(&mut self, key: usize) -> T {
// Swap the entry at the provided value
let prev = mem::replace(
&mut self.entries[key],
Entry::Vacant(self.next));
if let Some(entry) = self.entries.get_mut(key) {
// Swap the entry at the provided value
let prev = mem::replace(entry, Entry::Vacant(self.next));
match prev {
Entry::Occupied(val) => {
self.len -= 1;
self.next = key;
val
}
_ => {
// Woops, the entry is actually vacant, restore the state
self.entries[key] = prev;
panic!("invalid key");
match prev {
Entry::Occupied(val) => {
self.len -= 1;
self.next = key;
return val;
}
_ => {
// Woops, the entry is actually vacant, restore the state
*entry = prev;
}
}
}
panic!("invalid key");
}
/// Return `true` if a value is associated with the given key.
@ -697,14 +1001,10 @@ impl<T> Slab<T> {
/// assert!(!slab.contains(hello));
/// ```
pub fn contains(&self, key: usize) -> bool {
self.entries.get(key)
.map(|e| {
match *e {
Entry::Occupied(_) => true,
_ => false,
}
})
.unwrap_or(false)
match self.entries.get(key) {
Some(&Entry::Occupied(_)) => true,
_ => false,
}
}
/// Retain only the elements specified by the predicate.
@ -732,7 +1032,8 @@ impl<T> Slab<T> {
/// assert_eq!(2, slab.len());
/// ```
pub fn retain<F>(&mut self, mut f: F)
where F: FnMut(usize, &mut T) -> bool
where
F: FnMut(usize, &mut T) -> bool,
{
for i in 0..self.entries.len() {
let keep = match self.entries[i] {
@ -745,14 +1046,47 @@ impl<T> Slab<T> {
}
}
}
/// Return a draining iterator that removes all elements from the slab and
/// yields the removed items.
///
/// Note: Elements are removed even if the iterator is only partially
/// consumed or not consumed at all.
///
/// # Examples
///
/// ```
/// # use slab::*;
/// let mut slab = Slab::new();
///
/// let _ = slab.insert(0);
/// let _ = slab.insert(1);
/// let _ = slab.insert(2);
///
/// {
/// let mut drain = slab.drain();
///
/// assert_eq!(Some(0), drain.next());
/// assert_eq!(Some(1), drain.next());
/// assert_eq!(Some(2), drain.next());
/// assert_eq!(None, drain.next());
/// }
///
/// assert!(slab.is_empty());
/// ```
pub fn drain(&mut self) -> Drain<T> {
self.len = 0;
self.next = 0;
Drain(self.entries.drain(..))
}
}
impl<T> ops::Index<usize> for Slab<T> {
type Output = T;
fn index(&self, key: usize) -> &T {
match self.entries[key] {
Entry::Occupied(ref v) => v,
match self.entries.get(key) {
Some(&Entry::Occupied(ref v)) => v,
_ => panic!("invalid key"),
}
}
@ -760,13 +1094,25 @@ impl<T> ops::Index<usize> for Slab<T> {
impl<T> ops::IndexMut<usize> for Slab<T> {
fn index_mut(&mut self, key: usize) -> &mut T {
match self.entries[key] {
Entry::Occupied(ref mut v) => v,
match self.entries.get_mut(key) {
Some(&mut Entry::Occupied(ref mut v)) => v,
_ => panic!("invalid key"),
}
}
}
impl<T> IntoIterator for Slab<T> {
type Item = (usize, T);
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
IntoIter {
entries: self.entries.into_iter(),
curr: 0,
}
}
}
impl<'a, T> IntoIterator for &'a Slab<T> {
type Item = (usize, &'a T);
type IntoIter = Iter<'a, T>;
@ -785,16 +1131,93 @@ impl<'a, T> IntoIterator for &'a mut Slab<T> {
}
}
impl<T> fmt::Debug for Slab<T> where T: fmt::Debug {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt,
"Slab {{ len: {}, cap: {} }}",
self.len,
self.capacity())
/// Create a slab from an iterator of key-value pairs.
///
/// If the iterator produces duplicate keys, the previous value is replaced with the later one.
/// The keys does not need to be sorted beforehand, and this function always
/// takes O(n) time.
/// Note that the returned slab will use space proportional to the largest key,
/// so don't use `Slab` with untrusted keys.
///
/// # Examples
///
/// ```
/// # use slab::*;
///
/// let vec = vec![(2,'a'), (6,'b'), (7,'c')];
/// let slab = vec.into_iter().collect::<Slab<char>>();
/// assert_eq!(slab.len(), 3);
/// assert!(slab.capacity() >= 8);
/// assert_eq!(slab[2], 'a');
/// ```
///
/// With duplicate and unsorted keys:
///
/// ```
/// # use slab::*;
///
/// let vec = vec![(20,'a'), (10,'b'), (11,'c'), (10,'d')];
/// let slab = vec.into_iter().collect::<Slab<char>>();
/// assert_eq!(slab.len(), 3);
/// assert_eq!(slab[10], 'd');
/// ```
impl<T> FromIterator<(usize, T)> for Slab<T> {
fn from_iter<I>(iterable: I) -> Self
where
I: IntoIterator<Item = (usize, T)>,
{
let iterator = iterable.into_iter();
let mut slab = Self::with_capacity(iterator.size_hint().0);
let mut vacant_list_broken = false;
for (key, value) in iterator {
if key < slab.entries.len() {
// iterator is not sorted, might need to recreate vacant list
if let Entry::Vacant(_) = slab.entries[key] {
vacant_list_broken = true;
slab.len += 1;
}
// if an element with this key already exists, replace it.
// This is consisent with HashMap and BtreeMap
slab.entries[key] = Entry::Occupied(value);
} else {
// insert holes as necessary
while slab.entries.len() < key {
// add the entry to the start of the vacant list
let next = slab.next;
slab.next = slab.entries.len();
slab.entries.push(Entry::Vacant(next));
}
slab.entries.push(Entry::Occupied(value));
slab.len += 1;
}
}
if slab.len == slab.entries.len() {
// no vacant enries, so next might not have been updated
slab.next = slab.entries.len();
} else if vacant_list_broken {
slab.recreate_vacant_list();
}
slab
}
}
impl<'a, T: 'a> fmt::Debug for Iter<'a, T> where T: fmt::Debug {
impl<T> fmt::Debug for Slab<T>
where
T: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Slab")
.field("len", &self.len)
.field("cap", &self.capacity())
.finish()
}
}
impl<T> fmt::Debug for IntoIter<T>
where
T: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Iter")
.field("curr", &self.curr)
@ -803,7 +1226,22 @@ impl<'a, T: 'a> fmt::Debug for Iter<'a, T> where T: fmt::Debug {
}
}
impl<'a, T: 'a> fmt::Debug for IterMut<'a, T> where T: fmt::Debug {
impl<'a, T: 'a> fmt::Debug for Iter<'a, T>
where
T: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Iter")
.field("curr", &self.curr)
.field("remaining", &self.entries.len())
.finish()
}
}
impl<'a, T: 'a> fmt::Debug for IterMut<'a, T>
where
T: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("IterMut")
.field("curr", &self.curr)
@ -812,6 +1250,12 @@ impl<'a, T: 'a> fmt::Debug for IterMut<'a, T> where T: fmt::Debug {
}
}
impl<'a, T: 'a> fmt::Debug for Drain<'a, T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Drain").finish()
}
}
// ===== VacantEntry =====
impl<'a, T> VacantEntry<'a, T> {
@ -840,8 +1284,8 @@ impl<'a, T> VacantEntry<'a, T> {
pub fn insert(self, val: T) -> &'a mut T {
self.slab.insert_at(self.key, val);
match self.slab.entries[self.key] {
Entry::Occupied(ref mut v) => v,
match self.slab.entries.get_mut(self.key) {
Some(&mut Entry::Occupied(ref mut v)) => v,
_ => unreachable!(),
}
}
@ -872,6 +1316,42 @@ impl<'a, T> VacantEntry<'a, T> {
}
}
// ===== IntoIter =====
impl<T> Iterator for IntoIter<T> {
type Item = (usize, T);
fn next(&mut self) -> Option<(usize, T)> {
while let Some(entry) = self.entries.next() {
let curr = self.curr;
self.curr += 1;
if let Entry::Occupied(v) = entry {
return Some((curr, v));
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.entries.len()))
}
}
impl<T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<(usize, T)> {
while let Some(entry) = self.entries.next_back() {
if let Entry::Occupied(v) = entry {
let key = self.curr + self.entries.len();
return Some((key, v));
}
}
None
}
}
// ===== Iter =====
impl<'a, T> Iterator for Iter<'a, T> {
@ -889,6 +1369,23 @@ impl<'a, T> Iterator for Iter<'a, T> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.entries.len()))
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
fn next_back(&mut self) -> Option<(usize, &'a T)> {
while let Some(entry) = self.entries.next_back() {
if let Entry::Occupied(ref v) = *entry {
let key = self.curr + self.entries.len();
return Some((key, v));
}
}
None
}
}
// ===== IterMut =====
@ -908,4 +1405,53 @@ impl<'a, T> Iterator for IterMut<'a, T> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.entries.len()))
}
}
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
fn next_back(&mut self) -> Option<(usize, &'a mut T)> {
while let Some(entry) = self.entries.next_back() {
if let Entry::Occupied(ref mut v) = *entry {
let key = self.curr + self.entries.len();
return Some((key, v));
}
}
None
}
}
// ===== Drain =====
impl<'a, T> Iterator for Drain<'a, T> {
type Item = T;
fn next(&mut self) -> Option<T> {
while let Some(entry) = self.0.next() {
if let Entry::Occupied(v) = entry {
return Some(v);
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.0.len()))
}
}
impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
fn next_back(&mut self) -> Option<T> {
while let Some(entry) = self.0.next_back() {
if let Entry::Occupied(v) = entry {
return Some(v);
}
}
None
}
}

91
third_party/rust/slab/src/serde.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,91 @@
extern crate serde;
use core::fmt;
use core::marker::PhantomData;
use self::serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
use self::serde::ser::{Serialize, SerializeMap, Serializer};
use super::{Entry, Slab};
impl<T> Serialize for Slab<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
for (key, value) in self {
map_serializer.serialize_key(&key)?;
map_serializer.serialize_value(value)?;
}
map_serializer.end()
}
}
struct SlabVisitor<T>(PhantomData<T>);
impl<'de, T> Visitor<'de> for SlabVisitor<T>
where
T: Deserialize<'de>,
{
type Value = Slab<T>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "a map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut slab = Slab::with_capacity(map.size_hint().unwrap_or(0));
// same as FromIterator impl
let mut vacant_list_broken = false;
while let Some((key, value)) = map.next_entry()? {
if key < slab.entries.len() {
// iterator is not sorted, might need to recreate vacant list
if let Entry::Vacant(_) = slab.entries[key] {
vacant_list_broken = true;
slab.len += 1;
}
// if an element with this key already exists, replace it.
// This is consisent with HashMap and BtreeMap
slab.entries[key] = Entry::Occupied(value);
} else {
// insert holes as necessary
while slab.entries.len() < key {
// add the entry to the start of the vacant list
let next = slab.next;
slab.next = slab.entries.len();
slab.entries.push(Entry::Vacant(next));
}
slab.entries.push(Entry::Occupied(value));
slab.len += 1;
}
}
if slab.len == slab.entries.len() {
// no vacant enries, so next might not have been updated
slab.next = slab.entries.len();
} else if vacant_list_broken {
slab.recreate_vacant_list();
}
Ok(slab)
}
}
impl<'de, T> Deserialize<'de> for Slab<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(SlabVisitor(PhantomData))
}
}

50
third_party/rust/slab/tests/serde.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,50 @@
#![cfg(feature = "serde")]
extern crate serde;
extern crate serde_test;
extern crate slab;
use serde::{Deserialize, Serialize};
use serde_test::{assert_tokens, Token};
use slab::Slab;
#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
struct SlabPartialEq<T>(Slab<T>);
impl<T: PartialEq> PartialEq for SlabPartialEq<T> {
fn eq(&self, other: &Self) -> bool {
self.0
.iter()
.zip(other.0.iter())
.all(|(this, other)| this.0 == other.0 && this.1 == other.1)
}
}
#[test]
fn test_serde_empty() {
let slab = Slab::<usize>::new();
assert_tokens(
&SlabPartialEq(slab),
&[Token::Map { len: Some(0) }, Token::MapEnd],
);
}
#[test]
fn test_serde() {
let vec = vec![(1, 2), (3, 4), (5, 6)];
let slab: Slab<_> = vec.iter().cloned().collect();
assert_tokens(
&SlabPartialEq(slab),
&[
Token::Map { len: Some(3) },
Token::U64(1),
Token::I32(2),
Token::U64(3),
Token::I32(4),
Token::U64(5),
Token::I32(6),
Token::MapEnd,
],
);
}

421
third_party/rust/slab/tests/slab.rs поставляемый
Просмотреть файл

@ -2,6 +2,8 @@ extern crate slab;
use slab::*;
use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
#[test]
fn insert_get_remove_one() {
let mut slab = Slab::new();
@ -82,14 +84,21 @@ fn get_vacant_entry_without_using() {
}
#[test]
#[should_panic]
#[should_panic(expected = "invalid key")]
fn invalid_get_panics() {
let slab = Slab::<usize>::with_capacity(1);
slab[0];
let _ = &slab[0];
}
#[test]
#[should_panic]
#[should_panic(expected = "invalid key")]
fn invalid_get_mut_panics() {
let mut slab = Slab::<usize>::new();
let _ = &mut slab[0];
}
#[test]
#[should_panic(expected = "invalid key")]
fn double_remove_panics() {
let mut slab = Slab::<usize>::with_capacity(1);
let key = slab.insert(123);
@ -98,7 +107,7 @@ fn double_remove_panics() {
}
#[test]
#[should_panic]
#[should_panic(expected = "invalid key")]
fn invalid_remove_panics() {
let mut slab = Slab::<usize>::with_capacity(1);
slab.remove(0);
@ -116,6 +125,34 @@ fn slab_get_mut() {
assert_eq!(slab[key], 3);
}
#[test]
fn key_of_tagged() {
let mut slab = Slab::new();
slab.insert(0);
assert_eq!(slab.key_of(&slab[0]), 0);
}
#[test]
fn key_of_layout_optimizable() {
// Entry<&str> doesn't need a discriminant tag because it can use the
// nonzero-ness of ptr and store Vacant's next at the same offset as len
let mut slab = Slab::new();
slab.insert("foo");
slab.insert("bar");
let third = slab.insert("baz");
slab.insert("quux");
assert_eq!(slab.key_of(&slab[third]), third);
}
#[test]
fn key_of_zst() {
let mut slab = Slab::new();
slab.insert(());
let second = slab.insert(());
slab.insert(());
assert_eq!(slab.key_of(&slab[second]), second);
}
#[test]
fn reserve_does_not_allocate_if_available() {
let mut slab = Slab::with_capacity(10);
@ -150,10 +187,26 @@ fn reserve_exact_does_not_allocate_if_available() {
assert!(slab.capacity() - slab.len() == 8);
slab.reserve(8);
slab.reserve_exact(8);
assert_eq!(10, slab.capacity());
}
#[test]
#[should_panic(expected = "capacity overflow")]
fn reserve_does_panic_with_capacity_overflow() {
let mut slab = Slab::with_capacity(10);
slab.insert(true);
slab.reserve(std::usize::MAX);
}
#[test]
#[should_panic(expected = "capacity overflow")]
fn reserve_exact_does_panic_with_capacity_overflow() {
let mut slab = Slab::with_capacity(10);
slab.insert(true);
slab.reserve_exact(std::usize::MAX);
}
#[test]
fn retain() {
let mut slab = Slab::with_capacity(2);
@ -184,6 +237,43 @@ fn retain() {
assert_eq!(4, slab.capacity());
}
#[test]
fn into_iter() {
let mut slab = Slab::new();
for i in 0..8 {
slab.insert(i);
}
slab.remove(0);
slab.remove(4);
slab.remove(5);
slab.remove(7);
let vals: Vec<_> = slab
.into_iter()
.inspect(|&(key, val)| assert_eq!(key, val))
.map(|(_, val)| val)
.collect();
assert_eq!(vals, vec![1, 2, 3, 6]);
}
#[test]
fn into_iter_rev() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
let mut iter = slab.into_iter();
assert_eq!(iter.next_back(), Some((3, 3)));
assert_eq!(iter.next_back(), Some((2, 2)));
assert_eq!(iter.next(), Some((0, 0)));
assert_eq!(iter.next_back(), Some((1, 1)));
assert_eq!(iter.next_back(), None);
assert_eq!(iter.next(), None);
}
#[test]
fn iter() {
let mut slab = Slab::new();
@ -192,10 +282,14 @@ fn iter() {
slab.insert(i);
}
let vals: Vec<_> = slab.iter().enumerate().map(|(i, (key, val))| {
assert_eq!(i, key);
*val
}).collect();
let vals: Vec<_> = slab
.iter()
.enumerate()
.map(|(i, (key, val))| {
assert_eq!(i, key);
*val
})
.collect();
assert_eq!(vals, vec![0, 1, 2, 3]);
slab.remove(1);
@ -204,6 +298,19 @@ fn iter() {
assert_eq!(vals, vec![0, 2, 3]);
}
#[test]
fn iter_rev() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
slab.remove(0);
let vals = slab.iter().rev().collect::<Vec<_>>();
assert_eq!(vals, vec![(3, &3), (2, &2), (1, &1)]);
}
#[test]
fn iter_mut() {
let mut slab = Slab::new();
@ -214,7 +321,7 @@ fn iter_mut() {
for (i, (key, e)) in slab.iter_mut().enumerate() {
assert_eq!(i, key);
*e = *e + 1;
*e += 1;
}
let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
@ -223,13 +330,79 @@ fn iter_mut() {
slab.remove(2);
for (_, e) in slab.iter_mut() {
*e = *e + 1;
*e += 1;
}
let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
assert_eq!(vals, vec![2, 3, 5]);
}
#[test]
fn iter_mut_rev() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
slab.remove(2);
{
let mut iter = slab.iter_mut();
assert_eq!(iter.next(), Some((0, &mut 0)));
let mut prev_key = !0;
for (key, e) in iter.rev() {
*e += 10;
assert!(prev_key > key);
prev_key = key;
}
}
assert_eq!(slab[0], 0);
assert_eq!(slab[1], 11);
assert_eq!(slab[3], 13);
assert!(!slab.contains(2));
}
#[test]
fn from_iterator_sorted() {
let mut slab = (0..5).map(|i| (i, i)).collect::<Slab<_>>();
assert_eq!(slab.len(), 5);
assert_eq!(slab[0], 0);
assert_eq!(slab[2], 2);
assert_eq!(slab[4], 4);
assert_eq!(slab.vacant_entry().key(), 5);
}
#[test]
fn from_iterator_new_in_order() {
// all new keys come in increasing order, but existing keys are overwritten
let mut slab = [(0, 'a'), (1, 'a'), (1, 'b'), (0, 'b'), (9, 'a'), (0, 'c')]
.iter()
.cloned()
.collect::<Slab<_>>();
assert_eq!(slab.len(), 3);
assert_eq!(slab[0], 'c');
assert_eq!(slab[1], 'b');
assert_eq!(slab[9], 'a');
assert_eq!(slab.get(5), None);
assert_eq!(slab.vacant_entry().key(), 8);
}
#[test]
fn from_iterator_unordered() {
let mut slab = vec![(1, "one"), (50, "fifty"), (3, "three"), (20, "twenty")]
.into_iter()
.collect::<Slab<_>>();
assert_eq!(slab.len(), 4);
assert_eq!(slab.vacant_entry().key(), 0);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((1, &"one")));
assert_eq!(iter.next(), Some((3, &"three")));
assert_eq!(iter.next(), Some((20, &"twenty")));
assert_eq!(iter.next(), Some((50, &"fifty")));
assert_eq!(iter.next(), None);
}
#[test]
fn clear() {
let mut slab = Slab::new();
@ -260,3 +433,229 @@ fn clear() {
let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
assert!(vals.is_empty());
}
#[test]
fn shrink_to_fit_empty() {
let mut slab = Slab::<bool>::with_capacity(20);
slab.shrink_to_fit();
assert_eq!(slab.capacity(), 0);
}
#[test]
fn shrink_to_fit_no_vacant() {
let mut slab = Slab::with_capacity(20);
slab.insert(String::new());
slab.shrink_to_fit();
assert!(slab.capacity() < 10);
}
#[test]
fn shrink_to_fit_doesnt_move() {
let mut slab = Slab::with_capacity(8);
slab.insert("foo");
let bar = slab.insert("bar");
slab.insert("baz");
let quux = slab.insert("quux");
slab.remove(quux);
slab.remove(bar);
slab.shrink_to_fit();
assert_eq!(slab.len(), 2);
assert!(slab.capacity() >= 3);
assert_eq!(slab.get(0), Some(&"foo"));
assert_eq!(slab.get(2), Some(&"baz"));
assert_eq!(slab.vacant_entry().key(), bar);
}
#[test]
fn shrink_to_fit_doesnt_recreate_list_when_nothing_can_be_done() {
let mut slab = Slab::with_capacity(16);
for i in 0..4 {
slab.insert(Box::new(i));
}
slab.remove(0);
slab.remove(2);
slab.remove(1);
assert_eq!(slab.vacant_entry().key(), 1);
slab.shrink_to_fit();
assert_eq!(slab.len(), 1);
assert!(slab.capacity() >= 4);
assert_eq!(slab.vacant_entry().key(), 1);
}
#[test]
fn compact_empty() {
let mut slab = Slab::new();
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 0);
assert_eq!(slab.capacity(), 0);
slab.reserve(20);
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 0);
assert_eq!(slab.capacity(), 0);
slab.insert(0);
slab.insert(1);
slab.insert(2);
slab.remove(1);
slab.remove(2);
slab.remove(0);
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 0);
assert_eq!(slab.capacity(), 0);
}
#[test]
fn compact_no_moves_needed() {
let mut slab = Slab::new();
for i in 0..10 {
slab.insert(i);
}
slab.remove(8);
slab.remove(9);
slab.remove(6);
slab.remove(7);
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 6);
for ((index, &value), want) in slab.iter().zip(0..6) {
assert!(index == value);
assert_eq!(index, want);
}
assert!(slab.capacity() >= 6 && slab.capacity() < 10);
}
#[test]
fn compact_moves_successfully() {
let mut slab = Slab::with_capacity(20);
for i in 0..10 {
slab.insert(i);
}
for &i in &[0, 5, 9, 6, 3] {
slab.remove(i);
}
let mut moved = 0;
slab.compact(|&mut v, from, to| {
assert!(from > to);
assert!(from >= 5);
assert!(to < 5);
assert_eq!(from, v);
moved += 1;
true
});
assert_eq!(slab.len(), 5);
assert_eq!(moved, 2);
assert_eq!(slab.vacant_entry().key(), 5);
assert!(slab.capacity() >= 5 && slab.capacity() < 20);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((0, &8)));
assert_eq!(iter.next(), Some((1, &1)));
assert_eq!(iter.next(), Some((2, &2)));
assert_eq!(iter.next(), Some((3, &7)));
assert_eq!(iter.next(), Some((4, &4)));
assert_eq!(iter.next(), None);
}
#[test]
fn compact_doesnt_move_if_closure_errors() {
let mut slab = Slab::with_capacity(20);
for i in 0..10 {
slab.insert(i);
}
for &i in &[9, 3, 1, 4, 0] {
slab.remove(i);
}
slab.compact(|&mut v, from, to| {
assert!(from > to);
assert_eq!(from, v);
v != 6
});
assert_eq!(slab.len(), 5);
assert!(slab.capacity() >= 7 && slab.capacity() < 20);
assert_eq!(slab.vacant_entry().key(), 3);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((0, &8)));
assert_eq!(iter.next(), Some((1, &7)));
assert_eq!(iter.next(), Some((2, &2)));
assert_eq!(iter.next(), Some((5, &5)));
assert_eq!(iter.next(), Some((6, &6)));
assert_eq!(iter.next(), None);
}
#[test]
fn compact_handles_closure_panic() {
let mut slab = Slab::new();
for i in 0..10 {
slab.insert(i);
}
for i in 1..6 {
slab.remove(i);
}
let result = catch_unwind(AssertUnwindSafe(|| {
slab.compact(|&mut v, from, to| {
assert!(from > to);
assert_eq!(from, v);
if v == 7 {
panic!("test");
}
true
})
}));
match result {
Err(ref payload) if payload.downcast_ref() == Some(&"test") => {}
Err(bug) => resume_unwind(bug),
Ok(()) => unreachable!(),
}
assert_eq!(slab.len(), 5 - 1);
assert_eq!(slab.vacant_entry().key(), 3);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((0, &0)));
assert_eq!(iter.next(), Some((1, &9)));
assert_eq!(iter.next(), Some((2, &8)));
assert_eq!(iter.next(), Some((6, &6)));
assert_eq!(iter.next(), None);
}
#[test]
fn fully_consumed_drain() {
let mut slab = Slab::new();
for i in 0..3 {
slab.insert(i);
}
{
let mut drain = slab.drain();
assert_eq!(Some(0), drain.next());
assert_eq!(Some(1), drain.next());
assert_eq!(Some(2), drain.next());
assert_eq!(None, drain.next());
}
assert!(slab.is_empty());
}
#[test]
fn partially_consumed_drain() {
let mut slab = Slab::new();
for i in 0..3 {
slab.insert(i);
}
{
let mut drain = slab.drain();
assert_eq!(Some(0), drain.next());
}
assert!(slab.is_empty())
}
#[test]
fn drain_rev() {
let mut slab = Slab::new();
for i in 0..10 {
slab.insert(i);
}
slab.remove(9);
let vals: Vec<u64> = slab.drain().rev().collect();
assert_eq!(vals, (0..9).rev().collect::<Vec<u64>>());
}