* Closes https://github.com/Lokathor/tinyvec/issues/75

* This is a breaking change to the macro

* benchmarks fixes.

* slim down to just `take`
This commit is contained in:
Lokathor
2020-07-03 10:56:45 -06:00
committed by GitHub
parent fb92d14ab4
commit 5bb7c7585b
10 changed files with 322 additions and 306 deletions
+232 -220
View File
@@ -1,8 +1,14 @@
use core::borrow::Borrow;
use core::fmt;
use core::mem::swap;
use core::ops::{AddAssign, SubAssign};
#![cfg(feature = "experimental_array_set")]
// This was contributed by user `dhardy`! Big thanks.
use super::Array;
use core::{
borrow::Borrow,
fmt,
mem::swap,
ops::{AddAssign, SubAssign},
};
/// Error resulting from attempting to insert into a full array
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -11,9 +17,9 @@ pub struct InsertError;
// TODO(when std): impl std::error::Error for InsertError {}
impl fmt::Display for InsertError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ArraySet: insertion failed")
}
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ArraySet: insertion failed")
}
}
/// An array-backed set
@@ -26,266 +32,272 @@ impl fmt::Display for InsertError {
/// Due to restrictions, `L` may be only `u8` or `u16`.
#[derive(Clone, Debug, Default)]
pub struct ArraySet<A: Array, L> {
arr: A,
len: L,
arr: A,
len: L,
}
impl<A: Array + Default, L: From<u8>> ArraySet<A, L> {
/// Constructs a new, empty, set
#[inline]
pub fn new() -> Self {
ArraySet {
arr: Default::default(),
len: 0.into(),
}
}
/// Constructs a new, empty, set
#[inline]
pub fn new() -> Self {
ArraySet { arr: Default::default(), len: 0.into() }
}
}
impl<A: Array, L: Copy + Into<usize>> ArraySet<A, L> {
/// Constructs a new set from given inputs
///
/// Panics if `len> arr.len()`.
#[inline]
pub fn from(arr: A, len: L) -> Self {
if len.into() > A::CAPACITY {
panic!("ArraySet::from(array, len): len > array.len()");
}
ArraySet { arr, len }
/// Constructs a new set from given inputs
///
/// Panics if `len> arr.len()`.
#[inline]
pub fn from(arr: A, len: L) -> Self {
if len.into() > A::CAPACITY {
panic!("ArraySet::from(array, len): len > array.len()");
}
ArraySet { arr, len }
}
}
impl<A: Array, L> ArraySet<A, L>
where
L: Copy + PartialEq + From<u8> + Into<usize>,
L: Copy + PartialEq + From<u8> + Into<usize>,
{
/// Returns the fixed capacity of the set
#[inline]
pub fn capacity(&self) -> usize {
A::CAPACITY
}
/// Returns the number of elements in the set
#[inline]
pub fn len(&self) -> usize {
self.len.into()
}
/// Returns true when the set contains no elements
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0.into()
}
/// Removes all elements
#[inline]
pub fn clear(&mut self) {
self.len = 0.into();
}
/// Iterate over all contents
#[inline]
pub fn iter(&self) -> Iter<A::Item> {
Iter { a: self.arr.as_slice(), i: 0 }
}
/// Returns the fixed capacity of the set
#[inline]
pub fn capacity(&self) -> usize {
A::CAPACITY
}
/// Returns the number of elements in the set
#[inline]
pub fn len(&self) -> usize {
self.len.into()
}
/// Returns true when the set contains no elements
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0.into()
}
/// Removes all elements
#[inline]
pub fn clear(&mut self) {
self.len = 0.into();
}
/// Iterate over all contents
#[inline]
pub fn iter(&self) -> Iter<A::Item> {
Iter { a: self.arr.as_slice(), i: 0 }
}
}
impl<A: Array, L> ArraySet<A, L>
where
L: Copy + PartialOrd + AddAssign + SubAssign + From<u8> + Into<usize>,
L: Copy + PartialOrd + AddAssign + SubAssign + From<u8> + Into<usize>,
{
/// Check whether the set contains `elt`
#[inline]
pub fn contains<Q: Eq + ?Sized>(&self, elt: &Q) -> bool where A::Item: Borrow<Q> {
self.get(elt).is_some()
}
/// Check whether the set contains `elt`
#[inline]
pub fn contains<Q: Eq + ?Sized>(&self, elt: &Q) -> bool
where
A::Item: Borrow<Q>,
{
self.get(elt).is_some()
}
/// Get a reference to a contained item matching `elt`
pub fn get<Q: Eq + ?Sized>(&self, elt: &Q) -> Option<&A::Item> where
A::Item: Borrow<Q> {
let len: usize = self.len.into();
let arr = self.arr.as_slice();
for i in 0..len {
if arr[i].borrow() == elt {
return Some(&arr[i]);
}
}
None
/// Get a reference to a contained item matching `elt`
pub fn get<Q: Eq + ?Sized>(&self, elt: &Q) -> Option<&A::Item>
where
A::Item: Borrow<Q>,
{
let len: usize = self.len.into();
let arr = self.arr.as_slice();
for i in 0..len {
if arr[i].borrow() == elt {
return Some(&arr[i]);
}
}
None
}
/// Remove an item matching `elt`, if any
pub fn remove<Q: Eq + ?Sized>(&mut self, elt: &Q) -> Option<A::Item> where
A::Item: Borrow<Q> {
let len: usize = self.len.into();
let arr = self.arr.as_slice_mut();
for i in 0..len {
if arr[i].borrow() == elt {
let l1 = len - 1;
if i < l1 {
arr.swap(i, l1);
}
self.len -= L::from(1);
let mut r = Default::default();
swap(&mut arr[l1], &mut r);
return Some(r);
}
/// Remove an item matching `elt`, if any
pub fn remove<Q: Eq + ?Sized>(&mut self, elt: &Q) -> Option<A::Item>
where
A::Item: Borrow<Q>,
{
let len: usize = self.len.into();
let arr = self.arr.as_slice_mut();
for i in 0..len {
if arr[i].borrow() == elt {
let l1 = len - 1;
if i < l1 {
arr.swap(i, l1);
}
None
self.len -= L::from(1);
return take(&mut arr[l1]);
}
}
/// Remove any items for which `f(item) == false`
pub fn retain<F>(&mut self, mut f: F) where
F: FnMut(&A::Item) -> bool {
let mut len = self.len;
let arr = self.arr.as_slice_mut();
let mut i = 0;
while i < len.into() {
if !f(&arr[i]) {
len -= L::from(1);
if i < len.into() {
arr.swap(i, len.into());
}
} else {
i += 1;
}
None
}
/// Remove any items for which `f(item) == false`
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&A::Item) -> bool,
{
let mut len = self.len;
let arr = self.arr.as_slice_mut();
let mut i = 0;
while i < len.into() {
if !f(&arr[i]) {
len -= L::from(1);
if i < len.into() {
arr.swap(i, len.into());
}
self.len = len;
} else {
i += 1;
}
}
self.len = len;
}
}
impl<A: Array, L> ArraySet<A, L>
where
A::Item: Eq,
L: Copy + PartialOrd + AddAssign + SubAssign + From<u8> + Into<usize>,
A::Item: Eq,
L: Copy + PartialOrd + AddAssign + SubAssign + From<u8> + Into<usize>,
{
/// Insert an item
///
/// Due to the fixed size of the backing array, insertion may fail.
#[inline]
pub fn insert(&mut self, elt: A::Item) -> Result<bool, InsertError> {
if self.contains(&elt) {
return Ok(false);
}
let len = self.len.into();
let arr = self.arr.as_slice_mut();
if len >= arr.len() {
return Err(InsertError);
}
arr[len] = elt;
self.len += L::from(1);
Ok(true)
/// Insert an item
///
/// Due to the fixed size of the backing array, insertion may fail.
#[inline]
pub fn insert(&mut self, elt: A::Item) -> Result<bool, InsertError> {
if self.contains(&elt) {
return Ok(false);
}
/* Hits borrow checker
pub fn get_or_insert(&mut self, elt: A::Item) -> Result<&A::Item, InsertError> {
if let Some(r) = self.get(&elt) {
return Ok(r);
}
self.insert(elt)?;
let len: usize = self.len.into();
Ok(&self.arr.as_slice()[len - 1])
let len = self.len.into();
let arr = self.arr.as_slice_mut();
if len >= arr.len() {
return Err(InsertError);
}
*/
/// Replace an item matching `elt` with `elt`, or insert `elt`
///
/// Returns the replaced item, if any. Fails when there is no matching item
/// and the backing array is full, preventing insertion.
pub fn replace(&mut self, mut elt: A::Item) -> Result<Option<A::Item>, InsertError> {
let len: usize = self.len.into();
let arr = self.arr.as_slice_mut();
for i in 0..len {
if arr[i] == elt {
swap(&mut arr[i], &mut elt);
return Ok(Some(elt));
}
}
if len >= arr.len() {
return Err(InsertError);
}
arr[len] = elt;
self.len += L::from(1);
Ok(None)
arr[len] = elt;
self.len += L::from(1);
Ok(true)
}
/* Hits borrow checker
pub fn get_or_insert(&mut self, elt: A::Item) -> Result<&A::Item, InsertError> {
if let Some(r) = self.get(&elt) {
return Ok(r);
}
self.insert(elt)?;
let len: usize = self.len.into();
Ok(&self.arr.as_slice()[len - 1])
}
*/
/// Replace an item matching `elt` with `elt`, or insert `elt`
///
/// Returns the replaced item, if any. Fails when there is no matching item
/// and the backing array is full, preventing insertion.
pub fn replace(
&mut self,
mut elt: A::Item,
) -> Result<Option<A::Item>, InsertError> {
let len: usize = self.len.into();
let arr = self.arr.as_slice_mut();
for i in 0..len {
if arr[i] == elt {
swap(&mut arr[i], &mut elt);
return Ok(Some(elt));
}
}
if len >= arr.len() {
return Err(InsertError);
}
arr[len] = elt;
self.len += L::from(1);
Ok(None)
}
}
/// Type returned by [`ArraySet::iter`]
pub struct Iter<'a, T> {
a: &'a [T],
i: usize,
a: &'a [T],
i: usize,
}
impl<'a, T> ExactSizeIterator for Iter<'a, T> {
#[inline]
fn len(&self) -> usize {
self.a.len() - self.i
}
#[inline]
fn len(&self) -> usize {
self.a.len() - self.i
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.a.len() {
let i = self.i;
self.i += 1;
Some(&self.a[i])
} else {
None
}
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.a.len() {
let i = self.i;
self.i += 1;
Some(&self.a[i])
} else {
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
#[cfg(test)]
mod test {
use super::*;
use core::mem::size_of;
#[test]
fn test_size() {
assert_eq!(size_of::<ArraySet<[i8; 7], u8>>(), 8);
}
#[test]
fn test() {
let mut set: ArraySet<[i8; 7], u8> = ArraySet::new();
assert_eq!(set.capacity(), 7);
assert_eq!(set.insert(1), Ok(true));
assert_eq!(set.insert(5), Ok(true));
assert_eq!(set.insert(6), Ok(true));
assert_eq!(set.len(), 3);
assert_eq!(set.insert(5), Ok(false));
assert_eq!(set.len(), 3);
assert_eq!(set.replace(1), Ok(Some(1)));
assert_eq!(set.replace(2), Ok(None));
assert_eq!(set.len(), 4);
assert_eq!(set.insert(3), Ok(true));
assert_eq!(set.insert(4), Ok(true));
assert_eq!(set.insert(7), Ok(true));
assert_eq!(set.insert(8), Err(InsertError));
assert_eq!(set.len(), 7);
assert_eq!(set.replace(9), Err(InsertError));
assert_eq!(set.remove(&3), Some(3));
assert_eq!(set.len(), 6);
set.retain(|x| *x == 3 || *x == 6);
assert_eq!(set.len(), 1);
assert!(!set.contains(&3));
assert!(set.contains(&6));
}
use super::*;
use core::mem::size_of;
#[test]
fn test_size() {
assert_eq!(size_of::<ArraySet<[i8; 7], u8>>(), 8);
}
#[test]
fn test() {
let mut set: ArraySet<[i8; 7], u8> = ArraySet::new();
assert_eq!(set.capacity(), 7);
assert_eq!(set.insert(1), Ok(true));
assert_eq!(set.insert(5), Ok(true));
assert_eq!(set.insert(6), Ok(true));
assert_eq!(set.len(), 3);
assert_eq!(set.insert(5), Ok(false));
assert_eq!(set.len(), 3);
assert_eq!(set.replace(1), Ok(Some(1)));
assert_eq!(set.replace(2), Ok(None));
assert_eq!(set.len(), 4);
assert_eq!(set.insert(3), Ok(true));
assert_eq!(set.insert(4), Ok(true));
assert_eq!(set.insert(7), Ok(true));
assert_eq!(set.insert(8), Err(InsertError));
assert_eq!(set.len(), 7);
assert_eq!(set.replace(9), Err(InsertError));
assert_eq!(set.remove(&3), Some(3));
assert_eq!(set.len(), 6);
set.retain(|x| *x == 3 || *x == 6);
assert_eq!(set.len(), 1);
assert!(!set.contains(&3));
assert!(set.contains(&6));
}
}
+22 -25
View File
@@ -13,7 +13,7 @@ use super::*;
///
/// // The backing array type can be specified in the macro call
/// let empty_av = array_vec!([u8; 16]);
/// let some_ints = array_vec!([i32; 4], 1, 2, 3);
/// let some_ints = array_vec!([i32; 4] => 1, 2, 3);
///
/// // Or left to inference
/// let empty_av: ArrayVec<[u8; 10]> = array_vec!();
@@ -21,24 +21,21 @@ use super::*;
/// ```
#[macro_export]
macro_rules! array_vec {
($array_type:ty) => {
{
let av: $crate::ArrayVec<$array_type> = Default::default();
av
}
};
($array_type:ty, $($elem:expr),*) => {
($array_type:ty => $($elem:expr),* $(,)?) => {
{
let mut av: $crate::ArrayVec<$array_type> = Default::default();
$( av.push($elem); )*
av
}
};
() => {
array_vec!(_)
($array_type:ty) => {
$crate::array_vec!($array_type =>)
};
($($elem:expr),*) => {
array_vec!(_, $($elem),*)
$crate::array_vec!(_ => $($elem),*)
};
() => {
$crate::array_vec!(_)
};
}
@@ -63,7 +60,7 @@ macro_rules! array_vec {
/// to have.
/// ```rust
/// # use tinyvec::*;
/// let some_ints = array_vec!([i32; 4], 1, 2, 3);
/// let some_ints = array_vec!([i32; 4] => 1, 2, 3);
/// assert_eq!(some_ints.len(), 3);
/// ```
///
@@ -141,8 +138,8 @@ impl<A: Array> ArrayVec<A> {
/// ## Example
/// ```rust
/// # use tinyvec::*;
/// let mut av = array_vec!([i32; 10], 1, 2, 3);
/// let mut av2 = array_vec!([i32; 10], 4, 5, 6);
/// let mut av = array_vec!([i32; 10] => 1, 2, 3);
/// let mut av2 = array_vec!([i32; 10] => 4, 5, 6);
/// av.append(&mut av2);
/// assert_eq!(av, &[1, 2, 3, 4, 5, 6][..]);
/// assert_eq!(av2, &[][..]);
@@ -216,7 +213,7 @@ impl<A: Array> ArrayVec<A> {
/// ## Example
/// ```rust
/// # use tinyvec::*;
/// let mut av = array_vec!([i32; 4], 1, 2, 3);
/// let mut av = array_vec!([i32; 4] => 1, 2, 3);
/// let av2: ArrayVec<[i32; 4]> = av.drain(1..).collect();
/// assert_eq!(av.as_slice(), &[1][..]);
/// assert_eq!(av2.as_slice(), &[2, 3][..]);
@@ -356,7 +353,7 @@ impl<A: Array> ArrayVec<A> {
/// ## Example
/// ```rust
/// use tinyvec::*;
/// let mut av = array_vec!([i32; 10], 1, 2, 3);
/// let mut av = array_vec!([i32; 10] => 1, 2, 3);
/// av.insert(1, 4);
/// assert_eq!(av.as_slice(), &[1, 4, 2, 3]);
/// av.insert(4, 5);
@@ -406,7 +403,7 @@ impl<A: Array> ArrayVec<A> {
/// ## Example
/// ```rust
/// # use tinyvec::*;
/// let mut av = array_vec!([i32; 10], 1, 2);
/// let mut av = array_vec!([i32; 10] => 1, 2);
/// assert_eq!(av.pop(), Some(2));
/// assert_eq!(av.pop(), Some(1));
/// assert_eq!(av.pop(), None);
@@ -441,7 +438,7 @@ impl<A: Array> ArrayVec<A> {
#[inline(always)]
pub fn push(&mut self, val: A::Item) {
if self.len < A::CAPACITY {
replace(&mut self.data.as_slice_mut()[self.len], val);
self.data.as_slice_mut()[self.len] = val;
self.len += 1;
} else {
panic!("ArrayVec::push> capacity overflow!")
@@ -460,7 +457,7 @@ impl<A: Array> ArrayVec<A> {
///
/// ```rust
/// # use tinyvec::*;
/// let mut av = array_vec!([i32; 4], 1, 2, 3);
/// let mut av = array_vec!([i32; 4] => 1, 2, 3);
/// assert_eq!(av.remove(1), 2);
/// assert_eq!(&av[..], [1, 3]);
/// ```
@@ -481,11 +478,11 @@ impl<A: Array> ArrayVec<A> {
/// ```rust
/// # use tinyvec::*;
///
/// let mut av = array_vec!([&str; 10], "hello");
/// let mut av = array_vec!([&str; 10] => "hello");
/// av.resize(3, "world");
/// assert_eq!(&av[..], ["hello", "world", "world"]);
///
/// let mut av = array_vec!([i32; 10], 1, 2, 3, 4);
/// let mut av = array_vec!([i32; 10] => 1, 2, 3, 4);
/// av.resize(2, 0);
/// assert_eq!(&av[..], [1, 2]);
/// ```
@@ -507,7 +504,7 @@ impl<A: Array> ArrayVec<A> {
/// ```rust
/// # use tinyvec::*;
///
/// let mut av = array_vec!([i32; 10], 1, 2, 3);
/// let mut av = array_vec!([i32; 10] => 1, 2, 3);
/// av.resize_with(5, Default::default);
/// assert_eq!(&av[..], [1, 2, 3, 0, 0]);
///
@@ -542,7 +539,7 @@ impl<A: Array> ArrayVec<A> {
/// ```rust
/// # use tinyvec::*;
///
/// let mut av = array_vec!([i32; 10], 1, 1, 2, 3, 3, 4);
/// let mut av = array_vec!([i32; 10] => 1, 1, 2, 3, 3, 4);
/// av.retain(|&x| x % 2 == 0);
/// assert_eq!(&av[..], [2, 4]);
/// ```
@@ -621,7 +618,7 @@ impl<A: Array> ArrayVec<A> {
///
/// ```rust
/// # use tinyvec::*;
/// let mut av = array_vec!([i32; 4], 1, 2, 3);
/// let mut av = array_vec!([i32; 4] => 1, 2, 3);
/// let av2 = av.split_off(1);
/// assert_eq!(&av[..], [1]);
/// assert_eq!(&av2[..], [2, 3]);
@@ -656,7 +653,7 @@ impl<A: Array> ArrayVec<A> {
/// ## Example
/// ```rust
/// # use tinyvec::*;
/// let mut av = array_vec!([&str; 4], "foo", "bar", "quack", "zap");
/// let mut av = array_vec!([&str; 4] => "foo", "bar", "quack", "zap");
///
/// assert_eq!(av.swap_remove(1), "bar");
/// assert_eq!(&av[..], ["foo", "zap", "quack"]);
+3 -1
View File
@@ -10,7 +10,7 @@
#![warn(clippy::must_use_candidate)]
#![warn(missing_docs)]
//! Programmers can have a little vec, as a treat.
//! For all those times when you need just a little bit of vec support.
//!
//! ## What This Is
//!
@@ -88,7 +88,9 @@ pub extern crate alloc;
mod array;
pub use array::*;
#[cfg(feature = "experimental_array_set")]
mod arrayset;
#[cfg(feature = "experimental_array_set")]
pub use arrayset::*;
mod arrayvec;
+2 -2
View File
@@ -352,7 +352,7 @@ impl<'s, T> SliceVec<'s, T> {
#[inline(always)]
pub fn push(&mut self, val: T) {
if self.len < self.capacity() {
replace(&mut self.data[self.len], val);
self.data[self.len] = val;
self.len += 1;
} else {
panic!("SliceVec::push> capacity overflow")
@@ -448,7 +448,7 @@ impl<'s, T> SliceVec<'s, T> {
if needs_drop::<T>() {
while self.len() > new_len {
self.len -= 1;
replace(&mut self.data[self.len], f());
self.data[self.len] = f();
}
} else {
self.len = new_len;
+33 -36
View File
@@ -17,8 +17,8 @@ use alloc::vec::Vec;
///
/// // The backing array type can be specified in the macro call
/// let empty_tv = tiny_vec!([u8; 16]);
/// let some_ints = tiny_vec!([i32; 4], 1, 2, 3);
/// let many_ints = tiny_vec!([i32; 4], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3);
/// let many_ints = tiny_vec!([i32; 4] => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
///
/// // Or left to inference
/// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!();
@@ -27,36 +27,30 @@ use alloc::vec::Vec;
/// ```
#[macro_export]
macro_rules! tiny_vec {
($array_type:ty) => {
($array_type:ty => $($elem:expr),* $(,)?) => {
{
let mut tv: $crate::TinyVec<$array_type> = Default::default();
tv
}
};
($array_type:ty, $($elem:expr),* $(,)?) => {
{
// Note(Lokathor): This goofy looking thing will count the number of
// `$elem` entries we were given. We can't spit out the "+1"s on their
// own, we need to use `$elem` in the repetition-expansion somehow.
// However, we also can't assume it's `Copy` data, so we must use `$elem`
// only once "for real" in the expansion as a whole. To achieve this, we
// can `stringify!` each element in an inner block, then have the block
// return a 1. The stringification is a compile time thing, it won't
// actually move any values.
// https://github.com/rust-lang/lang-team/issues/28
const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*;
// If we have more `$elem` than the `CAPACITY` we will simply go directly
// to constructing on the heap.
match $crate::TinyVec::constructor_for_capacity(INVOKED_ELEM_COUNT) {
$crate::TinyVecConstructor::Inline(f) => f($crate::array_vec!($array_type, $($elem),*)),
$crate::TinyVecConstructor::Heap(f) => f(vec!($($elem),*)),
$crate::TinyVecConstructor::Inline(f) => {
f($crate::array_vec!($array_type => $($elem),*))
}
$crate::TinyVecConstructor::Heap(f) => {
f(vec!($($elem),*))
}
}
}
};
() => {
tiny_vec!(_)
($array_type:ty) => {
$crate::tiny_vec!($array_type =>)
};
($($elem:expr),*) => {
tiny_vec!(_, $($elem),*)
$crate::tiny_vec!(_ => $($elem),*)
};
() => {
$crate::tiny_vec!(_)
};
}
@@ -85,7 +79,7 @@ pub enum TinyVecConstructor<A: Array> {
/// ```rust
/// # use tinyvec::*;
/// let empty_tv = tiny_vec!([u8; 16]);
/// let some_ints = tiny_vec!([i32; 4], 1, 2, 3);
/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3);
/// ```
#[derive(Clone)]
pub enum TinyVec<A: Array> {
@@ -152,7 +146,7 @@ impl<A: Array> TinyVec<A> {
for item in arr.drain(..) {
v.push(item);
}
replace(self, TinyVec::Heap(v));
*self = TinyVec::Heap(v);
}
TinyVec::Heap(_) => (),
}
@@ -274,7 +268,7 @@ impl<A: Array> TinyVec<A> {
/// ## Example
/// ```rust
/// use tinyvec::*;
/// let mut tv = tiny_vec!([i32; 4], 1, 2, 3);
/// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
/// let tv2: TinyVec<[i32; 4]> = tv.drain(1..).collect();
/// assert_eq!(tv.as_slice(), &[1][..]);
/// assert_eq!(tv2.as_slice(), &[2, 3][..]);
@@ -366,7 +360,7 @@ impl<A: Array> TinyVec<A> {
/// ## Example
/// ```rust
/// use tinyvec::*;
/// let mut tv = tiny_vec!([i32; 10], 1, 2, 3);
/// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3);
/// tv.insert(1, 4);
/// assert_eq!(tv.as_slice(), &[1, 4, 2, 3]);
/// tv.insert(4, 5);
@@ -456,7 +450,7 @@ impl<A: Array> TinyVec<A> {
///
/// ```rust
/// use tinyvec::*;
/// let mut tv = tiny_vec!([i32; 4], 1, 2, 3);
/// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
/// assert_eq!(tv.remove(1), 2);
/// assert_eq!(tv.as_slice(), &[1, 3][..]);
/// ```
@@ -478,11 +472,11 @@ impl<A: Array> TinyVec<A> {
/// ```rust
/// use tinyvec::*;
///
/// let mut tv = tiny_vec!([&str; 10], "hello");
/// let mut tv = tiny_vec!([&str; 10] => "hello");
/// tv.resize(3, "world");
/// assert_eq!(tv.as_slice(), &["hello", "world", "world"][..]);
///
/// let mut tv = tiny_vec!([i32; 10], 1, 2, 3, 4);
/// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4);
/// tv.resize(2, 0);
/// assert_eq!(tv.as_slice(), &[1, 2][..]);
/// ```
@@ -514,7 +508,7 @@ impl<A: Array> TinyVec<A> {
/// ```rust
/// use tinyvec::*;
///
/// let mut tv = tiny_vec!([i32; 10], 1, 2, 3);
/// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3);
/// tv.resize_with(5, Default::default);
/// assert_eq!(tv.as_slice(), &[1, 2, 3, 0, 0][..]);
///
@@ -541,7 +535,7 @@ impl<A: Array> TinyVec<A> {
/// ```rust
/// use tinyvec::*;
///
/// let mut tv = tiny_vec!([i32; 10], 1, 2, 3, 4);
/// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4);
/// tv.retain(|&x| x % 2 == 0);
/// assert_eq!(tv.as_slice(), &[2, 4][..]);
/// ```
@@ -565,7 +559,7 @@ impl<A: Array> TinyVec<A> {
///
/// ```rust
/// use tinyvec::*;
/// let mut tv = tiny_vec!([i32; 4], 1, 2, 3);
/// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
/// let tv2 = tv.split_off(1);
/// assert_eq!(tv.as_slice(), &[1][..]);
/// assert_eq!(tv2.as_slice(), &[2, 3][..]);
@@ -589,7 +583,7 @@ impl<A: Array> TinyVec<A> {
/// ## Example
/// ```rust
/// use tinyvec::*;
/// let mut tv = tiny_vec!([&str; 4], "foo", "bar", "quack", "zap");
/// let mut tv = tiny_vec!([&str; 4] => "foo", "bar", "quack", "zap");
///
/// assert_eq!(tv.swap_remove(1), "bar");
/// assert_eq!(tv.as_slice(), &["foo", "zap", "quack"][..]);
@@ -640,7 +634,7 @@ pub struct TinyVecDrain<'p, A: Array> {
target_index: usize,
target_count: usize,
}
impl<'p, A: Array> FusedIterator for TinyVecDrain<'p, A> { }
impl<'p, A: Array> FusedIterator for TinyVecDrain<'p, A> {}
impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> {
type Item = A::Item;
#[inline]
@@ -778,7 +772,7 @@ impl<A: Array> TinyVecIterator<A> {
}
}
}
impl<A: Array> FusedIterator for TinyVecIterator<A> { }
impl<A: Array> FusedIterator for TinyVecIterator<A> {}
impl<A: Array> Iterator for TinyVecIterator<A> {
type Item = A::Item;
#[inline]
@@ -819,7 +813,10 @@ impl<A: Array> Iterator for TinyVecIterator<A> {
}
}
impl<A: Array> Debug for TinyVecIterator<A> where A::Item: Debug {
impl<A: Array> Debug for TinyVecIterator<A>
where
A::Item: Debug,
{
#[allow(clippy::missing_inline_in_public_items)]
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish()