Skip to main content

bulks/adapters/
contained.rs

1use 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    /// # Safety
57    /// 
58    /// This creates a bulk that is possibly only invalid.
59    /// 
60    /// Always wrap this bulk in another bulk so that its length is limited.
61    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    /// # Safety
234    /// 
235    /// This creates an iterator that is possibly only invalid.
236    /// 
237    /// Always wrap this bulk in another bulk so that its length is limited.
238    #[allow(unused)]
239    pub unsafe trait IntoContainedIter: IntoIterator
240    {
241        type IntoContainedIter: ExactSizeIterator<Item = Self::Item>;
242
243        /// # Safety
244        /// 
245        /// This creates a bulk that is possibly only invalid.
246        /// 
247        /// Always wrap this bulk in another bulk so that its length is limited.
248        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    /// # Safety
276    /// 
277    /// This creates a bulk that is possibly only invalid.
278    /// 
279    /// Always wrap this bulk in another bulk so that its length is limited.
280    pub const unsafe trait IntoContained: IntoIterator
281    {
282        type IntoContained: ~const IntoBulk<Item = Self::Item, IntoIter: ExactSizeIterator<Item = Self::Item>>;
283
284        /// # Safety
285        /// 
286        /// This creates a bulk that is possibly only invalid.
287        /// 
288        /// Always wrap this bulk in another bulk so that its length is limited.
289        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}