use super::raw_vec::RawVec;
use crate::collections::CollectionAllocErr;
use crate::Bump;
use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{self, Hash};
use core::iter::FusedIterator;
use core::marker::PhantomData;
use core::mem;
use core::ops;
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Index, IndexMut, RangeBounds};
use core::ptr;
use core::ptr::NonNull;
use core::slice;
#[cfg(feature = "std")]
use std::io;
unsafe fn arith_offset<T>(p: *const T, offset: isize) -> *const T {
p.offset(offset)
}
fn partition_dedup_by<T, F>(s: &mut [T], mut same_bucket: F) -> (&mut [T], &mut [T])
where
F: FnMut(&mut T, &mut T) -> bool,
{
let len = s.len();
if len <= 1 {
return (s, &mut []);
}
let ptr = s.as_mut_ptr();
let mut next_read: usize = 1;
let mut next_write: usize = 1;
unsafe {
while next_read < len {
let ptr_read = ptr.add(next_read);
let prev_ptr_write = ptr.add(next_write - 1);
if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {
if next_read != next_write {
let ptr_write = prev_ptr_write.offset(1);
mem::swap(&mut *ptr_read, &mut *ptr_write);
}
next_write += 1;
}
next_read += 1;
}
}
s.split_at_mut(next_write)
}
unsafe fn offset_from<T>(p: *const T, origin: *const T) -> isize
where
T: Sized,
{
let pointee_size = mem::size_of::<T>();
assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
let d = isize::wrapping_sub(p as _, origin as _);
d / (pointee_size as isize)
}
#[macro_export]
macro_rules! vec {
(in $bump:expr; $elem:expr; $n:expr) => {{
let n = $n;
let mut v = $crate::collections::Vec::with_capacity_in(n, $bump);
if n > 0 {
let elem = $elem;
for _ in 0..n - 1 {
v.push(elem.clone());
}
v.push(elem);
}
v
}};
(in $bump:expr) => { $crate::collections::Vec::new_in($bump) };
(in $bump:expr; $($x:expr),*) => {{
let mut v = $crate::collections::Vec::new_in($bump);
$( v.push($x); )*
v
}};
(in $bump:expr; $($x:expr,)*) => (bumpalo::vec![in $bump; $($x),*])
}
pub struct Vec<'bump, T: 'bump> {
buf: RawVec<'bump, T>,
len: usize,
}
impl<'bump, T: 'bump> Vec<'bump, T> {
#[inline]
pub fn new_in(bump: &'bump Bump) -> Vec<'bump, T> {
Vec {
buf: RawVec::new_in(bump),
len: 0,
}
}
#[inline]
pub fn with_capacity_in(capacity: usize, bump: &'bump Bump) -> Vec<'bump, T> {
Vec {
buf: RawVec::with_capacity_in(capacity, bump),
len: 0,
}
}
pub fn from_iter_in<I: IntoIterator<Item = T>>(iter: I, bump: &'bump Bump) -> Vec<'bump, T> {
let mut v = Vec::new_in(bump);
v.extend(iter);
v
}
pub unsafe fn from_raw_parts_in(
ptr: *mut T,
length: usize,
capacity: usize,
bump: &'bump Bump,
) -> Vec<'bump, T> {
Vec {
buf: RawVec::from_raw_parts_in(ptr, capacity, bump),
len: length,
}
}
#[inline]
#[must_use]
pub fn bump(&self) -> &'bump Bump {
self.buf.bump()
}
#[inline]
pub fn capacity(&self) -> usize {
self.buf.cap()
}
pub fn reserve(&mut self, additional: usize) {
self.buf.reserve(self.len, additional);
}
pub fn reserve_exact(&mut self, additional: usize) {
self.buf.reserve_exact(self.len, additional);
}
pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
self.buf.try_reserve(self.len, additional)
}
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
self.buf.try_reserve_exact(self.len, additional)
}
pub fn shrink_to_fit(&mut self) {
if self.capacity() != self.len {
self.buf.shrink_to_fit(self.len);
}
}
pub fn into_bump_slice(self) -> &'bump [T] {
unsafe {
let ptr = self.as_ptr();
let len = self.len();
mem::forget(self);
slice::from_raw_parts(ptr, len)
}
}
pub fn into_bump_slice_mut(mut self) -> &'bump mut [T] {
let ptr = self.as_mut_ptr();
let len = self.len();
mem::forget(self);
unsafe { slice::from_raw_parts_mut(ptr, len) }
}
pub fn truncate(&mut self, len: usize) {
let current_len = self.len;
unsafe {
let mut ptr = self.as_mut_ptr().add(self.len);
let mut local_len = SetLenOnDrop::new(&mut self.len);
for _ in len..current_len {
local_len.decrement_len(1);
ptr = ptr.offset(-1);
ptr::drop_in_place(ptr);
}
}
}
#[inline]
pub fn as_slice(&self) -> &[T] {
self
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
self
}
#[inline]
pub fn as_ptr(&self) -> *const T {
let ptr = self.buf.ptr();
unsafe {
if ptr.is_null() {
core::hint::unreachable_unchecked();
}
}
ptr
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut T {
let ptr = self.buf.ptr();
unsafe {
if ptr.is_null() {
core::hint::unreachable_unchecked();
}
}
ptr
}
#[inline]
pub unsafe fn set_len(&mut self, new_len: usize) {
self.len = new_len;
}
#[inline]
pub fn swap_remove(&mut self, index: usize) -> T {
unsafe {
let hole: *mut T = &mut self[index];
let last = ptr::read(self.get_unchecked(self.len - 1));
self.len -= 1;
ptr::replace(hole, last)
}
}
pub fn insert(&mut self, index: usize, element: T) {
let len = self.len();
assert!(index <= len);
if len == self.buf.cap() {
self.reserve(1);
}
unsafe {
{
let p = self.as_mut_ptr().add(index);
ptr::copy(p, p.offset(1), len - index);
ptr::write(p, element);
}
self.set_len(len + 1);
}
}
pub fn remove(&mut self, index: usize) -> T {
let len = self.len();
assert!(index < len);
unsafe {
let ret;
{
let ptr = self.as_mut_ptr().add(index);
ret = ptr::read(ptr);
ptr::copy(ptr.offset(1), ptr, len - index - 1);
}
self.set_len(len - 1);
ret
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&T) -> bool,
{
self.drain_filter(|x| !f(x));
}
pub fn retain_mut<F>(&mut self, mut f: F)
where
F: FnMut(&mut T) -> bool,
{
self.drain_filter(|x| !f(x));
}
pub fn drain_filter<'a, F>(&'a mut self, filter: F) -> DrainFilter<'a, 'bump, T, F>
where
F: FnMut(&mut T) -> bool,
{
let old_len = self.len();
unsafe {
self.set_len(0);
}
DrainFilter {
vec: self,
idx: 0,
del: 0,
old_len,
pred: filter,
}
}
#[inline]
pub fn dedup_by_key<F, K>(&mut self, mut key: F)
where
F: FnMut(&mut T) -> K,
K: PartialEq,
{
self.dedup_by(|a, b| key(a) == key(b))
}
pub fn dedup_by<F>(&mut self, same_bucket: F)
where
F: FnMut(&mut T, &mut T) -> bool,
{
let len = {
let (dedup, _) = partition_dedup_by(self.as_mut_slice(), same_bucket);
dedup.len()
};
self.truncate(len);
}
#[allow(clippy::inline_always)]
#[inline(always)]
unsafe fn push_unchecked(&mut self, value: T) {
debug_assert!(self.len() < self.capacity());
ptr::write(self.buf.ptr().add(self.len), value);
self.len = self.len + 1;
}
#[inline]
pub fn push(&mut self, value: T) {
if self.len == self.buf.cap() {
self.reserve(1);
}
unsafe {
self.push_unchecked(value);
}
}
#[inline]
pub fn pop(&mut self) -> Option<T> {
if self.len == 0 {
None
} else {
unsafe {
self.len -= 1;
Some(ptr::read(self.as_ptr().add(self.len())))
}
}
}
#[inline]
pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
let last = self.last_mut()?;
if predicate(last) {
self.pop()
} else {
None
}
}
#[inline]
pub fn append(&mut self, other: &mut Self) {
unsafe {
self.append_elements(other.as_slice() as _);
other.set_len(0);
}
}
#[inline]
unsafe fn append_elements(&mut self, other: *const [T]) {
let count = (&(*other)).len();
self.reserve(count);
let len = self.len();
ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);
self.len += count;
}
pub fn drain<'a, R>(&'a mut self, range: R) -> Drain<'a, 'bump, T>
where
R: RangeBounds<usize>,
{
let len = self.len();
let start = match range.start_bound() {
Included(&n) => n,
Excluded(&n) => n + 1,
Unbounded => 0,
};
let end = match range.end_bound() {
Included(&n) => n + 1,
Excluded(&n) => n,
Unbounded => len,
};
assert!(start <= end);
assert!(end <= len);
unsafe {
self.set_len(start);
let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(start), end - start);
Drain {
tail_start: end,
tail_len: len - end,
iter: range_slice.iter(),
vec: NonNull::from(self),
}
}
}
#[inline]
pub fn clear(&mut self) {
self.truncate(0)
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn split_off(&mut self, at: usize) -> Self {
assert!(at <= self.len(), "`at` out of bounds");
let other_len = self.len - at;
let mut other = Vec::with_capacity_in(other_len, self.buf.bump());
unsafe {
self.set_len(at);
other.set_len(other_len);
ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len());
}
other
}
}
#[cfg(feature = "boxed")]
impl<'bump, T> Vec<'bump, T> {
pub fn into_boxed_slice(mut self) -> crate::boxed::Box<'bump, [T]> {
use crate::boxed::Box;
unsafe {
let slice = slice::from_raw_parts_mut(self.as_mut_ptr(), self.len);
let output: Box<'bump, [T]> = Box::from_raw(slice);
mem::forget(self);
output
}
}
}
impl<'bump, T: 'bump + Clone> Vec<'bump, T> {
pub fn resize(&mut self, new_len: usize, value: T) {
let len = self.len();
if new_len > len {
self.extend_with(new_len - len, ExtendElement(value))
} else {
self.truncate(new_len);
}
}
#[inline]
unsafe fn extend_from_slice_unchecked(&mut self, slice: &[T]) {
debug_assert!(
core::mem::size_of::<T>() == 0 || self.capacity() >= self.len() + slice.len()
);
debug_assert!(
core::mem::size_of::<T>() != 0
|| self.len() <= usize::MAX - slice.len()
);
let mut pos = 0usize;
loop
{
if pos == slice.len() {
return;
}
let elem = slice.get_unchecked(pos);
self.push_unchecked(elem.clone());
pos = pos + 1;
}
}
pub fn extend_from_slice(&mut self, other: &[T]) {
let capacity = self.capacity();
let remaining_cap = capacity - self.len;
if other.len() > remaining_cap {
self.reserve(other.len());
}
unsafe {
self.extend_from_slice_unchecked(other);
}
}
}
impl<'bump, T: 'bump + Copy> Vec<'bump, T> {
unsafe fn extend_from_slice_copy_unchecked(&mut self, other: &[T]) {
let old_len = self.len();
debug_assert!(old_len + other.len() <= self.capacity());
unsafe {
let src = other.as_ptr();
let dst = self.as_mut_ptr().add(old_len);
ptr::copy_nonoverlapping(src, dst, other.len());
self.set_len(old_len + other.len());
}
}
pub fn extend_from_slice_copy(&mut self, other: &[T]) {
self.reserve(other.len());
unsafe {
self.extend_from_slice_copy_unchecked(other);
}
}
pub fn extend_from_slices_copy(&mut self, slices: &[&[T]]) {
let capacity_to_reserve: usize = slices.iter().map(|slice| slice.len()).sum();
self.reserve(capacity_to_reserve);
unsafe {
slices.iter().for_each(|slice| {
self.extend_from_slice_copy_unchecked(slice);
});
}
}
}
trait ExtendWith<T> {
fn next(&mut self) -> T;
fn last(self) -> T;
}
struct ExtendElement<T>(T);
impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
fn next(&mut self) -> T {
self.0.clone()
}
fn last(self) -> T {
self.0
}
}
impl<'bump, T: 'bump> Vec<'bump, T> {
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
self.reserve(n);
unsafe {
let mut ptr = self.as_mut_ptr().add(self.len());
let mut local_len = SetLenOnDrop::new(&mut self.len);
for _ in 1..n {
ptr::write(ptr, value.next());
ptr = ptr.offset(1);
local_len.increment_len(1);
}
if n > 0 {
ptr::write(ptr, value.last());
local_len.increment_len(1);
}
}
}
}
struct SetLenOnDrop<'a> {
len: &'a mut usize,
local_len: usize,
}
impl<'a> SetLenOnDrop<'a> {
#[inline]
fn new(len: &'a mut usize) -> Self {
SetLenOnDrop {
local_len: *len,
len,
}
}
#[inline]
fn increment_len(&mut self, increment: usize) {
self.local_len += increment;
}
#[inline]
fn decrement_len(&mut self, decrement: usize) {
self.local_len -= decrement;
}
}
impl<'a> Drop for SetLenOnDrop<'a> {
#[inline]
fn drop(&mut self) {
*self.len = self.local_len;
}
}
impl<'bump, T: 'bump + PartialEq> Vec<'bump, T> {
#[inline]
pub fn dedup(&mut self) {
self.dedup_by(|a, b| a == b)
}
}
impl<'bump, T: 'bump + Clone> Clone for Vec<'bump, T> {
#[cfg(not(test))]
fn clone(&self) -> Vec<'bump, T> {
let mut v = Vec::with_capacity_in(self.len(), self.buf.bump());
v.extend(self.iter().cloned());
v
}
#[cfg(test)]
fn clone(&self) -> Vec<'bump, T> {
let mut v = Vec::new_in(self.buf.bump());
v.extend(self.iter().cloned());
v
}
}
impl<'bump, T: 'bump + Hash> Hash for Vec<'bump, T> {
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
Hash::hash(&**self, state)
}
}
impl<'bump, T, I> Index<I> for Vec<'bump, T>
where
I: ::core::slice::SliceIndex<[T]>,
{
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
Index::index(&**self, index)
}
}
impl<'bump, T, I> IndexMut<I> for Vec<'bump, T>
where
I: ::core::slice::SliceIndex<[T]>,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(&mut **self, index)
}
}
impl<'bump, T: 'bump> ops::Deref for Vec<'bump, T> {
type Target = [T];
fn deref(&self) -> &[T] {
unsafe {
let p = self.buf.ptr();
slice::from_raw_parts(p, self.len)
}
}
}
impl<'bump, T: 'bump> ops::DerefMut for Vec<'bump, T> {
fn deref_mut(&mut self) -> &mut [T] {
unsafe {
let ptr = self.buf.ptr();
slice::from_raw_parts_mut(ptr, self.len)
}
}
}
impl<'bump, T: 'bump> IntoIterator for Vec<'bump, T> {
type Item = T;
type IntoIter = IntoIter<'bump, T>;
#[inline]
fn into_iter(mut self) -> IntoIter<'bump, T> {
unsafe {
let begin = self.as_mut_ptr();
let end = if mem::size_of::<T>() == 0 {
arith_offset(begin as *const i8, self.len() as isize) as *const T
} else {
begin.add(self.len()) as *const T
};
mem::forget(self);
IntoIter {
phantom: PhantomData,
ptr: begin,
end,
}
}
}
}
impl<'a, 'bump, T> IntoIterator for &'a Vec<'bump, T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> slice::Iter<'a, T> {
self.iter()
}
}
impl<'a, 'bump, T> IntoIterator for &'a mut Vec<'bump, T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> slice::IterMut<'a, T> {
self.iter_mut()
}
}
impl<'bump, T: 'bump> Extend<T> for Vec<'bump, T> {
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let iter = iter.into_iter();
self.reserve(iter.size_hint().0);
for t in iter {
self.push(t);
}
}
}
impl<'bump, T: 'bump> Vec<'bump, T> {
#[inline]
pub fn splice<'a, R, I>(
&'a mut self,
range: R,
replace_with: I,
) -> Splice<'a, 'bump, I::IntoIter>
where
R: RangeBounds<usize>,
I: IntoIterator<Item = T>,
{
Splice {
drain: self.drain(range),
replace_with: replace_with.into_iter(),
}
}
}
impl<'a, 'bump, T: 'a + Copy> Extend<&'a T> for Vec<'bump, T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned())
}
}
macro_rules! __impl_slice_eq1 {
($Lhs: ty, $Rhs: ty) => {
__impl_slice_eq1! { $Lhs, $Rhs, Sized }
};
($Lhs: ty, $Rhs: ty, $Bound: ident) => {
impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs
where
A: PartialEq<B>,
{
#[inline]
fn eq(&self, other: &$Rhs) -> bool {
self[..] == other[..]
}
}
};
}
__impl_slice_eq1! { Vec<'a, A>, Vec<'b, B> }
__impl_slice_eq1! { Vec<'a, A>, &'b [B] }
__impl_slice_eq1! { Vec<'a, A>, &'b mut [B] }
macro_rules! __impl_slice_eq1_array {
($Lhs: ty, $Rhs: ty) => {
impl<'a, 'b, A, B, const N: usize> PartialEq<$Rhs> for $Lhs
where
A: PartialEq<B>,
{
#[inline]
fn eq(&self, other: &$Rhs) -> bool {
self[..] == other[..]
}
}
};
}
__impl_slice_eq1_array! { Vec<'a, A>, [B; N] }
__impl_slice_eq1_array! { Vec<'a, A>, &'b [B; N] }
__impl_slice_eq1_array! { Vec<'a, A>, &'b mut [B; N] }
impl<'bump, T: 'bump + PartialOrd> PartialOrd for Vec<'bump, T> {
#[inline]
fn partial_cmp(&self, other: &Vec<'bump, T>) -> Option<Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}
}
impl<'bump, T: 'bump + Eq> Eq for Vec<'bump, T> {}
impl<'bump, T: 'bump + Ord> Ord for Vec<'bump, T> {
#[inline]
fn cmp(&self, other: &Vec<'bump, T>) -> Ordering {
Ord::cmp(&**self, &**other)
}
}
impl<'bump, T: 'bump + fmt::Debug> fmt::Debug for Vec<'bump, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<'bump, T: 'bump> AsRef<Vec<'bump, T>> for Vec<'bump, T> {
fn as_ref(&self) -> &Vec<'bump, T> {
self
}
}
impl<'bump, T: 'bump> AsMut<Vec<'bump, T>> for Vec<'bump, T> {
fn as_mut(&mut self) -> &mut Vec<'bump, T> {
self
}
}
impl<'bump, T: 'bump> AsRef<[T]> for Vec<'bump, T> {
fn as_ref(&self) -> &[T] {
self
}
}
impl<'bump, T: 'bump> AsMut<[T]> for Vec<'bump, T> {
fn as_mut(&mut self) -> &mut [T] {
self
}
}
#[cfg(feature = "boxed")]
impl<'bump, T: 'bump> From<Vec<'bump, T>> for crate::boxed::Box<'bump, [T]> {
fn from(v: Vec<'bump, T>) -> crate::boxed::Box<'bump, [T]> {
v.into_boxed_slice()
}
}
impl<'bump, T: 'bump> Borrow<[T]> for Vec<'bump, T> {
#[inline]
fn borrow(&self) -> &[T] {
&self[..]
}
}
impl<'bump, T: 'bump> BorrowMut<[T]> for Vec<'bump, T> {
#[inline]
fn borrow_mut(&mut self) -> &mut [T] {
&mut self[..]
}
}
impl<'bump, T> Drop for Vec<'bump, T> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len))
}
}
}
pub struct IntoIter<'bump, T> {
phantom: PhantomData<&'bump [T]>,
ptr: *const T,
end: *const T,
}
impl<'bump, T: fmt::Debug> fmt::Debug for IntoIter<'bump, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
}
}
impl<'bump, T: 'bump> IntoIter<'bump, T> {
pub fn as_slice(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.ptr, self.len()) }
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self.ptr as *mut T, self.len()) }
}
}
unsafe impl<'bump, T: Send> Send for IntoIter<'bump, T> {}
unsafe impl<'bump, T: Sync> Sync for IntoIter<'bump, T> {}
impl<'bump, T: 'bump> Iterator for IntoIter<'bump, T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<T> {
unsafe {
if self.ptr as *const _ == self.end {
None
} else if mem::size_of::<T>() == 0 {
self.ptr = arith_offset(self.ptr as *const i8, 1) as *mut T;
Some(mem::zeroed())
} else {
let old = self.ptr;
self.ptr = self.ptr.offset(1);
Some(ptr::read(old))
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let exact = if mem::size_of::<T>() == 0 {
(self.end as usize).wrapping_sub(self.ptr as usize)
} else {
unsafe { offset_from(self.end, self.ptr) as usize }
};
(exact, Some(exact))
}
#[inline]
fn count(self) -> usize {
self.len()
}
}
impl<'bump, T: 'bump> DoubleEndedIterator for IntoIter<'bump, T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
unsafe {
if self.end == self.ptr {
None
} else if mem::size_of::<T>() == 0 {
self.end = arith_offset(self.end as *const i8, -1) as *mut T;
Some(mem::zeroed())
} else {
self.end = self.end.offset(-1);
Some(ptr::read(self.end))
}
}
}
}
impl<'bump, T: 'bump> ExactSizeIterator for IntoIter<'bump, T> {}
impl<'bump, T: 'bump> FusedIterator for IntoIter<'bump, T> {}
impl<'bump, T> Drop for IntoIter<'bump, T> {
fn drop(&mut self) {
self.for_each(drop);
}
}
pub struct Drain<'a, 'bump, T: 'a + 'bump> {
tail_start: usize,
tail_len: usize,
iter: slice::Iter<'a, T>,
vec: NonNull<Vec<'bump, T>>,
}
impl<'a, 'bump, T: 'a + 'bump + fmt::Debug> fmt::Debug for Drain<'a, 'bump, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
}
}
unsafe impl<'a, 'bump, T: Sync> Sync for Drain<'a, 'bump, T> {}
unsafe impl<'a, 'bump, T: Send> Send for Drain<'a, 'bump, T> {}
impl<'a, 'bump, T> Iterator for Drain<'a, 'bump, T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<T> {
self.iter
.next()
.map(|elt| unsafe { ptr::read(elt as *const _) })
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, 'bump, T> DoubleEndedIterator for Drain<'a, 'bump, T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
self.iter
.next_back()
.map(|elt| unsafe { ptr::read(elt as *const _) })
}
}
impl<'a, 'bump, T> Drop for Drain<'a, 'bump, T> {
fn drop(&mut self) {
self.for_each(drop);
if self.tail_len > 0 {
unsafe {
let source_vec = self.vec.as_mut();
let start = source_vec.len();
let tail = self.tail_start;
if tail != start {
let src = source_vec.as_ptr().add(tail);
let dst = source_vec.as_mut_ptr().add(start);
ptr::copy(src, dst, self.tail_len);
}
source_vec.set_len(start + self.tail_len);
}
}
}
}
impl<'a, 'bump, T> ExactSizeIterator for Drain<'a, 'bump, T> {}
impl<'a, 'bump, T> FusedIterator for Drain<'a, 'bump, T> {}
#[derive(Debug)]
pub struct Splice<'a, 'bump, I>
where
I: Iterator,
I::Item: 'a + 'bump,
{
drain: Drain<'a, 'bump, I::Item>,
replace_with: I,
}
impl<'a, 'bump, I: Iterator> Iterator for Splice<'a, 'bump, I> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
self.drain.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.drain.size_hint()
}
}
impl<'a, 'bump, I: Iterator> DoubleEndedIterator for Splice<'a, 'bump, I> {
fn next_back(&mut self) -> Option<Self::Item> {
self.drain.next_back()
}
}
impl<'a, 'bump, I: Iterator> ExactSizeIterator for Splice<'a, 'bump, I> {}
impl<'a, 'bump, I: Iterator> Drop for Splice<'a, 'bump, I> {
fn drop(&mut self) {
self.drain.by_ref().for_each(drop);
unsafe {
if self.drain.tail_len == 0 {
self.drain.vec.as_mut().extend(self.replace_with.by_ref());
return;
}
if !self.drain.fill(&mut self.replace_with) {
return;
}
let (lower_bound, _upper_bound) = self.replace_with.size_hint();
if lower_bound > 0 {
self.drain.move_tail(lower_bound);
if !self.drain.fill(&mut self.replace_with) {
return;
}
}
let mut collected = Vec::new_in(self.drain.vec.as_ref().buf.bump());
collected.extend(self.replace_with.by_ref());
let mut collected = collected.into_iter();
if collected.len() > 0 {
self.drain.move_tail(collected.len());
let filled = self.drain.fill(&mut collected);
debug_assert!(filled);
debug_assert_eq!(collected.len(), 0);
}
}
}
}
impl<'a, 'bump, T> Drain<'a, 'bump, T> {
unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
let vec = self.vec.as_mut();
let range_start = vec.len;
let range_end = self.tail_start;
let range_slice =
slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start);
for place in range_slice {
if let Some(new_item) = replace_with.next() {
ptr::write(place, new_item);
vec.len += 1;
} else {
return false;
}
}
true
}
unsafe fn move_tail(&mut self, extra_capacity: usize) {
let vec = self.vec.as_mut();
let used_capacity = self.tail_start + self.tail_len;
vec.buf.reserve(used_capacity, extra_capacity);
let new_tail_start = self.tail_start + extra_capacity;
let src = vec.as_ptr().add(self.tail_start);
let dst = vec.as_mut_ptr().add(new_tail_start);
ptr::copy(src, dst, self.tail_len);
self.tail_start = new_tail_start;
}
}
#[derive(Debug)]
pub struct DrainFilter<'a, 'bump: 'a, T: 'a + 'bump, F>
where
F: FnMut(&mut T) -> bool,
{
vec: &'a mut Vec<'bump, T>,
idx: usize,
del: usize,
old_len: usize,
pred: F,
}
impl<'a, 'bump, T, F> Iterator for DrainFilter<'a, 'bump, T, F>
where
F: FnMut(&mut T) -> bool,
{
type Item = T;
fn next(&mut self) -> Option<T> {
unsafe {
while self.idx != self.old_len {
let i = self.idx;
self.idx += 1;
let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len);
if (self.pred)(&mut v[i]) {
self.del += 1;
return Some(ptr::read(&v[i]));
} else if self.del > 0 {
let del = self.del;
let src: *const T = &v[i];
let dst: *mut T = &mut v[i - del];
ptr::copy_nonoverlapping(src, dst, 1);
}
}
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.old_len - self.idx))
}
}
impl<'a, 'bump, T, F> Drop for DrainFilter<'a, 'bump, T, F>
where
F: FnMut(&mut T) -> bool,
{
fn drop(&mut self) {
self.for_each(drop);
unsafe {
self.vec.set_len(self.old_len - self.del);
}
}
}
#[cfg(feature = "std")]
impl<'bump> io::Write for Vec<'bump, u8> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.extend_from_slice_copy(buf);
Ok(buf.len())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.extend_from_slice_copy(buf);
Ok(())
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[cfg(feature = "serde")]
mod serialize {
use super::*;
use serde::{ser::SerializeSeq, Serialize, Serializer};
impl<'a, T> Serialize for Vec<'a, T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len))?;
for e in self.iter() {
seq.serialize_element(e)?;
}
seq.end()
}
}
}