bulks/adapters/
contained.rs1use crate::Bulk;
2use crate::DoubleEndedBulk;
3use crate::IntoBulk;
4
5use array_trait::length;
6use array_trait::length::LengthValue;
7pub(crate) use private::IntoContained as IntoContained;
8#[allow(unused)]
9pub(crate) use private::IntoContainedIter as IntoContainedIter;
10pub(crate) use private::ContainedIntoIter as ContainedIntoIter;
11
12pub struct Contained<I>
13where
14 I: Iterator
15{
16 iter: I
17}
18
19impl<I> Iterator for Contained<I>
20where
21 I: Iterator
22{
23 type Item = I::Item;
24
25 fn next(&mut self) -> Option<Self::Item>
26 {
27 self.iter.next()
28 }
29}
30impl<I> ExactSizeIterator for Contained<I>
31where
32 I: Iterator
33{
34 fn len(&self) -> usize
35 {
36 Bulk::len(self)
37 }
38 fn is_empty(&self) -> bool
39 {
40 Bulk::is_empty(self)
41 }
42}
43impl<I> DoubleEndedIterator for Contained<I>
44where
45 I: DoubleEndedIterator
46{
47 fn next_back(&mut self) -> Option<Self::Item>
48 {
49 self.iter.next_back()
50 }
51}
52
53impl<I> Contained<I>
54where
55 I: Iterator
56{
57 pub(crate) const unsafe fn new(iter: I) -> Self
63 {
64 Self {
65 iter
66 }
67 }
68}
69
70impl<I> Bulk for Contained<I>
71where
72 I: Iterator
73{
74 default type MinLength = <I as private::InfiniteSpec>::Length;
75 default type MaxLength = <I as private::InfiniteSpec>::Length;
76
77 #[inline]
78 default fn len(&self) -> usize
79 {
80 self.iter.size_hint().1.unwrap_or(usize::MAX)
81 }
82
83 #[inline]
84 default fn is_empty(&self) -> bool
85 {
86 Bulk::len(self) == 0
87 }
88
89 fn first(mut self) -> Option<Self::Item>
90 where
91 Self: Sized
92 {
93 self.iter.next()
94 }
95 fn last(self) -> Option<Self::Item>
96 where
97 Self: Sized
98 {
99 self.iter.last()
100 }
101 fn nth<L>(mut self, n: L) -> Option<Self::Item>
102 where
103 Self: Sized,
104 L: LengthValue
105 {
106 self.iter.nth(length::value::len(n))
107 }
108
109 #[inline]
110 default fn for_each<F>(self, _f: F)
111 where
112 Self: Sized,
113 F: FnMut(Self::Item)
114 {
115 panic!("Possibly infinite iterator.")
116 }
117
118 #[inline]
119 default fn try_for_each<F, R>(self, _f: F) -> R
120 where
121 Self: Sized,
122 F: FnMut(Self::Item) -> R,
123 R: core::ops::Try<Output = ()>
124 {
125 panic!("Possibly infinite iterator.")
126 }
127}
128impl<I> Bulk for Contained<I>
129where
130 I: ExactSizeIterator
131{
132 type MinLength = <I as private::InfiniteSpec>::Length;
133 type MaxLength = <I as private::InfiniteSpec>::Length;
134
135 #[inline]
136 fn len(&self) -> usize
137 {
138 self.iter.len()
139 }
140
141 #[inline]
142 fn is_empty(&self) -> bool
143 {
144 self.iter.is_empty()
145 }
146
147 #[inline]
148 fn for_each<F>(self, f: F)
149 where
150 Self: Sized,
151 F: FnMut(Self::Item)
152 {
153 self.iter.for_each(f);
154 }
155
156 #[inline]
157 fn try_for_each<F, R>(mut self, f: F) -> R
158 where
159 Self: Sized,
160 F: FnMut(Self::Item) -> R,
161 R: core::ops::Try<Output = ()>
162 {
163 self.iter.try_for_each(f)
164 }
165}
166impl<I> DoubleEndedBulk for Contained<I>
167where
168 I: DoubleEndedIterator
169{
170 #[inline]
171 default fn rev_for_each<F>(self, _f: F)
172 where
173 Self: Sized,
174 F: FnMut(Self::Item)
175 {
176 panic!("Possibly infinite iterator.")
177 }
178
179 #[inline]
180 default fn try_rev_for_each<F, R>(self, _f: F) -> R
181 where
182 Self: Sized,
183 F: FnMut(Self::Item) -> R,
184 R: core::ops::Try<Output = ()>
185 {
186 panic!("Possibly infinite iterator.")
187 }
188}
189impl<I> DoubleEndedBulk for Contained<I>
190where
191 I: DoubleEndedIterator + ExactSizeIterator
192{
193 #[inline]
194 fn rev_for_each<F>(self, f: F)
195 where
196 Self: Sized,
197 F: FnMut(Self::Item)
198 {
199 self.iter.rev().for_each(f);
200 }
201
202 #[inline]
203 fn try_rev_for_each<F, R>(self, f: F) -> R
204 where
205 Self: Sized,
206 F: FnMut(Self::Item) -> R,
207 R: core::ops::Try<Output = ()>
208 {
209 self.iter.rev().try_for_each(f)
210 }
211}
212
213mod private
214{
215 use array_trait::{length::Length, same::Same};
216
217 use crate::{Contained, IntoBulk, util::InfiniteIterator};
218
219 pub trait InfiniteSpec
220 {
221 type Length: Length<Elem = ()> + ?Sized;
222 }
223 impl<I> InfiniteSpec for I
224 {
225 default type Length = [()];
226 }
227 impl<I> InfiniteSpec for I
228 where
229 I: InfiniteIterator
230 {
231 type Length = [(); usize::MAX];
232 }
233
234 #[allow(unused)]
240 pub unsafe trait IntoContainedIter: IntoIterator
241 {
242 type IntoContainedIter: ExactSizeIterator<Item = Self::Item>;
243
244 unsafe fn into_contained_iter(self) -> Self::IntoContainedIter;
250 }
251 unsafe impl<T> IntoContainedIter for T
252 where
253 T: IntoIterator
254 {
255 default type IntoContainedIter = Contained<T::IntoIter>;
256
257 default unsafe fn into_contained_iter(self) -> Self::IntoContainedIter
258 {
259 unsafe {
260 Contained::new(self.into_iter()).same().ok().unwrap()
261 }
262 }
263 }
264 unsafe impl<T> IntoContainedIter for T
265 where
266 T: IntoIterator<IntoIter: ExactSizeIterator>
267 {
268 type IntoContainedIter = T::IntoIter;
269
270 unsafe fn into_contained_iter(self) -> Self::IntoContainedIter
271 {
272 self.into_iter()
273 }
274 }
275
276 pub const unsafe trait IntoContained: IntoIterator
282 {
283 type IntoContained: ~const IntoBulk<Item = Self::Item, IntoIter: ExactSizeIterator<Item = Self::Item>>;
284
285 unsafe fn into_contained(self) -> Self::IntoContained;
291 }
292 unsafe impl<T> IntoContained for T
293 where
294 T: IntoIterator
295 {
296 default type IntoContained = Contained<T::IntoIter>;
297
298 default unsafe fn into_contained(self) -> Self::IntoContained
299 {
300 unsafe {
301 Contained::new(self.into_iter()).same().ok().unwrap()
302 }
303 }
304 }
305 unsafe impl<T> const IntoContained for T
306 where
307 T: ~const IntoBulk
308 {
309 type IntoContained = T;
310
311 unsafe fn into_contained(self) -> Self::IntoContained
312 {
313 self
314 }
315 }
316
317 pub unsafe trait ContainedIntoIter: IntoIterator<IntoIter: ExactSizeIterator>
323 {
324 type ContainedIntoIter: Iterator<Item = Self::Item>;
325
326 unsafe fn contained_into_iter(self) -> Self::ContainedIntoIter;
327 }
328 unsafe impl<T> ContainedIntoIter for T
329 where
330 T: IntoIterator<IntoIter: ExactSizeIterator>
331 {
332 default type ContainedIntoIter = T::IntoIter;
333
334 default unsafe fn contained_into_iter(self) -> Self::ContainedIntoIter
335 {
336 self.into_iter().same().ok().unwrap()
337 }
338 }
339 unsafe impl<I> ContainedIntoIter for Contained<I>
340 where
341 I: Iterator
342 {
343 type ContainedIntoIter = I;
344
345 unsafe fn contained_into_iter(self) -> Self::ContainedIntoIter
346 {
347 self.iter
348 }
349 }
350
351 pub trait EitherIntoBulk<B>: IntoIterator
352 where
353 B: IntoIterator
354 {
355 type EitherIntoBulk: IntoIterator;
356 }
357 impl<T, B> EitherIntoBulk<B> for T
358 where
359 T: IntoIterator,
360 B: IntoIterator
361 {
362 default type EitherIntoBulk = T;
363 }
364 impl<T, B> EitherIntoBulk<B> for T
365 where
366 T: IntoIterator,
367 B: IntoBulk
368 {
369 type EitherIntoBulk = B;
370 }
371}
372
373#[rustc_on_unimplemented(
374 message = "value of type `{Self}` cannot be zipped with `{B}` in bulk",
375 label = "neither `{Self}` nor `{B}` can be converted into bulks",
376)]
377pub trait EitherIntoBulk<B>: private::EitherIntoBulk<B, EitherIntoBulk: IntoBulk>
378where
379 B: IntoIterator
380{
381
382}
383impl<T, B> EitherIntoBulk<B> for T
384where
385 T: private::EitherIntoBulk<B, EitherIntoBulk: IntoBulk>,
386 B: IntoIterator
387{
388
389}
390
391#[rustc_on_unimplemented(
392 message = "value of type `{Self}` cannot be zipped with `{B}` in bulk",
393 label = "value of type `{Self}` cannot be zipped with `{B}` in bulk",
394)]
395pub const trait IntoContainedBy<B>: ~const IntoContained + EitherIntoBulk<B> + Sized
396where
397 B: IntoIterator
398{
399
400}
401impl<T, B> const IntoContainedBy<B> for T
402where
403 T: ~const IntoContained + EitherIntoBulk<B>,
404 B: IntoIterator
405{
406
407}