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