use {
super::{
super::{
SmallVec,
allocator::{
Allocator,
global::Global,
proxy::Proxy
}
},
drain::Drain
},
core::fmt::{
Debug,
Formatter,
Result as Format
}
};
pub struct Splice<'valid, I: Iterator + 'valid, const INLINE: usize, Heap: Allocator = Global> {
drain: Drain<'valid, I::Item, INLINE, Heap>,
replace_with: I
}
impl<'valid, I: Iterator + 'valid, const INLINE: usize, Heap: Allocator>
Splice<'valid, I, INLINE, Heap>
{
pub(crate) fn new(drain: Drain<'valid, I::Item, INLINE, Heap>, replace_with: I) -> Self {
Self {
drain,
replace_with
}
}
}
impl<'valid, I, const INLINE: usize, Heap: Allocator> Debug for Splice<'valid, I, INLINE, Heap>
where
I: Debug + Iterator + 'valid,
<I as Iterator>::Item: Debug
{
fn fmt(&self, f: &mut Formatter<'_>) -> Format {
f.debug_tuple("Splice").field(&self.drain).finish()
}
}
impl<I: Iterator, const INLINE: usize, Heap: Allocator> Iterator for Splice<'_, I, INLINE, Heap> {
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<I: Iterator, const INLINE: usize, Heap: Allocator> DoubleEndedIterator
for Splice<'_, I, INLINE, Heap>
{
fn next_back(&mut self) -> Option<Self::Item> {
self.drain.next_back()
}
}
impl<I: Iterator, const INLINE: usize, Heap: Allocator> ExactSizeIterator
for Splice<'_, I, INLINE, Heap>
{
}
impl<I: Iterator, const INLINE: usize, Heap: Allocator> Drop for Splice<'_, I, INLINE, Heap> {
fn drop(&mut self) {
self.drain.by_ref().for_each(drop);
self.drain.iter = [].iter();
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 smallvec =
SmallVec::<_, INLINE, _>::new_in(Proxy(&self.drain.vec.as_ref().allocator));
smallvec.extend(self.replace_with.by_ref());
let mut collected = smallvec.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);
}
}
}
}