1use core::{marker::Destruct, ops::Try};
2
3use array_trait::{length::{self, LengthValue}, same::Same};
4
5use crate::{Bulk, DoubleEndedBulk, IntoBulk, Step, range::BoundedRange};
6
7pub mod iter
8{
9 pub struct Bulk<T>
10 where
11 T: IntoIterator<IntoIter: ExactSizeIterator>
12 {
13 pub(super) iter: T::IntoIter
14 }
15}
16
17impl<T, A, I> iter::Bulk<T>
18where
19 T: IntoIterator<Item = A, IntoIter = I>,
20 I: ExactSizeIterator<Item = A>
21{
22 pub const fn by_ref(&mut self) -> &mut T::IntoIter
23 {
24 let Self { iter } = self;
25 iter
26 }
27}
28
29impl<T, A, I> IntoIterator for iter::Bulk<T>
30where
31 T: IntoIterator<Item = A, IntoIter = I>,
32 I: ExactSizeIterator<Item = A>
33{
34 type IntoIter = I;
35 type Item = A;
36
37 fn into_iter(self) -> Self::IntoIter
38 {
39 self.iter
40 }
41}
42
43impl<T, A, I> IntoBulk for T
44where
45 T: IntoIterator<Item = A, IntoIter = I>,
46 I: ExactSizeIterator<Item = A>
47{
48 default type IntoBulk = iter::Bulk<T>;
49
50 default fn into_bulk(self) -> Self::IntoBulk
51 {
52 iter::Bulk::<T> {
53 iter: self.into_iter()
54 }.same().ok().unwrap()
55 }
56}
57
58impl<T, A, I> Bulk for iter::Bulk<T>
59where
60 T: IntoIterator<Item = A, IntoIter = I>,
61 I: ExactSizeIterator<Item = A>
62{
63 #[inline]
64 default fn len(&self) -> usize
65 {
66 self.iter.len()
67 }
68 #[inline]
69 default fn is_empty(&self) -> bool
70 {
71 self.iter.is_empty()
72 }
73
74 #[inline]
75 default fn for_each<F>(self, f: F)
76 where
77 Self: Sized,
78 F: FnMut(Self::Item)
79 {
80 self.iter.for_each(f)
81 }
82 #[inline]
83 default fn try_for_each<F, R>(mut self, f: F) -> R
84 where
85 Self: Sized,
86 F: FnMut(Self::Item) -> R,
87 R: core::ops::Try<Output = ()>
88 {
89 self.iter.try_for_each(f)
90 }
91
92 default fn first(mut self) -> Option<Self::Item>
93 where
94 Self: Sized
95 {
96 self.iter.next()
97 }
98
99 default fn nth<L>(mut self, n: L) -> Option<Self::Item>
100 where
101 Self: Sized,
102 L: LengthValue
103 {
104 self.iter.nth(length::value::len(n))
105 }
106}
107impl<T, A, I> DoubleEndedBulk for iter::Bulk<T>
108where
109 T: IntoIterator<Item = A, IntoIter = I>,
110 I: ExactSizeIterator<Item = A> + DoubleEndedIterator
111{
112 fn rev_for_each<F>(self, f: F)
113 where
114 Self: Sized,
115 F: FnMut(Self::Item)
116 {
117 self.iter.rev().for_each(f);
118 }
119 fn try_rev_for_each<F, R>(self, f: F) -> R
120 where
121 Self: Sized,
122 F: FnMut(Self::Item) -> R,
123 R: Try<Output = ()>
124 {
125 self.iter.rev().try_for_each(f)
126 }
127}
128
129impl<R> const Bulk for iter::Bulk<R>
130where
131 R: ~const BoundedRange<R::Item> + ExactSizeIterator<Item: Copy + ~const Step> + ~const Destruct,
132{
133 fn len(&self) -> usize
134 {
135 self.iter.steps().0
136 }
137 fn first(self) -> Option<Self::Item>
138 where
139 Self: Sized
140 {
141 if !self.is_empty()
142 {
143 return Some(*self.iter.start())
144 }
145 None
146 }
147 fn for_each<F>(self, mut f: F)
148 where
149 Self: Sized,
150 F: ~const FnMut(Self::Item) + ~const Destruct
151 {
152 let Self { iter } = self;
153 let inclusive = iter.inclusive();
154 let mut range = *iter.start()..*iter.end();
155 loop
156 {
157 let n = Step::steps_between(&range.start, &range.end).0;
158 if n == 0
159 {
160 if inclusive
161 {
162 f(range.start)
163 }
164 break
165 }
166
167 f(range.start);
168 range.start = Step::forward(range.start, 1);
169 }
170 }
171 fn try_for_each<F, RR>(self, mut f: F) -> RR
172 where
173 Self: Sized,
174 F: ~const FnMut(Self::Item) -> RR + ~const Destruct,
175 RR: ~const Try<Output = ()>
176 {
177 let Self { iter } = self;
178 let inclusive = iter.inclusive();
179 let mut range = *iter.start()..*iter.end();
180 loop
181 {
182 let n = Step::steps_between(&range.start, &range.end).0;
183 if n == 0
184 {
185 if inclusive
186 {
187 f(range.start)?
188 }
189 break RR::from_output(())
190 }
191
192 f(range.start)?;
193 range.start = Step::forward(range.start, 1);
194 }
195 }
196}
197
198#[cfg(test)]
199mod test
200{
201 use crate::{Bulk, IntoBulk};
202
203 #[test]
204 fn vec()
205 {
206 let a = vec![1i32, 2, 3, 4, 5];
207
208 let bulk = a.into_bulk().map(|x| x as f64);
209
210 let b: Vec<f64> = bulk.collect();
211
212 println!("{b:?}")
213 }
214}