1#![no_std]
2#![doc = include_str!("../README.md")]
3
4extern crate alloc;
5
6use core::ops::{Deref, DerefMut};
7
8use alloc::{vec, vec::Vec};
9
10#[derive(Debug, Clone)]
12pub struct VecIter<I: Iterator> {
13 iter: I,
14 collected: Vec<I::Item>,
15}
16
17impl<I: Iterator> Deref for VecIter<I> {
18 type Target = [I::Item];
19
20 fn deref(&self) -> &Self::Target {
21 &self.collected
22 }
23}
24
25impl<I: Iterator> DerefMut for VecIter<I> {
26 fn deref_mut(&mut self) -> &mut Self::Target {
27 &mut self.collected
28 }
29}
30
31impl<I: Iterator> Iterator for VecIter<I>
32where I::Item: Clone,
33{
34 type Item = I::Item;
35
36 fn next(&mut self) -> Option<Self::Item> {
37 let elem = self.iter.next()?;
38 self.init_capacity_push(elem.clone());
39 Some(elem)
40 }
41
42 fn nth(&mut self, n: usize) -> Option<Self::Item> {
43 let elem = self.iter.next()?;
44 self.init_capacity_push(elem);
45 for _ in 1..n {
46 self.collected.push(self.iter.next()?);
47 }
48 self.next()
49 }
50
51 fn size_hint(&self) -> (usize, Option<usize>) {
52 let (lo, hi) = self.iter.size_hint();
53 (lo+self.collected_len(), hi.map(|hi| hi+self.collected_len()))
54 }
55
56 fn fold<B, F>(self, init: B, f: F) -> B
57 where Self: Sized,
58 F: FnMut(B, Self::Item) -> B,
59 {
60 self.collected.into_iter().chain(self.iter).fold(init, f)
61 }
62}
63
64impl<I: Iterator> VecIter<I>
65where I::Item: Clone,
66{
67 fn init_capacity(&mut self) {
68 if self.collected_len() == 0 {
69 self.collected.reserve(self.size_hint().0);
70 }
71 }
72
73 fn init_capacity_push(&mut self, value: I::Item) {
74 if self.collected_len() == 0 {
75 self.collected.reserve(self.size_hint().0+1);
76 }
77 self.collected.push(value);
78 }
79
80 fn require(&mut self, i: usize) -> Option<&mut I::Item> {
81 self.init_capacity();
82 let n = i.saturating_sub(self.collected_len())+1;
83 self.collected.extend(self.iter.by_ref().take(n));
84 self.collected.get_mut(i)
85 }
86
87 #[inline]
88 pub fn collected_len(&self) -> usize {
89 self.collected.len()
90 }
91
92 pub fn get_req(&mut self, i: usize) -> Option<&I::Item> {
94 self.require(i).map(|value| &*value)
95 }
96
97 pub fn get_req_mut(&mut self, i: usize) -> Option<&mut I::Item> {
99 self.require(i)
100 }
101
102 pub fn get_req_cloned(&mut self, i: usize) -> Option<I::Item> {
104 self.require(i).cloned()
105 }
106
107 pub fn into_all_collected(mut self) -> Vec<I::Item> {
109 self.collected.extend(self.iter);
110 self.collected
111 }
112}
113
114impl<I: Iterator + Default> Default for VecIter<I> {
115 fn default() -> Self {
116 Self {
117 iter: I::default(),
118 collected: vec![],
119 }
120 }
121}
122
123#[doc = include_str!("../README.md")]
124pub trait IterVecIterExt: Iterator + Sized {
125 fn vec_iter(self) -> VecIter<Self> {
126 VecIter { iter: self, collected: vec![] }
127 }
128}
129impl<I: Iterator> IterVecIterExt for I { }
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn basic_each() {
137 assert_eq!((0..5).vec_iter().collect::<Vec<_>>(), vec![0, 1, 2, 3, 4]);
138 assert_eq!((0..0).vec_iter().collect::<Vec<_>>(), vec![]);
139 }
140
141 #[test]
142 fn capacity() {
143 let mut iter = (0..5).vec_iter();
144 assert_eq!(iter.collected.capacity(), 0);
145 assert_eq!(iter.next(), Some(0));
146 assert_eq!(iter.collected.capacity(), 5);
147 assert_eq!(iter.collected_len(), 1);
148 }
149
150 #[test]
151 fn nth() {
152 let mut iter = (0..5).vec_iter();
153 assert_eq!(iter.collected.capacity(), 0);
154 assert_eq!(iter.nth(2), Some(2));
155 assert_eq!(iter.collected.capacity(), 5);
156 assert_eq!(*iter, [0, 1, 2]);
157 assert_eq!(iter.next(), Some(3));
158 }
159
160 #[test]
161 fn into_all_collected() {
162 let mut iter = (0..5).vec_iter();
163 assert_eq!(iter.collected.capacity(), 0);
164 assert_eq!(iter.next(), Some(0));
165 assert_eq!(iter.collected.capacity(), 5);
166 assert_eq!(iter.collected_len(), 1);
167 assert_eq!(iter.into_all_collected(), vec![0, 1, 2, 3, 4]);
168 }
169
170 #[test]
171 fn get_req() {
172 let mut iter = (0..5).vec_iter();
173 assert_eq!(iter.collected.capacity(), 0);
174 assert_eq!(iter.get_req_cloned(2), Some(2));
175 assert_eq!(iter.collected.capacity(), 5);
176 assert_eq!(iter.collected_len(), 3);
177 assert_eq!(iter.into_all_collected(), vec![0, 1, 2, 3, 4]);
178 }
179}