diff --git a/src/lib.rs b/src/lib.rs index eace3242a..0e79858b2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,7 +55,7 @@ extern crate core as std; extern crate alloc; #[cfg(feature = "use_alloc")] -use alloc::{string::String, vec::Vec}; +use alloc::{collections::VecDeque, string::String, vec::Vec}; pub use either::Either; @@ -72,6 +72,8 @@ use std::fmt::Write; use std::hash::Hash; use std::iter::{once, IntoIterator}; #[cfg(feature = "use_alloc")] +type VecDequeIntoIter = alloc::collections::vec_deque::IntoIter; +#[cfg(feature = "use_alloc")] type VecIntoIter = alloc::vec::IntoIter; use std::iter::FromIterator; @@ -3153,32 +3155,25 @@ pub trait Itertools: Iterator { /// `.rev().take(n).rev()` to have a similar result (lazy and non-allocating) /// without consuming the entire iterator. #[cfg(feature = "use_alloc")] - fn tail(self, n: usize) -> VecIntoIter + fn tail(self, n: usize) -> VecDequeIntoIter where Self: Sized, { match n { 0 => { self.last(); - Vec::new() + VecDeque::new() } 1 => self.last().into_iter().collect(), _ => { // Skip the starting part of iterator if possible. let (low, _) = self.size_hint(); let mut iter = self.fuse().skip(low.saturating_sub(n)); - let mut data: Vec<_> = iter.by_ref().take(n).collect(); - // Update `data` cyclically. - let idx = iter.fold(0, |i, val| { - data[i] = val; - if i + 1 == n { - 0 - } else { - i + 1 - } + let mut data: VecDeque<_> = iter.by_ref().take(n).collect(); + iter.for_each(|value| { + data.pop_front(); + data.push_back(value); }); - // Respect the insertion order. - data.rotate_left(idx); data } }