#[cfg(feature = "defmt")]
use defmt::{
Format as DeFormat,
Formatter as DeFormatter,
write as dewrite
};
use {
super::super::{
DropDealloc,
SmallVec,
locatedlength::LocatedLength,
rawsmallvec::RawSmallVec
},
alloc::alloc::Global,
core::{
alloc::Allocator,
fmt::{
Debug,
Formatter,
Result as Format
},
iter::FusedIterator,
ptr::{
NonNull,
slice_from_raw_parts_mut
},
slice::{
from_raw_parts,
from_raw_parts_mut
}
}
};
pub struct IntoIter<Item, const INLINE: usize, Heap: Allocator = Global> {
raw: RawSmallVec<Item, INLINE>,
allocator: Heap,
begin: usize,
end: LocatedLength<Item>
}
unsafe impl<Item: Send, const INLINE: usize, Heap: Allocator + Send> Send
for IntoIter<Item, INLINE, Heap>
{
}
unsafe impl<Item: Sync, const INLINE: usize, Heap: Allocator + Sync> Sync
for IntoIter<Item, INLINE, Heap>
{
}
impl<Item, const INLINE: usize, Heap: Allocator> AsRef<[Item]> for IntoIter<Item, INLINE, Heap> {
#[inline]
fn as_ref(&self) -> &[Item] {
let (end, spilled) = self.end.parts();
unsafe {
let pointer = self.raw.as_ptr(spilled);
from_raw_parts(pointer.add(self.begin), end - self.begin)
}
}
}
impl<Item, const INLINE: usize, Heap: Allocator> AsMut<[Item]> for IntoIter<Item, INLINE, Heap> {
#[inline]
fn as_mut(&mut self) -> &mut [Item] {
let (end, spilled) = self.end.parts();
unsafe {
let pointer = self.raw.as_mut_ptr(spilled);
from_raw_parts_mut(pointer.add(self.begin), end - self.begin)
}
}
}
impl<Item, const INLINE: usize, Heap: Allocator> IntoIter<Item, INLINE, Heap> {
#[deprecated(
since = "2.0.0-beta.3",
note = "use `<IntoIter<Item, INLINE, Heap> as AsRef<[Item]>>::as_ref` instead"
)]
#[inline]
pub fn as_slice(&self) -> &[Item] { self.as_ref() }
#[deprecated(
since = "2.0.0-beta.3",
note = "use `<IntoIter<Item, INLINE, Heap> as AsMut<[Item]>>::as_mut` instead"
)]
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [Item] { self.as_mut() }
#[cfg(feature = "specialization")]
pub(crate) fn mark_consumed(&mut self) { self.begin = self.end.len(); }
}
impl<Item, const INLINE: usize, Heap: Allocator> Iterator for IntoIter<Item, INLINE, Heap> {
type Item = Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let (end, spilled) = self.end.parts();
if self.begin == end {
None
} else {
unsafe {
let pointer = self.raw.as_mut_ptr(spilled);
let value = pointer.add(self.begin).read();
self.begin += 1;
Some(value)
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.end.len() - self.begin;
(size, Some(size))
}
}
impl<Item, const INLINE: usize, Heap: Allocator> DoubleEndedIterator
for IntoIter<Item, INLINE, Heap>
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let (end, spilled) = self.end.parts();
if self.begin == end {
None
} else {
unsafe {
let pointer = self.raw.as_mut_ptr(spilled);
self.end.sub(1);
let value = pointer.add(end - 1).read();
Some(value)
}
}
}
}
impl<Item, const INLINE: usize, Heap: Allocator> ExactSizeIterator
for IntoIter<Item, INLINE, Heap>
{
}
impl<Item, const INLINE: usize, Heap: Allocator> FusedIterator for IntoIter<Item, INLINE, Heap> {}
impl<Item, const INLINE: usize, Heap: Allocator> Drop for IntoIter<Item, INLINE, Heap> {
fn drop(&mut self) {
unsafe {
let (end, spilled) = self.end.parts();
let begin = self.begin;
let pointer = self.raw.as_mut_ptr(spilled);
let _drop_dealloc = if spilled {
let capacity = self.raw.heap.len();
Some(DropDealloc {
pointer: NonNull::new_unchecked(pointer as *mut u8),
size_bytes: capacity * size_of::<Item>(),
align: align_of::<Item>(),
allocator: &self.allocator
})
} else {
None
};
slice_from_raw_parts_mut(pointer.add(begin), end - begin).drop_in_place();
}
}
}
impl<Item: Clone, const INLINE: usize, Heap: Allocator + Clone> Clone
for IntoIter<Item, INLINE, Heap>
{
#[inline]
fn clone(&self) -> IntoIter<Item, INLINE, Heap> {
let mut vec = SmallVec {
length: LocatedLength::new(0, false),
raw: RawSmallVec::new(),
allocator: self.allocator.clone()
};
vec.extend(self.as_ref());
vec.into_iter()
}
}
impl<Item, const INLINE: usize, Heap: Allocator> IntoIterator for SmallVec<Item, INLINE, Heap> {
type IntoIter = IntoIter<Item, INLINE, Heap>;
type Item = Item;
fn into_iter(self) -> Self::IntoIter {
let (end, raw, allocator) = self.into();
IntoIter {
raw,
allocator,
begin: 0,
end
}
}
}
impl<Item: Debug, const INLINE: usize, Heap: Allocator> Debug for IntoIter<Item, INLINE, Heap> {
fn fmt(&self, f: &mut Formatter<'_>) -> Format {
f.debug_tuple("IntoIter").field(&self.as_ref()).finish()
}
}
#[cfg(feature = "defmt")]
impl<Item: DeFormat, const INLINE: usize, Heap: Allocator> DeFormat
for IntoIter<Item, INLINE, Heap>
{
fn format(&self, fmt: DeFormatter<'_>) {
dewrite!(fmt, "IntoIter({=[?]})", self.as_ref());
}
}