Skip to main content

bulks/
bulk.rs

1use core::{
2    borrow::BorrowMut, cmp::Ordering, error::Error, fmt::Display, future::Ready, iter::Step, marker::Destruct, ops::{Add, ControlFlow, Deref, FromResidual, Mul, Residual, Try}, pin::Pin
3};
4
5use array_trait::length::{self, Length, LengthValue, Value};
6
7use crate::{
8    ArrayChunks, Chain, Cloned, CollectionAdapter, CollectionStrategy, Copied, DoubleEndedBulk, Enumerate, EnumerateFrom, FlatMap, Flatten, FromBulk, Inspect,
9    Intersperse, IntersperseWith, IntoBulk, IntoContained, IntoContainedBy, Map, MapWindows, Merge, Mutate, Nearest, Pinned, Resize, ResizeWith, Rev, Skip, SplitBulk,
10    StaticBulk, StepBy, Take, TryCollectionStrategy, Unpinned, Zip, util
11};
12
13#[cfg(feature = "async")]
14use crate::{
15    AllAsync, AnyAsync, CollectArrayAsync, CollectAsync, FindMapAsync, ForEachAsync, PositionAsync, ReduceAsync, TryCollectArrayAsync, TryCollectAsync, TryForEachAsync, TryReduceAsync, util::BufferableBulk
16};
17
18pub type BulkLength<B> = <<B as Bulk>::MinLength as Length>::Intersect<<B as Bulk>::MaxLength>;
19
20//fn _assert_is_dyn_compatible(_: &dyn Bulk<Item = ()>) {}
21
22/// A trait for dealing with bulks.
23///
24/// This is the main bulk trait. For more about the concept of bulks
25/// generally, please see the [crate-level documentation](crate). In particular, you
26/// may want to know how to [implement `Bulk`][crate#implementing-bulk].
27#[rustc_on_unimplemented(
28    on(Self = "core::ops::range::RangeTo<Idx>", note = "you might have meant to use a bounded `Range`"),
29    on(Self = "core::ops::range::RangeToInclusive<Idx>", note = "you might have meant to use a bounded `RangeInclusive`"),
30    label = "`{Self}` is not a bulk",
31    message = "`{Self}` is not a bulk"
32)]
33#[doc(notable_trait)]
34#[must_use = "bulks are lazy and do nothing unless consumed"]
35pub const trait Bulk: [const] IntoBulk<IntoBulk = Self>
36{
37    type MinLength: Length<Elem = ()> + ?Sized = [(); 0];
38    type MaxLength: Length<Elem = ()> + ?Sized = [()];
39
40    /// Returns the exact length of the bulk.
41    ///
42    /// This function has the same safety guarantees as the
43    /// [`Iterator::size_hint`] function.
44    ///
45    /// Similar to [`ExactSizeIterator::len`].
46    ///
47    /// # Examples
48    ///
49    /// Basic usage:
50    ///
51    /// ```
52    /// use bulks::*;
53    ///
54    /// // a finite range knows exactly how many times it will iterate
55    /// let mut range = (0..5).into_bulk();
56    ///
57    /// let len = range.len();
58    ///
59    /// assert_eq!(len, 5);
60    /// ```
61    #[track_caller]
62    fn len(&self) -> usize;
63
64    fn length(&self) -> Value<BulkLength<Self>>
65    {
66        let len = self.len();
67        let length = length::value::or_len(len);
68        assert!(length::value::len(length) == len);
69        length
70    }
71
72    /// Returns `true` if the bulk is empty.
73    ///
74    /// This method has a default implementation using
75    /// [`Bulk::len()`], so you don't need to implement it yourself.
76    ///
77    /// Similar to [`ExactSizeIterator::is_empty`].
78    ///
79    /// # Examples
80    ///
81    /// Basic usage:
82    ///
83    /// ```
84    /// use bulks::*;
85    ///
86    /// let one_element = bulks::once(0);
87    /// assert!(!one_element.is_empty());
88    /// ```
89    #[inline]
90    #[track_caller]
91    fn is_empty(&self) -> bool
92    {
93        length::value::eq(self.length(), [(); 0])
94    }
95
96    /// Returns the first value, and discards the rest of the bulk.
97    ///
98    /// Returns [`None`] if the bulk is empty.
99    ///
100    /// # Examples
101    ///
102    /// ```
103    /// use bulks::*;
104    ///
105    /// let a = [1, 2, 3];
106    ///
107    /// let bulk = a.bulk();
108    ///
109    /// let a1 = bulk.first();
110    /// assert_eq!(a1, Some(&1));
111    /// ```
112    fn first(self) -> Option<Self::Item>
113    where
114        Self::Item: [const] Destruct,
115        Self: Sized
116    {
117        const fn break_on_first<T>(x: T) -> ControlFlow<T>
118        {
119            ControlFlow::Break(x)
120        }
121
122        match self.try_for_each(break_on_first)
123        {
124            ControlFlow::Break(first) => Some(first),
125            ControlFlow::Continue(()) => None
126        }
127    }
128
129    /// Returns the last value, and discards the rest of the bulk.
130    ///
131    /// Returns [`None`] if the bulk is empty.
132    ///
133    /// # Examples
134    ///
135    /// ```
136    /// use bulks::*;
137    ///
138    /// let a = [1, 2, 3];
139    ///
140    /// let bulk = a.bulk();
141    ///
142    /// let a1 = bulk.last();
143    /// assert_eq!(a1, Some(&3));
144    /// ```
145    fn last(self) -> Option<Self::Item>
146    where
147        Self::Item: [const] Destruct,
148        Self: Sized
149    {
150        const fn store<T>(_: T, x: T) -> T
151        where
152            T: [const] Destruct
153        {
154            x
155        }
156
157        self.reduce(store)
158    }
159
160    /// Returns the `n`-th value from the back, and discards the rest of the bulk.
161    ///
162    /// Returns [`None`] if index `n` is out of bounds.
163    ///
164    /// # Examples
165    ///
166    /// ```
167    /// use bulks::*;
168    ///
169    /// let a = [1, 2, 3];
170    ///
171    /// let bulk = a.bulk();
172    ///
173    /// // The bulk is consumed, so it must be cloned each time. Don't actually do this.
174    /// let a1 = bulk.clone().last();
175    /// let a2 = bulk.clone().nth_back(1);
176    /// let a3 = bulk.clone().nth_back(2);
177    /// let a4 = bulk.clone().nth_back(3);
178    ///
179    /// assert_eq!(a1, Some(&3));
180    /// assert_eq!(a2, Some(&2));
181    /// assert_eq!(a3, Some(&1));
182    /// assert_eq!(a4, None);
183    /// ```
184    fn nth_back<L>(self, n: L) -> Option<Self::Item>
185    where
186        Self: Sized + [const] DoubleEndedBulk,
187        Self::Item: [const] Destruct,
188        L: LengthValue
189    {
190        self.rev().skip(n).first()
191    }
192
193    /// Returns the `n`-th value, and discards the rest of the bulk.
194    ///
195    /// Returns [`None`] if index `n` is out of bounds.
196    ///
197    /// # Examples
198    ///
199    /// ```
200    /// use bulks::*;
201    ///
202    /// let a = [1, 2, 3];
203    ///
204    /// let bulk = a.bulk();
205    ///
206    /// // The bulk is consumed, so it must be cloned each time. Don't actually do this.
207    /// let a1 = bulk.clone().first();
208    /// let a2 = bulk.clone().nth(1);
209    /// let a3 = bulk.clone().nth(2);
210    /// let a4 = bulk.clone().nth(3);
211    ///
212    /// assert_eq!(a1, Some(&1));
213    /// assert_eq!(a2, Some(&2));
214    /// assert_eq!(a3, Some(&3));
215    /// assert_eq!(a4, None);
216    /// ```
217    fn nth<L>(self, n: L) -> Option<Self::Item>
218    where
219        Self: Sized,
220        Self::Item: [const] Destruct,
221        L: LengthValue
222    {
223        self.skip(n).first()
224    }
225
226    fn many<NN, const N: usize>(self, n: NN) -> [Option<Self::Item>; N]
227    where
228        Self: Sized,
229        Self::Item: [const] Destruct,
230        NN: [const] IntoBulk<Item = usize, IntoBulk: [const] Bulk + StaticBulk<Array<()> = [(); N]>>
231    {
232        struct Functor<'a, T, const N: usize>
233        {
234            done: usize,
235            refs: &'a mut [Result<T, usize>; N]
236        }
237        impl<'a, T, const N: usize> Functor<'a, T, N>
238        {
239            const fn update(&mut self, i: usize, x: T)
240            where
241                T: [const] Destruct
242            {
243                const trait ManySpec: Sized
244                {
245                    fn update<const N: usize>(refs: &mut [Result<Self, usize>; N], k: &mut usize, i: usize, x: Self);
246                }
247                const impl<T> ManySpec for T
248                where
249                    T: [const] Destruct
250                {
251                    default fn update<const N: usize>(refs: &mut [Result<Self, usize>; N], k: &mut usize, i: usize, x: Self)
252                    {
253                        while *k < N
254                        {
255                            if let Err(j) = &refs[*k]
256                            {
257                                if *j == i
258                                {
259                                    refs[*k] = Ok(x);
260                                    return;
261                                }
262                                else
263                                {
264                                    break;
265                                }
266                            }
267                            *k += 1
268                        }
269                        let mut n = *k;
270                        while n < N
271                        {
272                            if let Err(j) = &refs[n]
273                                && *j == i
274                            {
275                                refs[n] = Ok(x);
276                                return;
277                            }
278                            n += 1
279                        }
280                    }
281                }
282                const impl<T> ManySpec for T
283                where
284                    T: Copy + [const] Destruct
285                {
286                    fn update<const N: usize>(refs: &mut [Result<Self, usize>; N], k: &mut usize, i: usize, x: Self)
287                    {
288                        while *k < N
289                        {
290                            if let Err(j) = &refs[*k]
291                            {
292                                if *j == i { refs[*k] = Ok(x) } else { break }
293                            }
294                            *k += 1
295                        }
296                        let mut n = *k;
297                        while n < N
298                        {
299                            if let Err(j) = &refs[n]
300                                && *j == i
301                            {
302                                refs[n] = Ok(x)
303                            }
304                            n += 1
305                        }
306                    }
307                }
308
309                ManySpec::update(self.refs, &mut self.done, i, x);
310            }
311        }
312
313        const impl<'a, T, const N: usize> FnOnce<((usize, T),)> for Functor<'a, T, N>
314        where
315            T: [const] Destruct
316        {
317            type Output = ();
318
319            extern "rust-call" fn call_once(mut self, args: ((usize, T),)) -> Self::Output
320            {
321                self.call_mut(args)
322            }
323        }
324        const impl<'a, T, const N: usize> FnMut<((usize, T),)> for Functor<'a, T, N>
325        where
326            T: [const] Destruct
327        {
328            extern "rust-call" fn call_mut(&mut self, ((i, x),): ((usize, T),)) -> Self::Output
329            {
330                self.update(i, x);
331            }
332        }
333
334        let mut refs = n.into_bulk().map(Err).collect_array();
335
336        self.enumerate().for_each(Functor { done: 0, refs: &mut refs });
337
338        refs.map(Result::ok)
339    }
340
341    #[cfg(feature = "async")]
342    fn par(self) -> Map<Self, impl Fn(Self::Item) -> Ready<Self::Item>>
343    where
344        Self: Sized
345    {
346        self.map(core::future::ready)
347    }
348
349    /// Calls a closure on each element of a bulk.
350    ///
351    /// This is equivalent to using a [`for`] loop on the bulk, although
352    /// `break` and `continue` are not possible from a closure. It's generally
353    /// more idiomatic to use a `for` loop, but `for_each` may be more legible
354    /// when processing items at the end of longer iterator chains. In some
355    /// cases `for_each` may also be faster than a loop, because it will use
356    /// internal iteration on adapters like [`Chain`](crate::Chain).
357    ///
358    /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
359    ///
360    /// # Examples
361    ///
362    /// Basic usage:
363    ///
364    /// ```
365    /// use bulks::*;
366    ///
367    /// let a = [1, 2, 3, 4];
368    /// let mut x0 = 0;
369    /// a.into_bulk()
370    ///     .for_each(|x| {
371    ///         assert_eq!(x, x0 + 1);
372    ///         x0 = x;
373    ///     })
374    /// ```
375    fn for_each<F>(self, f: F)
376    where
377        Self: Sized,
378        F: [const] FnMut(Self::Item) + [const] Destruct;
379
380    /// Calls an asynchronous closure once on each element of a bulk
381    /// in an arbitrary execution order.
382    ///
383    /// # Examples
384    ///
385    /// Basic usage:
386    ///
387    /// ```
388    /// use bulks::*;
389    /// use core::time::Duration;
390    ///
391    /// let a = [1024, 512, 256];
392    ///
393    /// # tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async {
394    /// a.into_bulk()
395    ///     .for_each_async(async |n| {
396    ///         tokio::time::sleep(Duration::from_millis(n)).await;
397    ///     })
398    ///     .await
399    /// # })
400    /// ```
401    #[cfg(feature = "async")]
402    #[rustc_non_const_trait_method]
403    fn for_each_async<F>(self, f: F) -> ForEachAsync<Self, F>
404    where
405        Self: BufferableBulk + Sized,
406        F: FnMut<(Self::Item,), Output: Future<Output = ()>>
407    {
408        ForEachAsync::new(self, f)
409    }
410
411    /// A bulk method that applies a fallible function to each item in the
412    /// bulk, stopping at the first error and returning that error.
413    ///
414    /// This can also be thought of as the fallible form of [`for_each()`](Bulk::for_each)
415    /// or as the stateless version of [`try_fold()`](Bulk::try_fold).
416    ///
417    /// # Examples
418    ///
419    /// ```
420    /// use bulks::*;
421    ///
422    /// let a = ["1", "2", "3", "4", "wrong"];
423    /// let mut x0 = 0;
424    /// let res = a.into_bulk()
425    ///     .try_for_each(|x| {
426    ///         let x = x.parse::<u32>().map_err(|_| x)?;
427    ///         assert_eq!(x, x0 + 1);
428    ///         x0 = x;
429    ///         Ok(())
430    ///     });
431    /// assert_eq!(res, Err("wrong"))
432    /// ```
433    fn try_for_each<F, R>(self, f: F) -> R
434    where
435        Self: Sized,
436        Self::Item: [const] Destruct,
437        F: [const] FnMut(Self::Item) -> R + [const] Destruct,
438        R: [const] Try<Output = ()>;
439
440    /// Applies a fallible asynchronous function once to each item
441    /// in an arbitrary execution order.
442    ///
443    /// # Example
444    ///
445    /// ```
446    /// use bulks::*;
447    /// use core::time::Duration;
448    ///
449    /// let a = ["1024", "512", "256", "lol"];
450    ///
451    /// # tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async {
452    /// let res = a.into_bulk()
453    ///     .try_for_each_async(async |n| {
454    ///         let n = n.parse::<u64>().map_err(|_| n)?;
455    ///         tokio::time::sleep(Duration::from_millis(n)).await;
456    ///
457    ///         panic!("Tasks will be cancelled before this point.");
458    ///
459    ///         Ok(())
460    ///     })
461    ///     .await;
462    /// assert_eq!(res, Err("lol"))
463    /// # })
464    /// ```
465    #[cfg(feature = "async")]
466    #[rustc_non_const_trait_method]
467    fn try_for_each_async<F>(self, f: F) -> TryForEachAsync<Self, F>
468    where
469        Self: BufferableBulk + Sized,
470        F: FnMut<(Self::Item,), Output: Future<Output: Try<Output = ()>>>
471    {
472        TryForEachAsync::new(self, f)
473    }
474
475    /// Folds every element into an accumulator by applying an operation,
476    /// returning the final result.
477    ///
478    /// `fold()` takes two arguments: an initial value, and a closure with two
479    /// arguments: an 'accumulator', and an element. The closure returns the value that
480    /// the accumulator should have for the next iteration.
481    ///
482    /// The initial value is the value the accumulator will have on the first
483    /// call.
484    ///
485    /// After applying this closure to every element of the iterator, `fold()`
486    /// returns the accumulator.
487    ///
488    /// This operation is sometimes called 'reduce' or 'inject'.
489    ///
490    /// Folding is useful whenever you have a collection of something, and want
491    /// to produce a single value from it.
492    ///
493    /// Note: [`reduce()`](Bulk::reduce) can be used to use the first element as the initial
494    /// value, if the accumulator type and item type is the same.
495    ///
496    /// Note: `fold()` combines elements in a *left-associative* fashion. For associative
497    /// operators like `+`, the order the elements are combined in is not important, but for non-associative
498    /// operators like `-` the order will affect the final result.
499    /// For a *right-associative* version of `fold()`, see [`DoubleEndedBulk::rfold()`].
500    ///
501    /// # Note to Implementors
502    ///
503    /// Several of the other (forward) methods have default implementations in
504    /// terms of this one, so try to implement this explicitly if it can
505    /// do something better than the default `for` loop implementation.
506    ///
507    /// In particular, try to have this call `fold()` on the internal parts
508    /// from which this iterator is composed.
509    ///
510    /// # Examples
511    ///
512    /// Basic usage:
513    ///
514    /// ```
515    /// use bulks::*;
516    ///
517    /// let a = [1, 2, 3];
518    ///
519    /// // the sum of all of the elements of the array
520    /// let sum = a.bulk().fold(0, |acc, x| acc + x);
521    ///
522    /// assert_eq!(sum, 6);
523    /// ```
524    ///
525    /// Let's walk through each step of the iteration here:
526    ///
527    /// | element | acc | x | result |
528    /// |---------|-----|---|--------|
529    /// |         | 0   |   |        |
530    /// | 1       | 0   | 1 | 1      |
531    /// | 2       | 1   | 2 | 3      |
532    /// | 3       | 3   | 3 | 6      |
533    ///
534    /// And so, our final result, `6`.
535    ///
536    /// This example demonstrates the left-associative nature of `fold()`:
537    /// it builds a string, starting with an initial value
538    /// and continuing with each element from the front until the back:
539    ///
540    /// ```
541    /// use bulks::*;
542    ///
543    /// let numbers = [1, 2, 3, 4, 5];
544    ///
545    /// let zero = "0".to_string();
546    ///
547    /// let result = numbers.bulk().fold(zero, |acc, &x| {
548    ///     format!("({acc} + {x})")
549    /// });
550    ///
551    /// assert_eq!(result, "(((((0 + 1) + 2) + 3) + 4) + 5)");
552    /// ```
553    #[doc(alias = "inject", alias = "foldl")]
554    #[inline]
555    fn fold<B, F>(self, init: B, f: F) -> B
556    where
557        Self: Sized,
558        B: [const] Destruct,
559        F: [const] FnMut(B, Self::Item) -> B + [const] Destruct
560    {
561        struct Closure<'a, B, F>
562        {
563            z: &'a mut Option<B>,
564            f: F
565        }
566        const impl<'a, B, F, T> FnOnce<(T,)> for Closure<'a, B, F>
567        where
568            B: [const] Destruct,
569            F: [const] FnOnce(B, T) -> B
570        {
571            type Output = ();
572
573            extern "rust-call" fn call_once(self, (x,): (T,)) -> Self::Output
574            {
575                let Self { z, f } = self;
576                let zz = unsafe { z.take().unwrap_unchecked() };
577                let _ = z.insert((f)(zz, x));
578            }
579        }
580        const impl<'a, B, F, T> FnMut<(T,)> for Closure<'a, B, F>
581        where
582            B: [const] Destruct,
583            F: [const] FnMut(B, T) -> B
584        {
585            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
586            {
587                let Self { z, f } = self;
588                let zz = unsafe { z.take().unwrap_unchecked() };
589                let _ = z.insert((f)(zz, x));
590            }
591        }
592
593        let mut z = Some(init);
594        self.for_each(Closure { z: &mut z, f });
595
596        unsafe { z.unwrap_unchecked() }
597    }
598
599    /// Reduces the bulks's elements to a single, final value, starting from the back.
600    ///
601    /// This is the reverse version of [`Bulk::fold()`]: it takes elements
602    /// starting from the back of the bulk.
603    ///
604    /// `rfold()` takes two arguments: an initial value, and a closure with two
605    /// arguments: an 'accumulator', and an element. The closure returns the value that
606    /// the accumulator should have for the next iteration.
607    ///
608    /// The initial value is the value the accumulator will have on the first
609    /// call.
610    ///
611    /// After applying this closure to every element of the iterator, `rfold()`
612    /// returns the accumulator.
613    ///
614    /// This operation is sometimes called 'reduce' or 'inject'.
615    ///
616    /// Folding is useful whenever you have a collection of something, and want
617    /// to produce a single value from it.
618    ///
619    /// Note: `rfold()` combines elements in a *right-associative* fashion. For associative
620    /// operators like `+`, the order the elements are combined in is not important, but for non-associative
621    /// operators like `-` the order will affect the final result.
622    /// For a *left-associative* version of `rfold()`, see [`Bulk::fold()`].
623    ///
624    /// # Examples
625    ///
626    /// Basic usage:
627    ///
628    /// ```
629    /// use bulks::*;
630    ///
631    /// let a = [1, 2, 3];
632    ///
633    /// // the sum of all of the elements of a
634    /// let sum = a.bulk()
635    ///            .rfold(0, |acc, &x| acc + x);
636    ///
637    /// assert_eq!(sum, 6);
638    /// ```
639    ///
640    /// This example demonstrates the right-associative nature of `rfold()`:
641    /// it builds a string, starting with an initial value
642    /// and continuing with each element from the back until the front:
643    ///
644    /// ```
645    /// use bulks::*;
646    ///
647    /// let numbers = [1, 2, 3, 4, 5];
648    ///
649    /// let zero = "0".to_string();
650    ///
651    /// let result = numbers.bulk().rfold(zero, |acc, &x| {
652    ///     format!("({x} + {acc})")
653    /// });
654    ///
655    /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
656    /// ```
657    #[doc(alias = "foldr")]
658    #[inline]
659    fn rfold<B, F>(self, init: B, f: F) -> B
660    where
661        Self: Sized + [const] DoubleEndedBulk,
662        B: [const] Destruct,
663        F: [const] FnMut(B, Self::Item) -> B + [const] Destruct
664    {
665        struct Closure<'a, B, F>
666        {
667            z: &'a mut Option<B>,
668            f: F
669        }
670        const impl<'a, B, F, T> FnOnce<(T,)> for Closure<'a, B, F>
671        where
672            B: [const] Destruct,
673            F: [const] FnOnce(B, T) -> B
674        {
675            type Output = ();
676
677            extern "rust-call" fn call_once(self, (x,): (T,)) -> Self::Output
678            {
679                let Self { z, f } = self;
680                let zz = unsafe { z.take().unwrap_unchecked() };
681                let _ = z.insert((f)(zz, x));
682            }
683        }
684        const impl<'a, B, F, T> FnMut<(T,)> for Closure<'a, B, F>
685        where
686            B: [const] Destruct,
687            F: [const] FnMut(B, T) -> B
688        {
689            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
690            {
691                let Self { z, f } = self;
692                let zz = unsafe { z.take().unwrap_unchecked() };
693                let _ = z.insert((f)(zz, x));
694            }
695        }
696
697        let mut z = Some(init);
698        self.rev_for_each(Closure { z: &mut z, f });
699
700        unsafe { z.unwrap_unchecked() }
701    }
702
703    fn try_fold<B, F, R>(self, init: B, f: F) -> R
704    where
705        B: [const] Destruct,
706        Self: Sized,
707        Self::Item: [const] Destruct,
708        F: [const] FnMut(B, Self::Item) -> R + [const] Destruct,
709        R: [const] Try<Output = B>
710    {
711        struct Closure<'a, B, F>
712        {
713            z: &'a mut Option<B>,
714            f: F
715        }
716        const impl<'a, B, F, T, R> FnOnce<(T,)> for Closure<'a, B, F>
717        where
718            B: [const] Destruct,
719            F: [const] FnOnce(B, T) -> R,
720            R: [const] Try<Output = B>
721        {
722            type Output = ControlFlow<R::Residual, ()>;
723
724            extern "rust-call" fn call_once(self, (x,): (T,)) -> Self::Output
725            {
726                let Self { z, f } = self;
727                let zz = unsafe { z.take().unwrap_unchecked() };
728                let _ = z.insert(f(zz, x).branch()?);
729                ControlFlow::Continue(())
730            }
731        }
732        const impl<'a, B, F, T, R> FnMut<(T,)> for Closure<'a, B, F>
733        where
734            B: [const] Destruct,
735            F: [const] FnMut(B, T) -> R,
736            R: [const] Try<Output = B>
737        {
738            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
739            {
740                let Self { z, f } = self;
741                let zz = unsafe { z.take().unwrap_unchecked() };
742                let _ = z.insert(f(zz, x).branch()?);
743                ControlFlow::Continue(())
744            }
745        }
746
747        let mut z = Some(init);
748        match self.try_for_each(Closure { z: &mut z, f })
749        {
750            ControlFlow::Break(residual) => R::from_residual(residual),
751            ControlFlow::Continue(()) => R::from_output(unsafe { z.unwrap_unchecked() })
752        }
753    }
754
755    fn try_rfold<B, F, R>(self, init: B, f: F) -> R
756    where
757        B: [const] Destruct,
758        Self: Sized + [const] DoubleEndedBulk,
759        Self::Item: [const] Destruct,
760        F: [const] FnMut(B, Self::Item) -> R + [const] Destruct,
761        R: [const] Try<Output = B>
762    {
763        struct Closure<'a, B, F>
764        {
765            z: &'a mut Option<B>,
766            f: F
767        }
768        const impl<'a, B, F, T, R> FnOnce<(T,)> for Closure<'a, B, F>
769        where
770            B: [const] Destruct,
771            F: [const] FnOnce(B, T) -> R,
772            R: [const] Try<Output = B>
773        {
774            type Output = ControlFlow<R::Residual, ()>;
775
776            extern "rust-call" fn call_once(self, (x,): (T,)) -> Self::Output
777            {
778                let Self { z, f } = self;
779                let zz = unsafe { z.take().unwrap_unchecked() };
780                let _ = z.insert(f(zz, x).branch()?);
781                ControlFlow::Continue(())
782            }
783        }
784        const impl<'a, B, F, T, R> FnMut<(T,)> for Closure<'a, B, F>
785        where
786            B: [const] Destruct,
787            F: [const] FnMut(B, T) -> R,
788            R: [const] Try<Output = B>
789        {
790            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
791            {
792                let Self { z, f } = self;
793                let zz = unsafe { z.take().unwrap_unchecked() };
794                let _ = z.insert(f(zz, x).branch()?);
795                ControlFlow::Continue(())
796            }
797        }
798
799        let mut z = Some(init);
800        match self.try_rev_for_each(Closure { z: &mut z, f })
801        {
802            ControlFlow::Break(residual) => R::from_residual(residual),
803            ControlFlow::Continue(()) => R::from_output(unsafe { z.unwrap_unchecked() })
804        }
805    }
806
807    /// Reduces the elements to a single one, by repeatedly applying a reducing
808    /// operation.
809    ///
810    /// If the bulk is empty, returns [`None`]; otherwise, returns the
811    /// result of the reduction.
812    ///
813    /// The reducing function is a closure with two arguments: an 'accumulator', and an element.
814    /// For bulks with at least one element, this is the same as [`fold()`]
815    /// with the first element of the bulk as the initial accumulator value, folding
816    /// every subsequent element into it.
817    ///
818    /// [`fold()`]: Bulk::fold
819    ///
820    /// # Example
821    ///
822    /// ```
823    /// use bulks::*;
824    ///
825    /// let reduced: i32 = (1..10).into_bulk().reduce(|acc, e| acc + e).unwrap_or(0);
826    /// assert_eq!(reduced, 45);
827    ///
828    /// // Which is equivalent to doing it with `fold`:
829    /// let folded: i32 = (1..10).into_bulk().fold(0, |acc, e| acc + e);
830    /// assert_eq!(reduced, folded);
831    /// ```
832    fn reduce<F>(self, f: F) -> Option<Self::Item>
833    where
834        Self: Sized,
835        Self::Item: [const] Destruct,
836        F: [const] FnMut(Self::Item, Self::Item) -> Self::Item + [const] Destruct
837    {
838        struct Closure<F>
839        {
840            f: F
841        }
842        const impl<F, T> FnOnce<(Option<T>, T)> for Closure<F>
843        where
844            F: [const] FnOnce(T, T) -> T + [const] Destruct
845        {
846            type Output = Option<T>;
847
848            extern "rust-call" fn call_once(self, (z, x): (Option<T>, T)) -> Self::Output
849            {
850                let Self { f } = self;
851
852                match z
853                {
854                    Some(z) => Some(f(z, x)),
855                    None => Some(x)
856                }
857            }
858        }
859        const impl<F, T> FnMut<(Option<T>, T)> for Closure<F>
860        where
861            F: [const] FnMut(T, T) -> T
862        {
863            extern "rust-call" fn call_mut(&mut self, (z, x): (Option<T>, T)) -> Self::Output
864            {
865                let Self { f } = self;
866
867                match z
868                {
869                    Some(z) => Some(f(z, x)),
870                    None => Some(x)
871                }
872            }
873        }
874
875        self.fold(None, Closure { f })
876    }
877
878    /// Reduces the elements to a single one, by concurrently applying a reducing
879    /// operation, by way of divide and conquer.
880    ///
881    /// If the bulk is empty, returns [`None`]; otherwise, returns the
882    /// result of the reduction.
883    ///
884    /// # Example
885    ///
886    /// ```
887    /// use bulks::*;
888    ///
889    /// let a = [1, 2, 3];
890    ///
891    /// # tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async {
892    /// let n = a.into_bulk().reduce_async(async |a, b| a + b).await;
893    ///
894    /// assert_eq!(n, Some(1 + 2 + 3))
895    /// # })
896    /// ```
897    #[cfg(feature = "async")]
898    #[rustc_non_const_trait_method]
899    fn reduce_async<F>(self, f: F) -> ReduceAsync<Self, F>
900    where
901        Self: BufferableBulk + Sized,
902        F: FnMut<(Self::Item, Self::Item), Output: Future<Output = Self::Item>>
903    {
904        ReduceAsync::new(self, f)
905    }
906
907    /// Reduces the elements to a single one by repeatedly applying a reducing operation. If the
908    /// closure returns a failure, the failure is propagated back to the caller immediately.
909    ///
910    /// The return type of this method depends on the return type of the closure. If the closure
911    /// returns `Result<Self::Item, E>`, then this function will return `Result<Option<Self::Item>,
912    /// E>`. If the closure returns `Option<Self::Item>`, then this function will return
913    /// `Option<Option<Self::Item>>`.
914    ///
915    /// When called on an empty bulk, this function will return either `Some(None)` or
916    /// `Ok(None)` depending on the type of the provided closure.
917    ///
918    /// For bulks with at least one element, this is essentially the same as calling
919    /// [`try_fold()`] with the first element of the bulk as the initial accumulator value.
920    ///
921    /// [`try_fold()`]: Bulk::try_fold
922    ///
923    /// # Examples
924    ///
925    /// Safely calculate the sum of a series of numbers:
926    ///
927    /// ```
928    /// use bulks::*;
929    ///
930    /// let numbers: Vec<usize> = vec![10, 20, 5, 23, 0];
931    /// let sum = numbers.into_bulk().try_reduce(|x, y| x.checked_add(y));
932    /// assert_eq!(sum, Some(Some(58)));
933    /// ```
934    ///
935    /// Determine when a reduction short circuited:
936    ///
937    /// ```
938    /// use bulks::*;
939    ///
940    /// let numbers = vec![1, 2, 3, usize::MAX, 4, 5];
941    /// let sum = numbers.into_bulk().try_reduce(|x, y| x.checked_add(y));
942    /// assert_eq!(sum, None);
943    /// ```
944    ///
945    /// Determine when a reduction was not performed because there are no elements:
946    ///
947    /// ```
948    /// use bulks::*;
949    ///
950    /// let numbers: Vec<usize> = Vec::new();
951    /// let sum = numbers.into_bulk().try_reduce(|x, y| x.checked_add(y));
952    /// assert_eq!(sum, Some(None));
953    /// ```
954    ///
955    /// Use a [`Result`] instead of an [`Option`]:
956    ///
957    /// ```
958    /// use bulks::*;
959    ///
960    /// let numbers = vec!["1", "2", "3", "4", "5"];
961    /// let max: Result<Option<_>, <usize as std::str::FromStr>::Err> =
962    ///     numbers.into_bulk().try_reduce(|x, y| {
963    ///         if x.parse::<usize>()? > y.parse::<usize>()? { Ok(x) } else { Ok(y) }
964    ///     });
965    /// assert_eq!(max, Ok(Some("5")));
966    /// ```
967    fn try_reduce<F, R>(self, f: F) -> <R::Residual as Residual<Option<R::Output>>>::TryType
968    where
969        Self: Sized,
970        Self::Item: [const] Destruct,
971        F: [const] FnMut(Self::Item, Self::Item) -> R + [const] Destruct,
972        R: [const] Try<Output = Self::Item, Residual: Residual<Option<Self::Item>, TryType: [const] Try> + [const] Destruct>
973    {
974        struct Closure<F>
975        {
976            f: F
977        }
978        const impl<F, T, R> FnOnce<(Option<T>, T)> for Closure<F>
979        where
980            F: [const] FnOnce(T, T) -> R + [const] Destruct,
981            R: [const] Try<Output = T, Residual: [const] Destruct>
982        {
983            type Output = ControlFlow<R::Residual, Option<T>>;
984
985            extern "rust-call" fn call_once(self, (z, x): (Option<T>, T)) -> Self::Output
986            {
987                let Self { f } = self;
988
989                ControlFlow::Continue(Some(match z
990                {
991                    Some(z) => f(z, x).branch()?,
992                    None => x
993                }))
994            }
995        }
996        const impl<F, T, R> FnMut<(Option<T>, T)> for Closure<F>
997        where
998            F: [const] FnMut(T, T) -> R,
999            R: [const] Try<Output = T, Residual: [const] Destruct>
1000        {
1001            extern "rust-call" fn call_mut(&mut self, (z, x): (Option<T>, T)) -> Self::Output
1002            {
1003                let Self { f } = self;
1004
1005                ControlFlow::Continue(Some(match z
1006                {
1007                    Some(z) => f(z, x).branch()?,
1008                    None => x
1009                }))
1010            }
1011        }
1012
1013        match self.try_fold(None, Closure { f })
1014        {
1015            ControlFlow::Break(residual) => FromResidual::from_residual(residual),
1016            ControlFlow::Continue(output) => Try::from_output(output)
1017        }
1018    }
1019
1020    #[cfg(feature = "async")]
1021    #[rustc_non_const_trait_method]
1022    fn try_reduce_async<F, R>(self, f: F) -> TryReduceAsync<Self, F, R>
1023    where
1024        Self: BufferableBulk + Sized,
1025        F: FnMut<(Self::Item, Self::Item), Output: Future<Output = R>>,
1026        R: Try<Output = Self::Item, Residual: Residual<Option<Self::Item>>>
1027    {
1028        TryReduceAsync::new(self, f)
1029    }
1030
1031    /// Tests if every element of the bulk matches a predicate.
1032    ///
1033    /// `all()` takes a closure that returns `true` or `false`. It applies
1034    /// this closure to each element of the bulk, and if they all return
1035    /// `true`, then so does `all()`. If any of them return `false`, it
1036    /// returns `false`.
1037    ///
1038    /// `all()` is short-circuiting; in other words, it will stop processing
1039    /// as soon as it finds a `false`, given that no matter what else happens,
1040    /// the result will also be `false`.
1041    ///
1042    /// An empty bulk returns `true`.
1043    ///
1044    /// # Examples
1045    ///
1046    /// Basic usage:
1047    ///
1048    /// ```
1049    /// use bulks::*;
1050    ///
1051    /// let a = [1, 2, 3];
1052    ///
1053    /// assert!(a.into_bulk().all(|x| x > 0));
1054    ///
1055    /// assert!(!a.into_bulk().all(|x| x > 2));
1056    /// ```
1057    fn all<F>(self, f: F) -> bool
1058    where
1059        Self: Sized,
1060        F: [const] FnMut(Self::Item) -> bool + [const] Destruct,
1061        Self::Item: [const] Destruct
1062    {
1063        struct Functor<F>(F);
1064        const impl<F, T> FnOnce<(T,)> for Functor<F>
1065        where
1066            F: [const] FnMut(T) -> bool + [const] Destruct
1067        {
1068            type Output = ControlFlow<()>;
1069
1070            extern "rust-call" fn call_once(mut self, args: (T,)) -> Self::Output
1071            {
1072                self.call_mut(args)
1073            }
1074        }
1075        const impl<F, T> FnMut<(T,)> for Functor<F>
1076        where
1077            F: [const] FnMut(T) -> bool
1078        {
1079            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
1080            {
1081                if self.0(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
1082            }
1083        }
1084
1085        self.try_for_each(Functor(f)) == ControlFlow::Continue(())
1086    }
1087
1088    /// Tests if every element of the bulk matches an asynchronous predicate.
1089    ///
1090    /// `all()` takes a closure that returns `true` or `false`. It applies
1091    /// this closure to each element of the bulk in an unscpecified order,
1092    /// and if they all return `true`, then so does `all()`.
1093    /// If any of them return `false`, it returns `false`.
1094    ///
1095    /// `all()` is short-circuiting; in other words, it will stop processing
1096    /// as soon as it finds a `false`, given that no matter what else happens,
1097    /// the result will also be `false`.
1098    ///
1099    /// An empty bulk returns `true`.
1100    ///
1101    /// # Examples
1102    ///
1103    /// Basic usage:
1104    ///
1105    /// ```
1106    /// use bulks::*;
1107    ///
1108    /// let a = [1, 2, 3];
1109    ///
1110    /// # tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async {
1111    /// assert!(a.into_bulk().all_async(async |x| x > 0).await);
1112    ///
1113    /// assert!(!a.into_bulk().all_async(async |x| x > 2).await);
1114    /// # })
1115    /// ```
1116    #[cfg(feature = "async")]
1117    #[rustc_non_const_trait_method]
1118    fn all_async<F>(self, condition: F) -> AllAsync<Self, F>
1119    where
1120        Self: BufferableBulk + Sized,
1121        F: FnMut<(Self::Item,), Output: Future<Output = bool>>
1122    {
1123        AllAsync::new(self, condition)
1124    }
1125
1126    /// Tests if any element of the bulk matches a predicate.
1127    ///
1128    /// `any()` takes a closure that returns `true` or `false`. It applies
1129    /// this closure to each element of the bulk, and if any of them return
1130    /// `true`, then so does `any()`. If they all return `false`, it
1131    /// returns `false`.
1132    ///
1133    /// `any()` is short-circuiting; in other words, it will stop processing
1134    /// as soon as it finds a `true`, given that no matter what else happens,
1135    /// the result will also be `true`.
1136    ///
1137    /// An empty bulk returns `false`.
1138    ///
1139    /// # Examples
1140    ///
1141    /// Basic usage:
1142    ///
1143    /// ```
1144    /// use bulks::*;
1145    ///
1146    /// let a = [1, 2, 3];
1147    ///
1148    /// assert!(a.into_bulk().any(|x| x > 0));
1149    ///
1150    /// assert!(!a.into_bulk().any(|x| x > 5));
1151    /// ```
1152    fn any<F>(self, f: F) -> bool
1153    where
1154        Self: Sized,
1155        F: [const] FnMut(Self::Item) -> bool + [const] Destruct,
1156        Self::Item: [const] Destruct
1157    {
1158        struct Functor<F>(F);
1159        const impl<F, T> FnOnce<(T,)> for Functor<F>
1160        where
1161            F: [const] FnMut(T) -> bool + [const] Destruct
1162        {
1163            type Output = ControlFlow<()>;
1164
1165            extern "rust-call" fn call_once(mut self, args: (T,)) -> Self::Output
1166            {
1167                self.call_mut(args)
1168            }
1169        }
1170        const impl<F, T> FnMut<(T,)> for Functor<F>
1171        where
1172            F: [const] FnMut(T) -> bool
1173        {
1174            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
1175            {
1176                if self.0(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
1177            }
1178        }
1179
1180        self.try_for_each(Functor(f)) == ControlFlow::Break(())
1181    }
1182
1183    /// Tests if any element of the bulk matches an asynchronous predicate.
1184    ///
1185    /// `any()` takes a closure that returns `true` or `false`. It applies
1186    /// this closure to each element of the bulk in an unspecified order,
1187    /// and if any of them return `true`, then so does `any()`.
1188    /// If they all return `false`, it returns `false`.
1189    ///
1190    /// `any()` is short-circuiting; in other words, it will stop processing
1191    /// as soon as it finds a `true`, given that no matter what else happens,
1192    /// the result will also be `true`.
1193    ///
1194    /// An empty bulk returns `false`.
1195    ///
1196    /// # Examples
1197    ///
1198    /// Basic usage:
1199    ///
1200    /// ```
1201    /// use bulks::*;
1202    ///
1203    /// let a = [1, 2, 3];
1204    ///
1205    /// # tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async {
1206    /// assert!(a.into_bulk().any_async(async |x| x > 0).await);
1207    ///
1208    /// assert!(!a.into_bulk().any_async(async |x| x > 5).await);
1209    /// # })
1210    /// ```
1211    #[cfg(feature = "async")]
1212    #[rustc_non_const_trait_method]
1213    fn any_async<F>(self, condition: F) -> AnyAsync<Self, F>
1214    where
1215        Self: BufferableBulk + Sized,
1216        F: FnMut<(Self::Item,), Output: Future<Output = bool>>
1217    {
1218        AnyAsync::new(self, condition)
1219    }
1220
1221    /// Searches for an element of a bulk that satisfies a predicate.
1222    ///
1223    /// `find()` takes a closure that returns `true` or `false`. It applies
1224    /// this closure to each element of the bulk, and if any of them return
1225    /// `true`, then `find()` returns [`Some(element)`]. If they all return
1226    /// `false`, it returns [`None`].
1227    ///
1228    /// `find()` is short-circuiting; in other words, it will stop processing
1229    /// as soon as the closure returns `true`.
1230    ///
1231    /// Because `find()` takes a reference, and many iterators iterate over
1232    /// references, this leads to a possibly confusing situation where the
1233    /// argument is a double reference. You can see this effect in the
1234    /// examples below, with `&&x`.
1235    ///
1236    /// If you need the index of the element, see [`position()`].
1237    ///
1238    /// [`Some(element)`]: Some
1239    /// [`position()`]: Bulk::position
1240    ///
1241    /// # Examples
1242    ///
1243    /// Basic usage:
1244    ///
1245    /// ```
1246    /// use bulks::*;
1247    ///
1248    /// let a = [1, 2, 3];
1249    ///
1250    /// assert_eq!(a.into_bulk().find(|&x| x == 2), Some(2));
1251    /// assert_eq!(a.into_bulk().find(|&x| x == 5), None);
1252    /// ```
1253    ///
1254    /// Iterating over references:
1255    ///
1256    /// ```
1257    /// use bulks::*;
1258    ///
1259    /// let a = [1, 2, 3];
1260    ///
1261    /// // `bulk()` yields references i.e. `&i32` and `find()` takes a
1262    /// // reference to each element.
1263    /// assert_eq!(a.bulk().find(|&&x| x == 2), Some(&2));
1264    /// assert_eq!(a.bulk().find(|&&x| x == 5), None);
1265    /// ```
1266    #[inline]
1267    fn find<P>(self, predicate: P) -> Option<Self::Item>
1268    where
1269        Self: Sized,
1270        Self::Item: [const] Destruct,
1271        P: [const] FnMut(&Self::Item) -> bool + [const] Destruct
1272    {
1273        struct Functor<P>
1274        {
1275            predicate: P
1276        }
1277        const impl<T, P> FnOnce<(T,)> for Functor<P>
1278        where
1279            P: [const] FnMut(&T) -> bool + [const] Destruct,
1280            T: [const] Destruct
1281        {
1282            type Output = ControlFlow<T>;
1283
1284            extern "rust-call" fn call_once(mut self, args: (T,)) -> Self::Output
1285            {
1286                self.call_mut(args)
1287            }
1288        }
1289        const impl<T, P> FnMut<(T,)> for Functor<P>
1290        where
1291            P: [const] FnMut(&T) -> bool,
1292            T: [const] Destruct
1293        {
1294            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
1295            {
1296                if (self.predicate)(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
1297            }
1298        }
1299
1300        self.try_for_each(Functor { predicate }).break_value()
1301    }
1302
1303    // TODO
1304    /*#[cfg(feature = "async")]
1305    #[rustc_non_const_trait_method]
1306    fn find_async<F, Y>(self, f: F) -> FindAsync<Self, F, Y>
1307    where
1308        Self: BufferableBulk + Sized,
1309        F: FnMut(&Self::Item) -> Y,
1310        Y: Future<Output = bool>
1311    {
1312        FindAsync::new(self, f)
1313    }*/
1314
1315    /// Searches for an element of a bulk from the back that satisfies a predicate.
1316    ///
1317    /// `rfind()` takes a closure that returns `true` or `false`. It applies
1318    /// this closure to each element of the bulk, starting at the end, and if any
1319    /// of them return `true`, then `rfind()` returns [`Some(element)`]. If they all return
1320    /// `false`, it returns [`None`].
1321    ///
1322    /// `rfind()` is short-circuiting; in other words, it will stop processing
1323    /// as soon as the closure returns `true`.
1324    ///
1325    /// Because `rfind()` takes a reference, and many iterators iterate over
1326    /// references, this leads to a possibly confusing situation where the
1327    /// argument is a double reference. You can see this effect in the
1328    /// examples below, with `&&x`.
1329    ///
1330    /// [`Some(element)`]: Some
1331    ///
1332    /// # Examples
1333    ///
1334    /// Basic usage:
1335    ///
1336    /// ```
1337    /// use bulks::*;
1338    ///
1339    /// let a = [1, 2, 3];
1340    ///
1341    /// assert_eq!(a.into_bulk().rfind(|&x| x == 2), Some(2));
1342    /// assert_eq!(a.into_bulk().rfind(|&x| x == 5), None);
1343    /// ```
1344    ///
1345    /// Iterating over references:
1346    ///
1347    /// ```
1348    /// use bulks::*;
1349    ///
1350    /// let a = [1, 2, 3];
1351    ///
1352    /// // `bulk()` yields references i.e. `&i32` and `rfind()` takes a
1353    /// // reference to each element.
1354    /// assert_eq!(a.bulk().rfind(|&&x| x == 2), Some(&2));
1355    /// assert_eq!(a.bulk().rfind(|&&x| x == 5), None);
1356    /// ```
1357    #[inline]
1358    fn rfind<P>(self, predicate: P) -> Option<Self::Item>
1359    where
1360        Self: Sized + [const] DoubleEndedBulk,
1361        P: [const] FnMut(&Self::Item) -> bool + [const] Destruct,
1362        Self::Item: [const] Destruct
1363    {
1364        struct Functor<P>
1365        {
1366            predicate: P
1367        }
1368        const impl<T, P> FnOnce<((), T)> for Functor<P>
1369        where
1370            P: [const] FnMut(&T) -> bool + [const] Destruct,
1371            T: [const] Destruct
1372        {
1373            type Output = ControlFlow<T>;
1374
1375            extern "rust-call" fn call_once(mut self, args: ((), T)) -> Self::Output
1376            {
1377                self.call_mut(args)
1378            }
1379        }
1380        const impl<T, P> FnMut<((), T)> for Functor<P>
1381        where
1382            P: [const] FnMut(&T) -> bool,
1383            T: [const] Destruct
1384        {
1385            extern "rust-call" fn call_mut(&mut self, ((), x): ((), T)) -> Self::Output
1386            {
1387                if (self.predicate)(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
1388            }
1389        }
1390
1391        self.try_rfold((), Functor { predicate }).break_value()
1392    }
1393
1394    /// Applies function to the elements of the bulk and returns
1395    /// the first non-none result.
1396    ///
1397    /// # Examples
1398    ///
1399    /// ```
1400    /// use bulks::*;
1401    ///
1402    /// let a = ["lol", "NaN", "2", "5"];
1403    ///
1404    /// let first_number = a.bulk().find_map(|s| s.parse().ok());
1405    ///
1406    /// assert_eq!(first_number, Some(2));
1407    /// ```
1408    #[inline]
1409    fn find_map<B, F>(self, mapper: F) -> Option<B>
1410    where
1411        Self: Sized,
1412        Self::Item: [const] Destruct,
1413        F: [const] FnMut(Self::Item) -> Option<B> + [const] Destruct,
1414        B: [const] Destruct
1415    {
1416        struct Functor<P>
1417        {
1418            mapper: P
1419        }
1420        const impl<T, P, B> FnOnce<((), T)> for Functor<P>
1421        where
1422            P: [const] FnMut(T) -> Option<B> + [const] Destruct,
1423            T: [const] Destruct
1424        {
1425            type Output = ControlFlow<B>;
1426
1427            extern "rust-call" fn call_once(mut self, args: ((), T)) -> Self::Output
1428            {
1429                self.call_mut(args)
1430            }
1431        }
1432        const impl<T, P, B> FnMut<((), T)> for Functor<P>
1433        where
1434            P: [const] FnMut(T) -> Option<B>,
1435            T: [const] Destruct
1436        {
1437            extern "rust-call" fn call_mut(&mut self, ((), x): ((), T)) -> Self::Output
1438            {
1439                if let Some(y) = (self.mapper)(x)
1440                {
1441                    ControlFlow::Break(y)
1442                }
1443                else
1444                {
1445                    ControlFlow::Continue(())
1446                }
1447            }
1448        }
1449
1450        self.try_fold((), Functor { mapper }).break_value()
1451    }
1452
1453    #[cfg(feature = "async")]
1454    #[rustc_non_const_trait_method]
1455    fn find_map_async<B, F>(self, f: F) -> FindMapAsync<Self, B, F>
1456    where
1457        Self: BufferableBulk + Sized,
1458        F: FnMut<(Self::Item,), Output: Future<Output = Option<B>>>
1459    {
1460        FindMapAsync::new(self, f)
1461    }
1462
1463    /// Applies function to the elements of the bulk and returns
1464    /// the first true result or the first error.
1465    ///
1466    /// The return type of this method depends on the return type of the closure.
1467    /// If you return `Result<bool, E>` from the closure, you'll get a `Result<Option<Self::Item>, E>`.
1468    /// If you return `Option<bool>` from the closure, you'll get an `Option<Option<Self::Item>>`.
1469    ///
1470    /// # Examples
1471    ///
1472    /// ```
1473    /// use bulks::*;
1474    ///
1475    /// let a = ["1", "2", "lol", "NaN", "5"];
1476    ///
1477    /// let is_my_num = |s: &str, search: i32| -> Result<bool, std::num::ParseIntError> {
1478    ///     Ok(s.parse::<i32>()? == search)
1479    /// };
1480    ///
1481    /// let result = a.into_bulk().try_find(|&s| is_my_num(s, 2));
1482    /// assert_eq!(result, Ok(Some("2")));
1483    ///
1484    /// let result = a.into_bulk().try_find(|&s| is_my_num(s, 5));
1485    /// assert!(result.is_err());
1486    /// ```
1487    ///
1488    /// This also supports other types which implement [`Try`], not just [`Result`].
1489    ///
1490    /// ```
1491    /// use bulks::*;
1492    ///
1493    /// use std::num::NonZero;
1494    ///
1495    /// let a = [3, 5, 7, 4, 9, 0, 11u32];
1496    /// let result = a.into_bulk().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
1497    /// assert_eq!(result, Some(Some(4)));
1498    /// let result = a.into_bulk().take(3).try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
1499    /// assert_eq!(result, Some(None));
1500    /// let result = a.into_bulk().rev().try_find(|&x| NonZero::new(x).map(|y| y.is_power_of_two()));
1501    /// assert_eq!(result, None);
1502    /// ```
1503    #[inline]
1504    fn try_find<F, R>(self, predicate: F) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
1505    where
1506        Self: Sized,
1507        Self::Item: [const] Destruct,
1508        F: [const] FnMut(&Self::Item) -> R + [const] Destruct,
1509        R: [const] Try<Output = bool, Residual: [const] Residual<Option<Self::Item>>>
1510    {
1511        struct Functor<P>
1512        {
1513            predicate: P
1514        }
1515        const impl<T, R, P> FnOnce<(T,)> for Functor<P>
1516        where
1517            P: [const] FnMut(&T) -> R + [const] Destruct,
1518            R: [const] Try<Output = bool, Residual: [const] Residual<Option<T>>>,
1519            T: [const] Destruct
1520        {
1521            type Output = ControlFlow<<R::Residual as Residual<Option<T>>>::TryType>;
1522
1523            extern "rust-call" fn call_once(mut self, args: (T,)) -> Self::Output
1524            {
1525                self.call_mut(args)
1526            }
1527        }
1528        const impl<T, R, P> FnMut<(T,)> for Functor<P>
1529        where
1530            P: [const] FnMut(&T) -> R,
1531            R: [const] Try<Output = bool, Residual: [const] Residual<Option<T>>>,
1532            T: [const] Destruct
1533        {
1534            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
1535            {
1536                match (self.predicate)(&x).branch()
1537                {
1538                    ControlFlow::Continue(false) => ControlFlow::Continue(()),
1539                    ControlFlow::Continue(true) => ControlFlow::Break(Try::from_output(Some(x))),
1540                    ControlFlow::Break(r) => ControlFlow::Break(FromResidual::from_residual(r))
1541                }
1542            }
1543        }
1544
1545        match self.try_for_each(Functor { predicate })
1546        {
1547            ControlFlow::Break(x) => x,
1548            ControlFlow::Continue(()) => Try::from_output(None)
1549        }
1550    }
1551
1552    // TODO
1553    /*#[cfg(feature = "async")]
1554    #[rustc_non_const_trait_method]
1555    fn try_find_async<F, R>(self, f: F) -> impl Future<Output = <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType>
1556    where
1557        Self: BufferableBulk + Sized,
1558        F: for<'a> FnMut<(&'a Self::Item,), Output: Future<Output = R>>,
1559        R: Try<Output = bool, Residual: Residual<Option<Self::Item>>>
1560    {
1561        async {
1562            match self
1563                .try_for_each_async(async |x| match f(&x).branch()
1564                {
1565                    ControlFlow::Continue(false) => ControlFlow::Continue(()),
1566                    ControlFlow::Continue(true) => ControlFlow::Break(Try::from_output(Some(x))),
1567                    ControlFlow::Break(r) => ControlFlow::Break(FromResidual::from_residual(r))
1568                })
1569                .await
1570            {
1571                ControlFlow::Break(x) => x,
1572                ControlFlow::Continue(()) => Try::from_output(None)
1573            }
1574        }
1575    }*/
1576
1577    /// Searches for an element in a bulk, returning its index.
1578    ///
1579    /// `position()` takes a closure that returns `true` or `false`. It applies
1580    /// this closure to each element of the bulk, and if one of them
1581    /// returns `true`, then `position()` returns [`Some(index)`]. If all of
1582    /// them return `false`, it returns [`None`].
1583    ///
1584    /// `position()` is short-circuiting; in other words, it will stop
1585    /// processing as soon as it finds a `true`.
1586    ///
1587    /// # Overflow Behavior
1588    ///
1589    /// The method does no guarding against overflows, so if there are more
1590    /// than [`usize::MAX`] non-matching elements, it either produces the wrong
1591    /// result or panics. If overflow checks are enabled, a panic is
1592    /// guaranteed.
1593    ///
1594    /// # Panics
1595    ///
1596    /// This function might panic if the iterator has more than `usize::MAX`
1597    /// non-matching elements.
1598    ///
1599    /// [`Some(index)`]: Some
1600    ///
1601    /// # Examples
1602    ///
1603    /// Basic usage:
1604    ///
1605    /// ```
1606    /// use bulks::*;
1607    ///
1608    /// let a = [1, 2, 3];
1609    ///
1610    /// assert_eq!(a.into_bulk().position(|x| x == 2), Some(1));
1611    ///
1612    /// assert_eq!(a.into_bulk().position(|x| x == 5), None);
1613    /// ```
1614    #[inline]
1615    fn position<P>(self, predicate: P) -> Option<usize>
1616    where
1617        Self: Sized,
1618        Self::Item: [const] Destruct,
1619        P: [const] FnMut(Self::Item) -> bool + [const] Destruct
1620    {
1621        struct Functor<P>
1622        {
1623            predicate: P
1624        }
1625        const impl<T, P> FnOnce<(usize, T)> for Functor<P>
1626        where
1627            P: [const] FnMut(T) -> bool + [const] Destruct
1628        {
1629            type Output = ControlFlow<usize, usize>;
1630
1631            #[rustc_inherit_overflow_checks]
1632            extern "rust-call" fn call_once(mut self, args: (usize, T)) -> Self::Output
1633            {
1634                self.call_mut(args)
1635            }
1636        }
1637        const impl<T, P> FnMut<(usize, T)> for Functor<P>
1638        where
1639            P: [const] FnMut(T) -> bool
1640        {
1641            #[rustc_inherit_overflow_checks]
1642            extern "rust-call" fn call_mut(&mut self, (i, x): (usize, T)) -> Self::Output
1643            {
1644                if (self.predicate)(x)
1645                {
1646                    ControlFlow::Break(i)
1647                }
1648                else
1649                {
1650                    ControlFlow::Continue(i + 1)
1651                }
1652            }
1653        }
1654
1655        self.try_fold(0, Functor { predicate }).break_value()
1656    }
1657
1658    #[cfg(feature = "async")]
1659    #[rustc_non_const_trait_method]
1660    fn position_async<F>(self, f: F) -> PositionAsync<Self, F>
1661    where
1662        Self: BufferableBulk + Sized,
1663        F: FnMut<(Self::Item,), Output: Future<Output = bool>>
1664    {
1665        PositionAsync::new(self, f)
1666    }
1667
1668    /// Searches for an element in a bulk from the right, returning its
1669    /// index.
1670    ///
1671    /// `rposition()` takes a closure that returns `true` or `false`. It applies
1672    /// this closure to each element of the bulk, starting from the end,
1673    /// and if one of them returns `true`, then `rposition()` returns
1674    /// [`Some(index)`]. If all of them return `false`, it returns [`None`].
1675    ///
1676    /// `rposition()` is short-circuiting; in other words, it will stop
1677    /// processing as soon as it finds a `true`.
1678    ///
1679    /// [`Some(index)`]: Some
1680    ///
1681    /// # Examples
1682    ///
1683    /// Basic usage:
1684    ///
1685    /// ```
1686    /// use bulks::*;
1687    ///
1688    /// let a = [1, 2, 3];
1689    ///
1690    /// assert_eq!(a.into_bulk().rposition(|x| x == 3), Some(2));
1691    ///
1692    /// assert_eq!(a.into_bulk().rposition(|x| x == 5), None);
1693    /// ```
1694    #[inline]
1695    fn rposition<P>(self, predicate: P) -> Option<usize>
1696    where
1697        P: [const] FnMut(Self::Item) -> bool + [const] Destruct,
1698        Self::Item: [const] Destruct,
1699        Self: Sized + [const] DoubleEndedBulk
1700    {
1701        struct Functor<P>
1702        {
1703            predicate: P
1704        }
1705        const impl<T, P> FnOnce<(usize, T)> for Functor<P>
1706        where
1707            P: [const] FnMut(T) -> bool + [const] Destruct
1708        {
1709            type Output = ControlFlow<usize, usize>;
1710
1711            extern "rust-call" fn call_once(mut self, args: (usize, T)) -> Self::Output
1712            {
1713                self.call_mut(args)
1714            }
1715        }
1716        const impl<T, P> FnMut<(usize, T)> for Functor<P>
1717        where
1718            P: [const] FnMut(T) -> bool
1719        {
1720            extern "rust-call" fn call_mut(&mut self, (mut i, x): (usize, T)) -> Self::Output
1721            {
1722                i -= 1;
1723                if (self.predicate)(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i) }
1724            }
1725        }
1726
1727        let len = self.len();
1728        self.try_rfold(len, Functor { predicate }).break_value()
1729    }
1730
1731    /// Returns the maximum element of a bulk.
1732    ///
1733    /// If several elements are equally maximum, the last element is
1734    /// returned. If the bulk is empty, [`None`] is returned.
1735    ///
1736    /// # Examples
1737    ///
1738    /// ```
1739    /// use bulks::*;
1740    ///
1741    /// let a = [1, 2, 3];
1742    /// let b: [u32; 0] = [];
1743    ///
1744    /// assert_eq!(a.into_bulk().max(), Some(3));
1745    /// assert_eq!(b.into_bulk().max(), None);
1746    /// ```
1747    #[inline]
1748    fn max(self) -> Option<Self::Item>
1749    where
1750        Self: Sized,
1751        Self::Item: [const] Ord + [const] Destruct
1752    {
1753        self.max_by(Ord::cmp)
1754    }
1755
1756    // TODO
1757    /*#[cfg(feature = "async")]
1758    #[rustc_non_const_trait_method]
1759    fn max_async(self) -> MaxByAsync<Self, fn(&Self::Item, &Self::Item) -> Ordering>
1760    where
1761        Self: BufferableBulk + Sized,
1762        Self::Item: Ord
1763    {
1764        self.max_by_async(Ord::cmp as fn(_, _) -> _)
1765    }*/
1766
1767    /// Returns the minimum element of a bulk.
1768    ///
1769    /// If several elements are equally minimum, the first element is returned.
1770    /// If the bulk is empty, [`None`] is returned.
1771    ///
1772    /// # Examples
1773    ///
1774    /// ```
1775    /// use bulks::*;
1776    ///
1777    /// let a = [1, 2, 3];
1778    /// let b: [u32; 0] = [];
1779    ///
1780    /// assert_eq!(a.into_bulk().min(), Some(1));
1781    /// assert_eq!(b.into_bulk().min(), None);
1782    /// ```
1783    #[inline]
1784    fn min(self) -> Option<Self::Item>
1785    where
1786        Self: Sized,
1787        Self::Item: [const] Ord + [const] Destruct
1788    {
1789        self.min_by(Ord::cmp)
1790    }
1791
1792    // TODO
1793    /*#[cfg(feature = "async")]
1794    #[rustc_non_const_trait_method]
1795    fn min_async(self) -> MinByAsync<Self, fn(&Self::Item, &Self::Item) -> Ordering>
1796    where
1797        Self: BufferableBulk + Sized,
1798        Self::Item: Ord
1799    {
1800        self.min_by_async(Ord::cmp as fn(_, _) -> _)
1801    }*/
1802
1803    /// Returns the element that gives the maximum value from the
1804    /// specified function.
1805    ///
1806    /// If several elements are equally maximum, the last element is
1807    /// returned. If the iterator is empty, [`None`] is returned.
1808    ///
1809    /// # Examples
1810    ///
1811    /// ```
1812    /// use bulks::*;
1813    ///
1814    /// let a = [-3_i32, 0, 1, 5, -10];
1815    /// assert_eq!(a.into_iter().max_by_key(|x| x.abs()).unwrap(), -10);
1816    /// ```
1817    fn max_by_key<B, F>(self, keygen: F) -> Option<Self::Item>
1818    where
1819        Self: Sized,
1820        Self::Item: [const] Destruct,
1821        F: [const] FnMut(&Self::Item) -> B + [const] Destruct,
1822        B: [const] Ord + [const] Destruct
1823    {
1824        struct Keygen<F>
1825        {
1826            keygen: F
1827        }
1828        const impl<T, F, K> FnOnce<(T,)> for Keygen<F>
1829        where
1830            F: [const] FnMut(&T) -> K + [const] Destruct
1831        {
1832            type Output = (K, T);
1833
1834            extern "rust-call" fn call_once(mut self, args: (T,)) -> Self::Output
1835            {
1836                self.call_mut(args)
1837            }
1838        }
1839        const impl<T, F, K> FnMut<(T,)> for Keygen<F>
1840        where
1841            F: [const] FnMut(&T) -> K
1842        {
1843            extern "rust-call" fn call_mut(&mut self, (value,): (T,)) -> Self::Output
1844            {
1845                let key = (self.keygen)(&value);
1846                (key, value)
1847            }
1848        }
1849
1850        const fn compare_keys<T, K>((lhs_key, _): &(K, T), (rhs_key, _): &(K, T)) -> Ordering
1851        where
1852            K: [const] Ord
1853        {
1854            lhs_key.cmp(rhs_key)
1855        }
1856
1857        let (_, x) = self.map(Keygen { keygen }).max_by(compare_keys)?;
1858        Some(x)
1859    }
1860
1861    // TODO
1862    /*fn max_async_by_key<B, F>(self, keygen: F) -> impl Future<Output = Option<Self::Item>>
1863    where
1864        Self: Sized,
1865        F: for<'a> FnMut<(&'a Self::Item,), Output: Future<Output = B>>,
1866        B: Ord
1867    {
1868        let (_, x) = self.map_async(async |x| (keygen(&x), x)).max_async_by(async |(a, _), (b, _)| a.cmp(b))?;
1869        Some(x)
1870    }*/
1871
1872    /// Returns the element that gives the maximum value with respect to the
1873    /// specified comparison function.
1874    ///
1875    /// If several elements are equally maximum, the last element is
1876    /// returned. If the bulk is empty, [`None`] is returned.
1877    ///
1878    /// # Examples
1879    ///
1880    /// ```
1881    /// use bulks::*;
1882    ///
1883    /// let a = [-3_i32, 0, 1, 5, -10];
1884    /// assert_eq!(a.into_bulk().max_by(|x, y| x.cmp(y)).unwrap(), 5);
1885    /// ```
1886    fn max_by<F>(self, compare: F) -> Option<Self::Item>
1887    where
1888        Self: Sized,
1889        Self::Item: [const] Destruct,
1890        F: [const] FnMut(&Self::Item, &Self::Item) -> Ordering + [const] Destruct
1891    {
1892        struct Functor<F>
1893        {
1894            compare: F
1895        }
1896        const impl<F, T> FnOnce<(T, T)> for Functor<F>
1897        where
1898            F: [const] FnMut(&T, &T) -> Ordering + [const] Destruct,
1899            T: [const] Destruct
1900        {
1901            type Output = T;
1902
1903            extern "rust-call" fn call_once(mut self, args: (T, T)) -> Self::Output
1904            {
1905                self.call_mut(args)
1906            }
1907        }
1908        const impl<F, T> FnMut<(T, T)> for Functor<F>
1909        where
1910            F: [const] FnMut(&T, &T) -> Ordering,
1911            T: [const] Destruct
1912        {
1913            extern "rust-call" fn call_mut(&mut self, (v1, v2): (T, T)) -> Self::Output
1914            {
1915                core::cmp::max_by(v1, v2, &mut self.compare)
1916            }
1917        }
1918
1919        self.reduce(Functor { compare })
1920    }
1921
1922    // TODO
1923    /*#[cfg(feature = "async")]
1924    #[rustc_non_const_trait_method]
1925    fn max_async_by<F>(self, mut compare: F) -> MaxAsyncBy<Self, F>
1926    where
1927        Self: Sized,
1928        F: for<'a> FnMut<(&'a Self::Item, &'a Self::Item), Output: Future<Output = Ordering>>
1929    {
1930        async fn max_async_by<T, Y: Future<Output = Ordering>, F: FnOnce(&T, &T) -> Y>(v1: T, v2: T, compare: F) -> T
1931        {
1932            if compare(&v1, &v2).await.is_gt() { v1 } else { v2 }
1933        }
1934
1935        self.reduce_async(async |a, b| max_async_by(a, b, &mut compare).await)
1936    }*/
1937
1938    /// Returns the element that gives the minimum value from the
1939    /// specified function.
1940    ///
1941    /// If several elements are equally minimum, the first element is
1942    /// returned. If the bulk is empty, [`None`] is returned.
1943    ///
1944    /// # Examples
1945    ///
1946    /// ```
1947    /// use bulks::*;
1948    ///
1949    /// let a = [-3_i32, 0, 1, 5, -10];
1950    /// assert_eq!(a.into_bulk().min_by_key(|x| x.abs()).unwrap(), 0);
1951    /// ```
1952    fn min_by_key<B, F>(self, keygen: F) -> Option<Self::Item>
1953    where
1954        Self: Sized,
1955        Self::Item: [const] Destruct,
1956        F: [const] FnMut(&Self::Item) -> B + [const] Destruct,
1957        B: [const] Ord + [const] Destruct
1958    {
1959        struct Keygen<F>
1960        {
1961            keygen: F
1962        }
1963        const impl<T, F, K> FnOnce<(T,)> for Keygen<F>
1964        where
1965            F: [const] FnMut(&T) -> K + [const] Destruct
1966        {
1967            type Output = (K, T);
1968
1969            extern "rust-call" fn call_once(mut self, args: (T,)) -> Self::Output
1970            {
1971                self.call_mut(args)
1972            }
1973        }
1974        const impl<T, F, K> FnMut<(T,)> for Keygen<F>
1975        where
1976            F: [const] FnMut(&T) -> K
1977        {
1978            extern "rust-call" fn call_mut(&mut self, (value,): (T,)) -> Self::Output
1979            {
1980                let key = (self.keygen)(&value);
1981                (key, value)
1982            }
1983        }
1984
1985        const fn compare_keys<T, K>((lhs_key, _): &(K, T), (rhs_key, _): &(K, T)) -> Ordering
1986        where
1987            K: [const] Ord
1988        {
1989            lhs_key.cmp(rhs_key)
1990        }
1991
1992        let (_, x) = self.map(Keygen { keygen }).min_by(compare_keys)?;
1993        Some(x)
1994    }
1995
1996    // TODO
1997    /*fn min_async_by_key<B, F>(self, keygen: F) -> impl Future<Output = Option<Self::Item>>
1998    where
1999        Self: Sized,
2000        F: for<'a> FnMut<(&'a Self::Item,), Output: Future<Output = B>>,
2001        B: Ord
2002    {
2003        let (_, x) = self.map(async |x| (keygen(&x), x)).min_async_by(async |(a, _), (b, _)| a.cmp(b))?;
2004        Some(x)
2005    }*/
2006
2007    /// Returns the element that gives the minimum value with respect to the
2008    /// specified comparison function.
2009    ///
2010    /// If several elements are equally minimum, the first element is
2011    /// returned. If the bulk is empty, [`None`] is returned.
2012    ///
2013    /// # Examples
2014    ///
2015    /// ```
2016    /// use bulks::*;
2017    ///
2018    /// let a = [-3_i32, 0, 1, 5, -10];
2019    /// assert_eq!(a.into_bulk().min_by(|x, y| x.cmp(y)).unwrap(), -10);
2020    /// ```
2021    fn min_by<F>(self, compare: F) -> Option<Self::Item>
2022    where
2023        Self: Sized,
2024        Self::Item: [const] Destruct,
2025        F: [const] FnMut(&Self::Item, &Self::Item) -> Ordering + [const] Destruct
2026    {
2027        struct Functor<F>
2028        {
2029            compare: F
2030        }
2031        const impl<F, T> FnOnce<(T, T)> for Functor<F>
2032        where
2033            F: [const] FnMut(&T, &T) -> Ordering + [const] Destruct,
2034            T: [const] Destruct
2035        {
2036            type Output = T;
2037
2038            extern "rust-call" fn call_once(mut self, args: (T, T)) -> Self::Output
2039            {
2040                self.call_mut(args)
2041            }
2042        }
2043        const impl<F, T> FnMut<(T, T)> for Functor<F>
2044        where
2045            F: [const] FnMut(&T, &T) -> Ordering,
2046            T: [const] Destruct
2047        {
2048            extern "rust-call" fn call_mut(&mut self, (v1, v2): (T, T)) -> Self::Output
2049            {
2050                core::cmp::min_by(v1, v2, &mut self.compare)
2051            }
2052        }
2053
2054        self.reduce(Functor { compare })
2055    }
2056
2057    // TODO
2058    /*fn min_async_by<F>(self, mut compare: F) -> impl Future<Output = Option<Self::Item>>
2059    where
2060        Self: Sized,
2061        F: for<'a> FnMut<(&'a Self::Item, &'a Self::Item), Output: Future<Output = Ordering>>
2062    {
2063        async fn min_async_by<T, Y: Future<Output = Ordering>, F: FnOnce(&T, &T) -> Y>(v1: T, v2: T, compare: F) -> T
2064        {
2065            if compare(&v1, &v2).await.is_le() { v1 } else { v2 }
2066        }
2067
2068        self.reduce_async(async |a, b| min_async_by(a, b, &mut compare).await)
2069    }*/
2070
2071    /// Creates a bulk starting at the same point, but stepping by
2072    /// the given amount at each iteration.
2073    ///
2074    /// Similar to [`Iterator::step_by`].
2075    ///
2076    /// # Panics
2077    ///
2078    /// The method will panic if the given step is `0`.
2079    ///
2080    /// # Examples
2081    ///
2082    /// ```
2083    /// # #![feature(generic_const_exprs)]
2084    /// use bulks::*;
2085    ///
2086    /// let a = [0, 1, 2, 3, 4, 5];
2087    ///
2088    /// let mut bulk = a.into_bulk().step_by([(); 2]);
2089    /// let a_even: [_; _] = bulk.collect();
2090    ///
2091    /// assert_eq!(a_even, [0, 2, 4]);
2092    ///
2093    /// let mut bulk = a.into_bulk().skip([(); 1]).step_by([(); 2]);
2094    /// let a_odd: [_; _] = bulk.collect();
2095    ///
2096    /// assert_eq!(a_odd, [1, 3, 5]);
2097    /// ```
2098    #[inline]
2099    #[track_caller]
2100    fn step_by<L>(self, step: L) -> StepBy<Self, L::Length<()>>
2101    where
2102        Self: Sized,
2103        L: LengthValue
2104    {
2105        StepBy::new(self, step)
2106    }
2107
2108    /// Takes two bulks and creates a new bulk over both in sequence.
2109    ///
2110    /// In other words, it links two bulks together, in a chain. 🔗
2111    ///
2112    /// Similar to [`Iterator::chain`].
2113    ///
2114    /// # Examples
2115    ///
2116    /// Basic usage:
2117    ///
2118    /// ```
2119    /// # #![feature(generic_const_exprs)]
2120    /// use bulks::*;
2121    ///
2122    /// let s1 = b"abc";
2123    /// let s2 = b"def";
2124    ///
2125    /// let mut bulk = s1.into_bulk()
2126    ///     .chain(s2)
2127    ///     .copied();
2128    ///
2129    /// let s: [_; _] = bulk.collect();
2130    ///
2131    /// assert_eq!(s, *b"abcdef");
2132    /// ```
2133    ///
2134    /// Since the argument to [`chain()`](Bulk::chain) uses [`IntoBulk`], we can pass
2135    /// anything that can be converted into a [`Bulk`], not just a
2136    /// [`Bulk`] itself. For example, arrays (`[T; _]`) implement
2137    /// [`IntoBulk`], and so can be passed to [`chain()`](Bulk::chain) directly:
2138    ///
2139    /// ```
2140    /// # #![feature(generic_const_exprs)]
2141    /// use bulks::*;
2142    ///
2143    /// let a1 = [1, 2, 3];
2144    /// let a2 = [4, 5, 6];
2145    ///
2146    /// let mut bulk = a1.into_bulk()
2147    ///     .chain(a2);
2148    ///
2149    /// let a: [_; _] = bulk.collect();
2150    ///
2151    /// assert_eq!(a, [1, 2, 3, 4, 5, 6]);
2152    /// ```
2153    #[inline]
2154    #[track_caller]
2155    fn chain<U>(self, other: U) -> Chain<Self, U::IntoBulk>
2156    where
2157        Self: Sized,
2158        U: [const] IntoBulk<Item = Self::Item>
2159    {
2160        Chain::new(self, other.into_bulk())
2161    }
2162
2163    /// 'Zips up' two bulks or iterators into a single bulk of pairs. One of them must be a bulk.
2164    ///
2165    /// Similar to [`Iterator::zip`].
2166    ///
2167    /// # Examples
2168    ///
2169    /// Basic usage:
2170    ///
2171    /// ```
2172    /// # #![feature(generic_const_exprs)]
2173    /// use bulks::*;
2174    ///
2175    /// let s1 = b"abc".into_bulk().copied();
2176    /// let s2 = b"def".into_bulk().copied();
2177    ///
2178    /// let mut bulk = s1.zip(s2);
2179    ///
2180    /// let s: [_; _] = bulk.collect();
2181    ///
2182    /// assert_eq!(s, [(b'a', b'd'), (b'b', b'e'), (b'c', b'f')]);
2183    /// ```
2184    ///
2185    /// Since the argument to [`zip()`](Bulk::zip) uses [`IntoBulk`], we can pass
2186    /// anything that can be converted into a [`Bulk`], not just a
2187    /// [`Bulk`] itself. For example, arrays (`[T]`) implement
2188    /// [`IntoBulk`], and so can be passed to [`zip()`](Bulk::zip) directly:
2189    ///
2190    /// ```
2191    /// # #![feature(generic_const_exprs)]
2192    /// use bulks::*;
2193    ///
2194    /// let a1 = [1, 2, 3];
2195    /// let a2 = [4, 5, 6];
2196    ///
2197    /// let mut bulk = a1.into_bulk().zip(a2);
2198    ///
2199    /// let a: [_; _] = bulk.collect();
2200    ///
2201    /// assert_eq!(a, [(1, 4), (2, 5), (3, 6)]);
2202    /// ```
2203    ///
2204    /// `zip()` is often used to zip an infinite iterator to a finite one.
2205    /// This works because the finite iterator will eventually return [`None`],
2206    /// ending the zipper. Zipping with `(0..)` can look a lot like [`enumerate`]:
2207    ///
2208    /// ```
2209    /// use bulks::*;
2210    ///
2211    /// let enumerate: [_; _] = (*b"foo").into_bulk().enumerate().collect();
2212    ///
2213    /// let zipper: Vec<_> = bulks::rzip(0.., *b"foo").collect();
2214    ///
2215    /// assert_eq!((0, b'f'), enumerate[0]);
2216    /// assert_eq!((0, b'f'), zipper[0]);
2217    ///
2218    /// assert_eq!((1, b'o'), enumerate[1]);
2219    /// assert_eq!((1, b'o'), zipper[1]);
2220    ///
2221    /// assert_eq!((2, b'o'), enumerate[2]);
2222    /// assert_eq!((2, b'o'), zipper[2]);
2223    /// ```
2224    ///
2225    /// It can be more readable to use [`bulks::zip`](crate::zip):
2226    ///
2227    /// ```
2228    /// # #![feature(generic_const_exprs)]
2229    /// use bulks::*;
2230    ///
2231    /// let a = [1, 2, 3];
2232    /// let b = [2, 3, 4];
2233    ///
2234    /// let mut zipped = bulks::zip(
2235    ///     a.into_bulk().map(|x| x * 2).skip([(); 1]),
2236    ///     b.into_bulk().map(|x| x * 2).skip([(); 1]),
2237    /// );
2238    ///
2239    /// let c: [_; _] = zipped.collect();
2240    ///
2241    /// assert_eq!(c, [(4, 6), (6, 8)]);
2242    /// ```
2243    ///
2244    /// compared to:
2245    ///
2246    /// ```
2247    /// # #![feature(generic_const_exprs)]
2248    /// # use bulks::*;
2249    /// #
2250    /// # let a = [1, 2, 3];
2251    /// # let b = [2, 3, 4];
2252    /// #
2253    /// let mut zipped = a.into_bulk()
2254    ///     .map(|x| x * 2)
2255    ///     .skip([(); 1])
2256    ///     .zip(b.into_bulk()
2257    ///         .map(|x| x * 2)
2258    ///         .skip([(); 1])
2259    ///     );
2260    /// #
2261    /// # let c: [_; _] = zipped.collect();
2262    /// # assert_eq!(c, [(4, 6), (6, 8)]);
2263    /// ```
2264    #[inline]
2265    #[track_caller]
2266    fn zip<U>(self, other: U) -> Zip<Self, <<U as IntoContained>::IntoContained as IntoBulk>::IntoBulk>
2267    where
2268        Self: Sized,
2269        U: [const] IntoContainedBy<Self>
2270    {
2271        crate::zip(self, other)
2272    }
2273
2274    /// Merges two bulks or iterators into a single bulk using a merging function.
2275    ///
2276    /// Similar to [`Bulk::zip`], followed by [`Bulk::map`], but keeps the tail if the length of the two bulks differ.
2277    ///
2278    /// # Examples
2279    ///
2280    /// Basic usage:
2281    ///
2282    /// ```
2283    /// # #![feature(generic_const_exprs)]
2284    /// use bulks::*;
2285    ///
2286    /// use core::ops::Add;
2287    ///
2288    /// let s1 = b"abc".into_bulk().copied();
2289    /// let s2 = b"defg".into_bulk().copied();
2290    ///
2291    /// let mut bulk = s1.merge(s2, Add::add);
2292    ///
2293    /// let s: [_; _] = bulk.collect_array();
2294    ///
2295    /// assert_eq!(s, [b'a' + b'd', b'b' + b'e', b'c' + b'f', b'g']);
2296    /// ```
2297    #[inline]
2298    #[track_caller]
2299    fn merge<U, F, O>(self, other: U, merger: F) -> Merge<Self, U::IntoBulk, F>
2300    where
2301        Self: Sized,
2302        U: [const] IntoBulk,
2303        Self::Item: Into<O>,
2304        U::Item: Into<O>,
2305        F: FnMut(Self::Item, U::Item) -> O
2306    {
2307        crate::merge(self, other, merger)
2308    }
2309
2310    /// Creates a new bulk which places a copy of `separator` between adjacent
2311    /// items of the original bulk.
2312    ///
2313    /// Similar to [`Iterator::intersperse`].
2314    ///
2315    /// In case `separator` does not implement [`Clone`](core::clone::Clone) or needs to be
2316    /// computed every time, use [`intersperse_with`](Bulk::intersperse_with).
2317    ///
2318    /// # Examples
2319    ///
2320    /// Basic usage:
2321    ///
2322    /// ```
2323    /// # #![feature(generic_const_exprs)]
2324    /// use bulks::*;
2325    ///
2326    /// let mut a: [_; _] = [0, 1, 2].into_bulk().intersperse(100).collect();
2327    ///
2328    /// assert_eq!(a, [0, 100, 1, 100, 2]);
2329    /// ```
2330    ///
2331    /// `intersperse` can be very useful to join a bulk's items using a common element:
2332    /// ```
2333    /// # #![feature(generic_const_exprs)]
2334    /// use bulks::*;
2335    ///
2336    /// let words = ["Hello", "World", "!"];
2337    /// let hello: String = words.into_bulk().intersperse(" ").collect();
2338    /// assert_eq!(hello, "Hello World !");
2339    /// ```
2340    #[inline]
2341    #[track_caller]
2342    fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
2343    where
2344        Self: Sized,
2345        Self::Item: Clone
2346    {
2347        Intersperse::new(self, separator)
2348    }
2349
2350    /// Creates a new bulk which places an item generated by `separator`
2351    /// between adjacent items of the original bulk.
2352    ///
2353    /// The closure will be called exactly once each time an item is placed
2354    /// between two adjacent items from the underlying bulk; specifically,
2355    /// the closure is not called if the underlying bulk has less than
2356    /// two items.
2357    ///
2358    /// Similar to [`Iterator::intersperse_with`].
2359    ///
2360    /// If the bulk's item implements [`Clone`](core::clone::Clone), it may be easier to use
2361    /// [`intersperse`](Bulk::intersperse).
2362    ///
2363    /// # Examples
2364    ///
2365    /// Basic usage:
2366    ///
2367    /// ```
2368    /// # #![feature(generic_const_exprs)]
2369    /// use bulks::*;
2370    ///
2371    /// #[derive(PartialEq, Debug)]
2372    /// struct NotClone(usize);
2373    ///
2374    /// let v = [NotClone(0), NotClone(1), NotClone(2)];
2375    /// let u: [_; _] = v.into_bulk().intersperse_with(|| NotClone(99)).collect();
2376    ///
2377    /// assert_eq!(u, [NotClone(0), NotClone(99), NotClone(1), NotClone(99), NotClone(2)]);
2378    /// ```
2379    ///
2380    /// [`intersperse_with`](Bulk::intersperse_with) can be used in situations where the separator needs
2381    /// to be computed:
2382    /// ```
2383    /// # #![feature(generic_const_exprs)]
2384    /// use bulks::*;
2385    ///
2386    /// let src = ["Hello", "to", "all", "people", "!!"].bulk().copied();
2387    ///
2388    /// // The closure mutably borrows its context to generate an item.
2389    /// let mut happy_emojis = [" ❤️ ", " 😀 "].into_iter();
2390    /// let separator = || happy_emojis.next().unwrap_or(" 🦀 ");
2391    ///
2392    /// let result: String = src.intersperse_with(separator).collect();
2393    ///
2394    /// assert_eq!(result, "Hello ❤️ to 😀 all 🦀 people 🦀 !!");
2395    /// ```
2396    #[inline]
2397    #[track_caller]
2398    fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
2399    where
2400        Self: Sized,
2401        G: FnMut() -> Self::Item
2402    {
2403        IntersperseWith::new(self, separator)
2404    }
2405
2406    /// Takes a closure and creates a bulk which calls that closure on each
2407    /// element.
2408    ///
2409    /// [`map()`](Bulk::map) transforms one bulk into another, by means of its argument:
2410    /// something that implements [`FnMut`]. It produces a new bulk which
2411    /// calls this closure on each element of the original bulk.
2412    ///
2413    /// Similar to [`Iterator::map`].
2414    ///
2415    /// # Examples
2416    ///
2417    /// Basic usage:
2418    ///
2419    /// ```
2420    /// use bulks::*;
2421    ///
2422    /// let a = [1, 2, 3];
2423    ///
2424    /// let mut b: [_; _] = a.bulk().map(|x| 2 * x).collect();
2425    ///
2426    /// assert_eq!(b, [2, 4, 6]);
2427    /// ```
2428    ///
2429    /// If you're doing some sort of side effect, prefer [`for`] to [`map()`](Bulk::map):
2430    ///
2431    /// ```
2432    /// # #![allow(unused_must_use)]
2433    /// use bulks::*;
2434    ///
2435    /// // don't do this:
2436    /// (0..5).into_bulk().map(|x| println!("{x}"));
2437    ///
2438    /// // it won't even execute, as it is lazy. Rust will warn you about this.
2439    ///
2440    /// // Instead, use a for-loop:
2441    /// for x in (0..5).into_bulk()
2442    /// {
2443    ///     println!("{x}");
2444    /// }
2445    /// ```
2446    ///
2447    /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
2448    #[inline]
2449    #[track_caller]
2450    fn map<B, F>(self, f: F) -> Map<Self, F>
2451    where
2452        Self: Sized,
2453        F: FnMut(Self::Item) -> B
2454    {
2455        Map::new(self, f)
2456    }
2457
2458    /// Creates a bulk which gives the current index together with its values.
2459    ///
2460    /// The bulk returned yields pairs `(i, val)`, where `i` is the
2461    /// current index of iteration and `val` is its corresponding value.
2462    ///
2463    /// Similar to [`Iterator::enumerate`].
2464    ///
2465    /// [`enumerate()`](Bulk::enumerate) keeps its count as a [`usize`]. If you want to count by a
2466    /// different sized integer, use [`enumerate_from`](Bulk::enumerate_from) instead.
2467    ///
2468    /// # Overflow Behavior
2469    ///
2470    /// The method does no guarding against overflows, so enumerating more than
2471    /// [`usize::MAX`] elements either produces the wrong result or panics. If
2472    /// overflow checks are enabled, a panic is guaranteed.
2473    ///
2474    /// # Panics
2475    ///
2476    /// The returned bulk might panic if the to-be-returned index would
2477    /// overflow a [`usize`].
2478    ///
2479    /// # Examples
2480    ///
2481    /// ```
2482    /// use bulks::*;
2483    ///
2484    /// let a = ['a', 'b', 'c'];
2485    ///
2486    /// let b = a.into_bulk()
2487    ///     .enumerate()
2488    ///     .collect_array();
2489    ///
2490    /// assert_eq!(b, [(0, 'a'), (1, 'b'), (2, 'c')]);
2491    /// ```
2492    #[inline]
2493    #[track_caller]
2494    fn enumerate(self) -> Enumerate<Self>
2495    where
2496        Self: Sized
2497    {
2498        Enumerate::new(self)
2499    }
2500
2501    /// Creates a bulk which gives the current index counting from a given initial index together with its values.
2502    ///
2503    /// The bulk returned yields pairs `(i, val)`, where `i` is the
2504    /// current index of iteration and `val` is its corresponding value.
2505    ///
2506    /// This is similar to [`Bulk::enumerate`], except here a different type and initial value for counting can be used.
2507    /// For counting an [`usize`] from 0 and up, [`Bulk::enumerate`] is a better alternative.
2508    ///
2509    /// # Overflow Behavior
2510    ///
2511    /// The method does no guarding against overflows, so enumerating more elements than supported values of `U`
2512    /// either produces the wrong result or panics. If
2513    /// overflow checks are enabled, a panic will happen depending how [`Step::forward`] is implemented for `U`.
2514    ///
2515    /// # Panics
2516    ///
2517    /// The returned bulk might panic if the to-be-returned index would
2518    /// overflow.
2519    ///
2520    /// # Examples
2521    ///
2522    /// ```
2523    /// use bulks::*;
2524    ///
2525    /// let a = ['a', 'b', 'c'];
2526    ///
2527    /// let b = a.into_bulk()
2528    ///     .enumerate_from(1)
2529    ///     .collect_array();
2530    ///
2531    /// assert_eq!(b, [(1, 'a'), (2, 'b'), (3, 'c')]);
2532    /// ```
2533    #[inline]
2534    #[track_caller]
2535    fn enumerate_from<U>(self, initial_count: U) -> EnumerateFrom<Self, U>
2536    where
2537        Self: Sized,
2538        U: Step + Copy
2539    {
2540        EnumerateFrom::new(self, initial_count)
2541    }
2542
2543    /// Creates a bulk that skips the first `n` elements.
2544    ///
2545    /// Similar to [`Iterator::skip`].
2546    ///
2547    /// [`skip(n)`](Bulk::skip) skips elements until `n` elements are skipped or the end of the
2548    /// bulk is reached (whichever happens first). The returned bulk will yield the remaining elements.
2549    /// If the original bulk is too short, then the returned bulk is empty.
2550    ///
2551    /// # Examples
2552    ///
2553    /// ```
2554    /// # #![feature(generic_const_exprs)]
2555    /// use bulks::*;
2556    ///
2557    /// let a = [1, 2, 3];
2558    ///
2559    /// let b: [_; _] = a.into_bulk().skip([(); 2]).collect();
2560    /// let c: Vec<_> = a.into_bulk().skip(2).collect();
2561    ///
2562    /// assert_eq!(b, [3]);
2563    /// assert_eq!(c, [3]);
2564    /// ```
2565    #[inline]
2566    #[track_caller]
2567    fn skip<L>(self, n: L) -> Skip<Self, L::Length<()>>
2568    where
2569        Self: Sized,
2570        L: LengthValue
2571    {
2572        Skip::new(self, n)
2573    }
2574
2575    /// Creates a bulk for the first `n` elements, or fewer
2576    /// if the underlying bulk/iterator is shorter.
2577    ///
2578    /// [`take(n)`](Bulk::take) yields elements until `n` elements are yielded or the end of the
2579    /// bulk is reached (whichever happens first).
2580    /// The returned bulk is a prefix of length `n` if the original bulk/iterator
2581    /// contains at least `n` elements, otherwise it contains all of the
2582    /// (fewer than `n`) elements of the original bulk/iterator.
2583    ///
2584    /// # Examples
2585    ///
2586    /// Basic usage:
2587    ///
2588    /// ```
2589    /// # #![feature(generic_const_exprs)]
2590    /// use bulks::*;
2591    ///
2592    /// let a = [1, 2, 3];
2593    ///
2594    /// let b: Vec<_> = a.into_bulk().take([(); 2]).collect();
2595    ///
2596    /// assert_eq!(b, [1, 2]);
2597    /// ```
2598    ///
2599    /// `take()` is often used with an infinite iterator, to make it finite:
2600    ///
2601    /// ```
2602    /// let a: Vec<_> = (0..).take(3).collect();
2603    ///
2604    /// assert_eq!(a, [0, 1, 2])
2605    /// ```
2606    ///
2607    /// If less than `n` elements are available,
2608    /// [`take`](Bulk::take) will limit itself to the size of the underlying bulk/iterator:
2609    ///
2610    /// ```
2611    /// # #![feature(generic_const_exprs)]
2612    /// use bulks::*;
2613    ///
2614    /// let v = [1, 2];
2615    /// let b: [_; _] = v.into_bulk().take([(); 5]).collect();
2616    ///
2617    /// assert_eq!(b, [1, 2])
2618    /// ```
2619    #[doc(alias = "limit")]
2620    #[inline]
2621    #[track_caller]
2622    fn take<L>(self, n: L) -> Take<Self, L::Length<()>>
2623    where
2624        Self: Sized,
2625        L: LengthValue
2626    {
2627        Take::new(self, n)
2628    }
2629
2630    /// Creates a bulk that works like map, but flattens nested structure.
2631    ///
2632    /// The [`map`](Bulk::map) adapter is very useful, but only when the closure
2633    /// argument produces values. If it produces something iterable instead, there's
2634    /// an extra layer of indirection. [`flat_map()`](Bulk::flat_map) will remove this extra layer
2635    /// on its own.
2636    ///
2637    /// Similar to [`Iterator::flat_map`].
2638    ///
2639    /// You can think of `flat_map(f)` as the semantic equivalent
2640    /// of [`map`](Bulk::map)ping, and then [`flatten`](Bulk::flatten)ing as in `map(f).flatten()`.
2641    ///
2642    /// # Examples
2643    ///
2644    /// ```
2645    /// # #![feature(generic_const_exprs)]
2646    /// use bulks::*;
2647    ///
2648    /// let words = [b"alpha", b"beta ", b"gamma"];
2649    ///
2650    /// let merged: String = words.into_bulk()
2651    ///     .flat_map(|&s| s.into_bulk().map(|b| char::from(b)))
2652    ///     .collect();
2653    /// assert_eq!(merged, "alphabeta gamma");
2654    /// ```
2655    #[inline]
2656    #[track_caller]
2657    fn flat_map<U, F>(self, f: F) -> FlatMap<Self, F>
2658    where
2659        Self: Sized,
2660        U: IntoBulk<IntoBulk: StaticBulk>,
2661        F: FnMut(Self::Item) -> U
2662    {
2663        FlatMap::new(self, f)
2664    }
2665
2666    /// Creates a bulk that flattens nested structure.
2667    ///
2668    /// This is useful when you have a bulk of bulk or a bulk of
2669    /// things that can be turned into bulks and you want to remove one
2670    /// level of indirection.
2671    ///
2672    /// Similar to [`Iterator::flatten`].
2673    ///
2674    /// # Examples
2675    ///
2676    /// Basic usage:
2677    ///
2678    /// ```
2679    /// # #![feature(generic_const_exprs)]
2680    /// use bulks::*;
2681    ///
2682    /// let data = [[1, 2, 3], [4, 5, 6]];
2683    /// let flattened: [_; _] = data.into_bulk().flatten().collect();
2684    /// assert_eq!(flattened, [1, 2, 3, 4, 5, 6]);
2685    /// ```
2686    ///
2687    /// Mapping and then flattening:
2688    ///
2689    /// ```
2690    /// # #![feature(generic_const_exprs)]
2691    /// use bulks::*;
2692    ///
2693    /// let words = [b"alpha", b"beta ", b"gamma"];
2694    ///
2695    /// let merged: String = words.into_bulk()
2696    ///     .map(|&s| s.into_bulk().map(|b| char::from(b)))
2697    ///     .flatten()
2698    ///     .collect();
2699    /// assert_eq!(merged, "alphabeta gamma");
2700    /// ```
2701    ///
2702    /// You can also rewrite this in terms of [`flat_map()`](Bulk::flat_map), which is preferable
2703    /// in this case since it conveys intent more clearly:
2704    ///
2705    /// ```
2706    /// # #![feature(generic_const_exprs)]
2707    /// use bulks::*;
2708    ///
2709    /// let words = [b"alpha", b"beta ", b"gamma"];
2710    ///
2711    /// let merged: String = words.into_bulk()
2712    ///     .flat_map(|&s| s.into_bulk().map(|b| char::from(b)))
2713    ///     .collect();
2714    /// assert_eq!(merged, "alphabeta gamma");
2715    /// ```
2716    ///
2717    /// Flattening only removes one level of nesting at a time:
2718    ///
2719    /// ```
2720    /// # #![feature(generic_const_exprs)]
2721    /// use bulks::*;
2722    ///
2723    /// let d3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]];
2724    ///
2725    /// let d2: [_; _] = d3.into_bulk().flatten().collect();
2726    /// assert_eq!(d2, [[1, 2], [3, 4], [5, 6], [7, 8]]);
2727    ///
2728    /// let d1: [_; _] = d3.into_bulk().flatten().flatten().collect();
2729    /// assert_eq!(d1, [1, 2, 3, 4, 5, 6, 7, 8]);
2730    /// ```
2731    ///
2732    /// Here we see that [`flatten()`](Bulk::flatten) does not perform a "deep" flatten.
2733    /// Instead, only one level of nesting is removed. That is, if you
2734    /// [`flatten()`](Bulk::flatten) a three-dimensional array, the result will be
2735    /// two-dimensional and not one-dimensional. To get a one-dimensional
2736    /// structure, you have to [`flatten()`](Bulk::flatten) again.
2737    #[inline]
2738    #[track_caller]
2739    fn flatten(self) -> Flatten<Self>
2740    where
2741        Self: Sized,
2742        Self::Item: IntoBulk<IntoBulk: StaticBulk>
2743    {
2744        Flatten::new(self)
2745    }
2746
2747    /// Calls the given function `f` for each contiguous window of size `N` over
2748    /// `self` and returns a bulk of the outputs of `f`. The windows during mapping will overlap.
2749    ///
2750    /// Similar to [`Iterator::map_windows`].
2751    ///
2752    /// In the following example, the closure is called three times with the
2753    /// arguments `&['a', 'b']`, `&['b', 'c']` and `&['c', 'd']` respectively.
2754    ///
2755    /// ```
2756    /// # #![feature(generic_const_exprs)]
2757    /// use bulks::*;
2758    ///
2759    /// let strings: [_; _] = b"abcd".bulk()
2760    ///     .map(|&c| char::from(c))
2761    ///     .map_windows(|[x, y]| format!("{}+{}", x, y))
2762    ///     .collect();
2763    ///
2764    /// assert_eq!(strings, ["a+b", "b+c", "c+d"]);
2765    /// ```
2766    ///
2767    /// Note that the const parameter `N` is usually inferred by the
2768    /// destructured argument in the closure.
2769    ///
2770    /// The returned bulk yields 𝑘 − `N` + 1 items (where 𝑘 is the number of
2771    /// items yielded by `self`). If 𝑘 is less than `N`, this method yields an
2772    /// empty bulk.
2773    ///
2774    /// # Panics
2775    ///
2776    /// Panics if `N` is zero.
2777    ///
2778    /// ```should_panic
2779    /// use bulks::*;
2780    ///
2781    /// let bulk = [0].into_bulk().map_windows(|&[]| ());
2782    /// ```
2783    ///
2784    /// # Examples
2785    ///
2786    /// Building the sums of neighboring numbers.
2787    ///
2788    /// ```
2789    /// # #![feature(generic_const_exprs)]
2790    /// use bulks::*;
2791    ///
2792    /// let w: [_; _] = [1, 3, 8, 1].bulk()
2793    ///     .map_windows(|&[a, b]| a + b)
2794    ///     .collect();
2795    ///
2796    /// assert_eq!(w, [1 + 3, 3 + 8, 8 + 1]);
2797    /// ```
2798    ///
2799    /// Since the elements in the following example implement [`Copy`], we can
2800    /// just copy the array and get a bulk of the windows.
2801    ///
2802    /// ```
2803    /// # #![feature(generic_const_exprs)]
2804    /// use bulks::*;
2805    ///
2806    /// let w: [[_; _]; _] = b"ferris".bulk()
2807    ///     .map_windows(|w: &[_; 3]| w.bulk()
2808    ///         .copied()
2809    ///         .copied()
2810    ///         .collect())
2811    ///     .collect();
2812    ///
2813    /// assert_eq!(w, [[b'f', b'e', b'r'], [b'e', b'r', b'r'], [b'r', b'r', b'i'], [b'r', b'i', b's']]);
2814    /// ```
2815    ///
2816    /// You can also use this function to check the sortedness of a bulk.
2817    /// For the simple case, rather use [`Bulk::is_sorted`].
2818    ///
2819    /// ```
2820    /// # #![feature(generic_const_exprs)]
2821    /// use bulks::*;
2822    ///
2823    /// let w: [_; _] = [0.5, 1.0, 3.5, 3.0, 8.5, 8.5, f32::NAN].bulk()
2824    ///     .map_windows(|[a, b]| a <= b)
2825    ///     .collect();
2826    ///
2827    /// assert_eq!(w, [true, true, false, true, true, false]);
2828    /// ```
2829    #[inline]
2830    #[track_caller]
2831    fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
2832    where
2833        Self: Sized,
2834        F: FnMut(&[Self::Item; N]) -> R
2835    {
2836        MapWindows::new(self, f)
2837    }
2838
2839    /// Does something with each element of a bulk, passing the value on.
2840    ///
2841    /// When using bulks, you'll often chain several of them together.
2842    /// While working on such code, you might want to check out what's
2843    /// happening at various parts in the pipeline. To do that, insert
2844    /// a call to [`inspect()`](Bulk::inspect).
2845    ///
2846    /// Similar to [`Iterator::inspect`].
2847    ///
2848    /// # Examples
2849    ///
2850    /// Basic usage:
2851    ///
2852    /// ```
2853    /// use bulks::*;
2854    ///
2855    /// let a = [1, 4, 2, 3];
2856    ///
2857    /// // this iterator sequence is complex.
2858    /// let sum = a.bulk()
2859    ///     .cloned()
2860    ///     .map(|x| if x % 2 == 0 {Some(x)} else {None})
2861    ///     .fold(0, |sum, i| sum + i.unwrap_or(0));
2862    ///
2863    /// println!("{sum}");
2864    ///
2865    /// // let's add some inspect() calls to investigate what's happening
2866    /// let sum = a.bulk()
2867    ///     .cloned()
2868    ///     .inspect(|x| println!("about to filter: {x}"))
2869    ///     .map(|x| if x % 2 == 0 {Some(x)} else {None})
2870    ///     .inspect(|x| if let Some(x) = x {println!("made it through filter: {x}")})
2871    ///     .fold(0, |sum, i| sum + i.unwrap_or(0));
2872    ///
2873    /// println!("{sum}");
2874    /// ```
2875    ///
2876    /// This will print:
2877    ///
2878    /// ```text
2879    /// 6
2880    /// about to filter: 1
2881    /// about to filter: 4
2882    /// made it through filter: 4
2883    /// about to filter: 2
2884    /// made it through filter: 2
2885    /// about to filter: 3
2886    /// 6
2887    /// ```
2888    ///
2889    /// Logging errors before discarding them:
2890    ///
2891    /// ```
2892    /// let lines = ["1", "2", "a"];
2893    ///
2894    /// let sum: i32 = lines
2895    ///     .iter()
2896    ///     .map(|line| line.parse::<i32>())
2897    ///     .inspect(|num| {
2898    ///         if let Err(ref e) = *num {
2899    ///             println!("Parsing error: {e}");
2900    ///         }
2901    ///     })
2902    ///     .filter_map(Result::ok)
2903    ///     .sum();
2904    ///
2905    /// println!("Sum: {sum}");
2906    /// ```
2907    ///
2908    /// This will print:
2909    ///
2910    /// ```text
2911    /// Parsing error: invalid digit found in string
2912    /// Sum: 3
2913    /// ```
2914    #[inline]
2915    #[track_caller]
2916    fn inspect<F>(self, f: F) -> Inspect<Self, F>
2917    where
2918        Self: Sized,
2919        F: FnMut(&Self::Item)
2920    {
2921        Inspect::new(self, f)
2922    }
2923
2924    /// Mutates with each element of a bulk, passing the value on.
2925    ///
2926    /// # Examples
2927    ///
2928    /// Basic usage:
2929    ///
2930    /// ```
2931    /// use bulks::*;
2932    ///
2933    /// let a = [1, 4, 2, 3];
2934    ///
2935    /// // this iterator sequence is complex.
2936    /// let b: [_; _] = a.into_bulk()
2937    ///     .mutate(|x| *x += 1)
2938    ///     .collect();
2939    ///
2940    /// assert_eq!(b, [2, 5, 3, 4]);
2941    /// ```
2942    #[inline]
2943    #[track_caller]
2944    fn mutate<F>(self, f: F) -> Mutate<Self, F>
2945    where
2946        Self: Sized,
2947        F: FnMut(&mut Self::Item)
2948    {
2949        Mutate::new(self, f)
2950    }
2951
2952    /// Transforms a bulk into a collection.
2953    ///
2954    /// [`collect()`](Bulk::collect) can take anything bulkable, and turn it into a relevant
2955    /// collection.
2956    ///
2957    /// Similar to [`Iterator::collect`].
2958    ///
2959    /// # Examples
2960    ///
2961    /// Basic usage:
2962    ///
2963    /// ```
2964    /// use bulks::*;
2965    ///
2966    /// let a = [1, 2, 3];
2967    ///
2968    /// let doubled: [i32; 3] = a.bulk()
2969    ///     .map(|x| x * 2)
2970    ///     .collect();
2971    ///
2972    /// assert_eq!(doubled, [2, 4, 6]);
2973    /// ```
2974    ///
2975    /// Note that we needed the `: [i32; 3]` on the left-hand side. This is because
2976    /// we could collect into, for example, a [`VecDeque<T>`](std::collections::VecDeque) instead:
2977    ///
2978    /// ```
2979    /// use std::collections::VecDeque;
2980    ///
2981    /// use bulks::*;
2982    ///
2983    /// let a = [1, 2, 3];
2984    ///
2985    /// let doubled: VecDeque<i32> = a.bulk()
2986    ///     .map(|x| x * 2)
2987    ///     .collect();
2988    ///
2989    /// assert_eq!(doubled[0], 2);
2990    /// assert_eq!(doubled[1], 4);
2991    /// assert_eq!(doubled[2], 6);
2992    /// ```
2993    ///
2994    /// Using the 'turbofish' instead of annotating `doubled`:
2995    ///
2996    /// ```
2997    /// use bulks::*;
2998    ///
2999    /// let a = [1, 2, 3];
3000    ///
3001    /// let doubled = a.bulk()
3002    ///     .map(|x| x * 2)
3003    ///     .collect::<[i32; 3], _>();
3004    ///
3005    /// assert_eq!(doubled, [2, 4, 6]);
3006    /// ```
3007    ///
3008    /// Because `collect()` only cares about what you're collecting into, you can
3009    /// still use a partial type hint, `_`, with the turbofish:
3010    ///
3011    /// ```
3012    /// use bulks::*;
3013    ///
3014    /// let a = [1, 2, 3];
3015    ///
3016    /// let doubled: [_; _] = a.bulk()
3017    ///     .map(|x| x * 2)
3018    ///     .collect();
3019    ///
3020    /// assert_eq!(doubled, [2, 4, 6]);
3021    /// ```
3022    ///
3023    /// Using `collect()` to make a [`String`](std::string::String):
3024    ///
3025    /// ```
3026    /// use bulks::*;
3027    ///
3028    /// let chars = ['g', 'd', 'k', 'k', 'n'];
3029    ///
3030    /// let hello: String = chars.bulk()
3031    ///     .copied()
3032    ///     .map(|x| x as u8)
3033    ///     .map(|x| (x + 1) as char)
3034    ///     .collect();
3035    ///
3036    /// assert_eq!(hello, "hello");
3037    /// ```
3038    ///
3039    /// If you have a list of [`Result<T, E>`][`Result`]s, you can use `collect()` to
3040    /// see if any of them failed:
3041    ///
3042    /// ```
3043    /// use bulks::*;
3044    ///
3045    /// let results = [Ok(1), Err("nope"), Ok(3), Err("bad")];
3046    ///
3047    /// let result: Result<[_; _], &str> = results.into_bulk().collect();
3048    ///
3049    /// // gives us the first error
3050    /// assert_eq!(result, Err("nope"));
3051    ///
3052    /// let results = [Ok(1), Ok(3)];
3053    ///
3054    /// let result: Result<[_; _], &str> = results.into_bulk().collect();
3055    ///
3056    /// // gives us the list of answers
3057    /// assert_eq!(result, Ok([1, 3]));
3058    /// ```
3059    #[inline]
3060    #[must_use = "if you really need to exhaust the bulk, consider `.for_each(drop)` instead"]
3061    fn collect<C, A>(self) -> C
3062    where
3063        Self: Sized,
3064        C: [const] FromBulk<A>,
3065        A: CollectionAdapter<Elem = Self::Item> + [const] CollectionStrategy<Self::MinLength, Self::MaxLength, C> + ?Sized
3066    {
3067        FromBulk::from_bulk(self)
3068    }
3069
3070    #[cfg(feature = "async")]
3071    #[rustc_non_const_trait_method]
3072    fn collect_async<C, A>(self) -> CollectAsync<Self, C, A>
3073    where
3074        Self: BufferableBulk + Sized,
3075        Self::Item: Future,
3076        C: FromBulk<A>,
3077        A: CollectionAdapter<Elem = <Self::Item as Future>::Output> + CollectionStrategy<Self::MinLength, Self::MaxLength, C> + ?Sized
3078    {
3079        CollectAsync::new(self)
3080    }
3081
3082    /// Fallibly transforms a bulk into a collection, short circuiting if
3083    /// a failure is encountered.
3084    ///
3085    /// `try_collect()` is a variation of [`collect()`][`Bulk::collect`] that allows fallible
3086    /// conversions during collection. Its main use case is simplifying conversions from
3087    /// iterators yielding [`Option<T>`][`Option`] into `Option<Collection<T>>`, or similarly for other [`Try`]
3088    /// types (e.g. [`Result`]).
3089    ///
3090    /// Importantly, `try_collect()` doesn't require that the outer [`Try`] type also implements [`FromBulk`];
3091    /// only the inner type produced on `Try::Output` must implement it. Concretely,
3092    /// this means that collecting into `ControlFlow<_, Vec<i32>>` is valid because `Vec<i32>` implements
3093    /// [`FromBulk`], even though [`ControlFlow`] doesn't.
3094    ///
3095    /// Unlike with [`Iterator::try_collect`], the bulk is fully consumed even if it short-circuits.
3096    /// A short-circuit will cause the rest of the elements of the bulk to be dropped.
3097    ///
3098    /// # Examples
3099    ///
3100    /// Successfully collecting a bulk of `Option<i32>` into `Option<[i32; _]>`:
3101    /// ```
3102    /// use bulks::*;
3103    ///
3104    /// let u = [Some(1), Some(2), Some(3)];
3105    ///
3106    /// let v = u.into_bulk().try_collect::<[i32; _], _>();
3107    ///
3108    /// assert_eq!(v, Some([1, 2, 3]));
3109    /// ```
3110    ///
3111    /// Failing to collect in the same way:
3112    /// ```
3113    /// use bulks::*;
3114    ///
3115    /// let u = [Some(1), Some(2), None, Some(3)];
3116    ///
3117    /// let v = u.into_bulk().try_collect::<[i32; _], _>();
3118    ///
3119    /// assert_eq!(v, None);
3120    /// ```
3121    ///
3122    /// A similar example, but with `Result`:
3123    /// ```
3124    /// use bulks::*;
3125    ///
3126    /// let u: [Result<i32, ()>; _] = [Ok(1), Ok(2), Ok(3)];
3127    ///
3128    /// let v = u.into_bulk().try_collect::<[i32; _], _>();
3129    ///
3130    /// assert_eq!(v, Ok([1, 2, 3]));
3131    ///
3132    /// let u = [Ok(1), Ok(2), Err(()), Ok(3)];
3133    ///
3134    /// let v = u.into_bulk().try_collect::<[i32; _], _>();
3135    ///
3136    /// assert_eq!(v, Err(()));
3137    /// ```
3138    ///
3139    /// Finally, even [`ControlFlow`] works, despite the fact that it
3140    /// doesn't implement [`FromBulk`].
3141    ///
3142    /// ```
3143    /// # #![feature(generic_const_exprs)]
3144    /// use bulks::*;
3145    ///
3146    /// use core::ops::ControlFlow::{Break, Continue};
3147    ///
3148    /// let u = [Continue(1), Continue(2), Break(3), Continue(4), Continue(5)];
3149    ///
3150    /// let v = u.into_bulk().try_collect::<[_; _], _>();
3151    ///
3152    /// assert_eq!(v, Break(3));
3153    ///
3154    /// let v = u.into_bulk().take([(); 2])
3155    ///     .chain(u.into_bulk().skip([(); 3]))
3156    ///     .try_collect::<[_; _], _>();
3157    ///
3158    /// assert_eq!(v, Continue([1, 2, 4, 5]));
3159    /// ```
3160    #[inline]
3161    #[must_use = "if you really need to exhaust the bulk, consider `.for_each(drop)` instead"]
3162    fn try_collect<C, A>(self) -> <<Self::Item as Try>::Residual as Residual<C>>::TryType
3163    where
3164        Self: Sized,
3165        C: [const] FromBulk<A>,
3166        A: CollectionAdapter<Elem = <Self::Item as Try>::Output> + [const] TryCollectionStrategy<Self::MinLength, Self::MaxLength, C> + ?Sized,
3167        Self::Item: [const] Try<Residual: [const] Residual<C, TryType: [const] Try> + [const] Destruct> + [const] Destruct
3168    {
3169        FromBulk::<A>::try_from_bulk(self)
3170    }
3171
3172    #[cfg(feature = "async")]
3173    #[rustc_non_const_trait_method]
3174    fn try_collect_async<C, A>(self) -> TryCollectAsync<Self, C, A>
3175    where
3176        Self: BufferableBulk + Sized,
3177        C: FromBulk<A>,
3178        A: CollectionAdapter<Elem = <<Self::Item as Future>::Output as Try>::Output> + TryCollectionStrategy<Self::MinLength, Self::MaxLength, C> + ?Sized,
3179        Self::Item: Future<Output: Try<Residual: Residual<C>>>
3180    {
3181        TryCollectAsync::new(self)
3182    }
3183
3184    fn collect_nearest(self) -> <BulkLength<Self> as Nearest>::NearestFrom<Self>
3185    where
3186        Self: Sized,
3187        BulkLength<Self>: [const] Nearest,
3188        Self::Item: [const] Destruct
3189    {
3190        self.collect::<<BulkLength<Self> as Nearest>::NearestFrom<Self>, <BulkLength<Self> as Nearest>::NearestStrategyFrom<Self>>()
3191    }
3192
3193    #[allow(clippy::type_complexity)]
3194    #[cfg(feature = "async")]
3195    #[rustc_non_const_trait_method]
3196    fn collect_nearest_async(
3197        self
3198    ) -> CollectAsync<Self, <BulkLength<Self> as Nearest>::NearestAsyncFrom<Self>, <BulkLength<Self> as Nearest>::NearestAsyncStrategyFrom<Self>>
3199    where
3200        Self: BufferableBulk + Sized,
3201        BulkLength<Self>: Nearest,
3202        Self::Item: Future
3203    {
3204        self.collect_async()
3205    }
3206
3207    fn try_collect_nearest(self) -> <<Self::Item as Try>::Residual as Residual<<BulkLength<Self> as Nearest>::TryNearestFrom<Self>>>::TryType
3208    where
3209        Self: Sized,
3210        BulkLength<Self>: [const] Nearest,
3211        Self::Item:
3212            [const] Try<Output: [const] Destruct, Residual: [const] Residual<<BulkLength<Self> as Nearest>::TryNearestFrom<Self>> + [const] Destruct> + [const] Destruct
3213    {
3214        self.try_collect::<<BulkLength<Self> as Nearest>::TryNearestFrom<Self>, <BulkLength<Self> as Nearest>::TryNearestStrategyFrom<Self>>()
3215    }
3216
3217    #[allow(clippy::type_complexity)]
3218    #[cfg(feature = "async")]
3219    #[rustc_non_const_trait_method]
3220    fn try_collect_nearest_async(self) -> TryCollectAsync<Self, <BulkLength<Self> as Nearest>::TryNearestAsyncFrom<Self>, <BulkLength<Self> as Nearest>::TryNearestAsyncStrategyFrom<Self>>
3221    where
3222        Self: BufferableBulk + Sized,
3223        BulkLength<Self>: Nearest,
3224        Self::Item: Future<Output: Try<Residual: Residual<<BulkLength<Self> as Nearest>::TryNearestAsyncFrom<Self>>>>
3225    {
3226        self.try_collect_async()
3227    }
3228
3229    /// Transforms a statically sized bulk into an array.
3230    /// The bulk must implement [`StaticBulk`].
3231    ///
3232    /// This is equivalent to [`collect()`](Bulk::collect), but the type does not need to be inferred.
3233    /// For types other than arrays, use [`collect()`](Bulk::collect).
3234    ///
3235    /// # Examples
3236    ///
3237    /// Basic usage:
3238    ///
3239    /// ```
3240    /// use bulks::*;
3241    ///
3242    /// let a = [1, 2, 3];
3243    ///
3244    /// let doubled = a.bulk()
3245    ///     .map(|x| x * 2)
3246    ///     .collect_array();
3247    ///
3248    /// assert_eq!(doubled, [2, 4, 6]);
3249    /// ```
3250    ///
3251    /// Alternatively, [`collect()`](Bulk::collect) can be used, but this requires us to specify the return type.
3252    ///
3253    /// ```
3254    /// use bulks::*;
3255    ///
3256    /// let a = [1, 2, 3];
3257    ///
3258    /// let doubled: [i32; 3] = a.bulk()
3259    ///     .map(|x| x * 2)
3260    ///     .collect();
3261    ///
3262    /// assert_eq!(doubled, [2, 4, 6]);
3263    /// ```
3264    #[must_use = "if you really need to exhaust the bulk, consider `.for_each(drop)` instead"]
3265    fn collect_array(self) -> <Self as StaticBulk>::Array<<Self as IntoIterator>::Item>
3266    where
3267        Self: StaticBulk
3268    {
3269        util::collect_array_with!(|f| self.for_each(f); for Self)
3270    }
3271
3272    #[cfg(feature = "async")]
3273    #[rustc_non_const_trait_method]
3274    fn collect_array_async(self) -> CollectArrayAsync<Self>
3275    where
3276        Self: StaticBulk,
3277        Self::Item: Future
3278    {
3279        CollectArrayAsync::new(self)
3280    }
3281
3282    /// Fallibly transforms a statically sized bulk into an array, short circuiting if
3283    /// a failure is encountered.
3284    /// The bulk must implement [`StaticBulk`].
3285    ///
3286    /// `try_collect_array()` is a variation of [`collect_array()`][`Bulk::collect_array`] that allows fallible
3287    /// conversions during collection. Its main use case is simplifying conversions from
3288    /// iterators yielding [`Option<T>`][`Option`] into `Option<Collection<T>>`, or similarly for other [`Try`]
3289    /// types (e.g. [`Result`]).
3290    ///
3291    /// Importantly, `try_collect()` doesn't require that the outer [`Try`] type also implements [`FromBulk`];
3292    /// only the inner type produced on `Try::Output` must implement it. Concretely,
3293    /// this means that collecting into `ControlFlow<_, Vec<i32>>` is valid because `Vec<i32>` implements
3294    /// [`FromBulk`], even though [`ControlFlow`] doesn't.
3295    ///
3296    /// This is equivalent to [`try_collect()`](Bulk::try_collect), but the type does not need to be inferred.
3297    /// For types other than arrays, use [`try_collect()`](Bulk::try_collect).
3298    ///
3299    /// Unlike with [`Iterator::try_collect`], the bulk is fully consumed even if it short-circuits.
3300    /// A short-circuit will cause the rest of the elements of the bulk to be dropped.
3301    ///
3302    /// # Examples
3303    ///
3304    /// Successfully collecting a bulk of `Option<i32>` into `Option<[i32; _]>`:
3305    /// ```
3306    /// use bulks::*;
3307    ///
3308    /// let u = [Some(1), Some(2), Some(3)];
3309    /// let v = u.into_bulk().try_collect_array();
3310    /// assert_eq!(v, Some([1, 2, 3]));
3311    /// ```
3312    ///
3313    /// Failing to collect in the same way:
3314    /// ```
3315    /// use bulks::*;
3316    ///
3317    /// let u = [Some(1), Some(2), None, Some(3)];
3318    /// let v = u.into_bulk().try_collect_array();
3319    /// assert_eq!(v, None);
3320    /// ```
3321    ///
3322    /// Alternatively, [`try_collect()`](Bulk::try_collect) can be used, but this requires us to specify the return type.
3323    /// ```
3324    /// use bulks::*;
3325    ///
3326    /// let u = [Some(1), Some(2), Some(3)];
3327    /// let v: Option<[i32; 3]> = u.into_bulk().try_collect();
3328    /// assert_eq!(v, Some([1, 2, 3]));
3329    /// ```
3330    ///
3331    /// A similar example, but with `Result`:
3332    /// ```
3333    /// use bulks::*;
3334    ///
3335    /// let u: [Result<i32, ()>; _] = [Ok(1), Ok(2), Ok(3)];
3336    /// let v = u.into_bulk().try_collect_array();
3337    /// assert_eq!(v, Ok([1, 2, 3]));
3338    ///
3339    /// let u = [Ok(1), Ok(2), Err(()), Ok(3)];
3340    /// let v = u.into_bulk().try_collect_array();
3341    /// assert_eq!(v, Err(()));
3342    /// ```
3343    ///
3344    /// Finally, even [`ControlFlow`] works, despite the fact that it
3345    /// doesn't implement [`FromBulk`].
3346    ///
3347    /// ```
3348    /// # #![feature(generic_const_exprs)]
3349    /// use core::ops::ControlFlow::{Break, Continue};
3350    ///
3351    /// use bulks::*;
3352    ///
3353    /// let u = [Continue(1), Continue(2), Break(3), Continue(4), Continue(5)];
3354    ///
3355    /// let v = u.into_bulk().try_collect_array();
3356    /// assert_eq!(v, Break(3));
3357    ///
3358    /// let v = u.into_bulk().take([(); 2])
3359    ///     .chain(u.into_bulk().skip([(); 3]))
3360    ///     .try_collect_array();
3361    /// assert_eq!(v, Continue([1, 2, 4, 5]));
3362    /// ```
3363    #[allow(clippy::type_complexity)]
3364    #[must_use = "if you really need to exhaust the bulk, consider `.for_each(drop)` instead"]
3365    fn try_collect_array(self) -> <<Self::Item as Try>::Residual as Residual<Self::Array<<Self::Item as Try>::Output>>>::TryType
3366    where
3367        Self: StaticBulk<
3368                Item: [const] Destruct
3369                          + [const] Try<Residual: Residual<Self::Array<<Self::Item as Try>::Output>, TryType: [const] Try> + [const] Destruct, Output: [const] Destruct>
3370            > + [const] Bulk
3371    {
3372        Try::from_output(util::try_collect_array_with!(|pusher| self.try_for_each(pusher); for Self))
3373    }
3374
3375    #[cfg(feature = "async")]
3376    #[rustc_non_const_trait_method]
3377    fn try_collect_array_async(self) -> TryCollectArrayAsync<Self>
3378    where
3379        Self: StaticBulk,
3380        Self::Item: Future<Output: Try<Residual: Residual<Self::Array<<<Self::Item as Future>::Output as Try>::Output>>>>
3381    {
3382        TryCollectArrayAsync::new(self)
3383    }
3384
3385    /// Resizes a bulk, padding it with copies of a given value of `element` if too short, or truncating it if too long.
3386    /// The resuling bulk will have an exact length given by `n`.
3387    ///
3388    /// ```
3389    /// # #![feature(generic_const_exprs)]
3390    ///
3391    /// use bulks::*;
3392    ///
3393    /// let u = [1, 3, 3, 7];
3394    ///
3395    /// let v = u.into_bulk()
3396    ///     .resize([(); 6], 9)
3397    ///     .collect_array();
3398    /// assert_eq!(v, [1, 3, 3, 7, 9, 9]);
3399    /// ```
3400    fn resize<N>(self, n: N, element: Self::Item) -> Resize<Self, N::Length<()>>
3401    where
3402        Self: Sized,
3403        Self::Item: Copy,
3404        N: LengthValue
3405    {
3406        Resize::new(self, n, element)
3407    }
3408
3409    /// Resizes a bulk, padding it with the output of `padder` if too short, or truncating it if too long.
3410    /// The resuling bulk will have an exact length given by `n`.
3411    ///
3412    /// ```
3413    /// # #![feature(generic_const_exprs)]
3414    ///
3415    /// use bulks::*;
3416    ///
3417    /// let u = [1, 3, 3, 7];
3418    ///
3419    /// let v = u.into_bulk()
3420    ///     .resize_with([(); 6], || 9)
3421    ///     .collect_array();
3422    /// assert_eq!(v, [1, 3, 3, 7, 9, 9]);
3423    /// ```
3424    fn resize_with<F, N>(self, n: N, padder: F) -> ResizeWith<Self, F, N::Length<()>>
3425    where
3426        Self: Sized,
3427        N: LengthValue,
3428        F: FnMut() -> Self::Item
3429    {
3430        ResizeWith::new(self, n, padder)
3431    }
3432
3433    /// Reverses a bulks's direction.
3434    ///
3435    /// Usually, bulks span from left to right. After using `rev()`,
3436    /// a bulk will instead span from right to left.
3437    ///
3438    /// Similar to [`Iterator::rev`].
3439    ///
3440    /// # Examples
3441    ///
3442    /// ```
3443    /// use bulks::*;
3444    ///
3445    /// let a = [1, 2, 3];
3446    ///
3447    /// let b: [_; _] = a.into_bulk().rev().collect();
3448    ///
3449    /// assert_eq!(b, [3, 2, 1]);
3450    /// ```
3451    #[inline]
3452    #[track_caller]
3453    #[doc(alias = "reverse")]
3454    fn rev(self) -> Rev<Self>
3455    where
3456        Self: Sized,
3457        Self: DoubleEndedBulk
3458    {
3459        Rev::new(self)
3460    }
3461
3462    /// Creates a bulk which copies all of its elements.
3463    ///
3464    /// This is useful when you have a bulk of `&T`, but you need a
3465    /// bulk of `T`.
3466    ///
3467    /// Similar to [`Iterator::copied`].
3468    ///
3469    /// # Examples
3470    ///
3471    /// ```
3472    /// use bulks::*;
3473    ///
3474    /// let a = [1, 2, 3];
3475    ///
3476    /// let v_copied: [_; _] = a.bulk().copied().collect();
3477    ///
3478    /// // copied is the same as .map(|&x| x)
3479    /// let v_map: [_; _] = a.bulk().map(|&x| x).collect();
3480    ///
3481    /// assert_eq!(v_copied, [1, 2, 3]);
3482    /// assert_eq!(v_map, [1, 2, 3]);
3483    /// ```
3484    #[inline]
3485    #[track_caller]
3486    fn copied<'a, T>(self) -> Copied<Self>
3487    where
3488        T: Copy + 'a,
3489        Self: Sized + [const] Bulk<Item = &'a T>
3490    {
3491        Copied::new(self)
3492    }
3493
3494    /// Creates a bulk which [`clone`](Clone::clone)s all of its elements.
3495    ///
3496    /// This is useful when you have a bulk of `&T`, but you need a
3497    /// bulk of `T`.
3498    ///
3499    /// There is no guarantee whatsoever about the `clone` method actually
3500    /// being called *or* optimized away. So code should not depend on
3501    /// either.
3502    ///
3503    /// Similar to [`Iterator::cloned`].
3504    ///
3505    /// # Examples
3506    ///
3507    /// Basic usage:
3508    ///
3509    /// ```
3510    /// use bulks::*;
3511    ///
3512    /// let a = [1, 2, 3];
3513    ///
3514    /// let v_cloned: [_; _] = a.bulk().cloned().collect();
3515    ///
3516    /// // cloned is the same as .map(|&x| x), for integers
3517    /// let v_map: [_; _] = a.bulk().map(|&x| x).collect();
3518    ///
3519    /// assert_eq!(v_cloned, [1, 2, 3]);
3520    /// assert_eq!(v_map, [1, 2, 3]);
3521    /// ```
3522    #[inline]
3523    #[track_caller]
3524    fn cloned<'a, T>(self) -> Cloned<Self>
3525    where
3526        T: Clone + 'a,
3527        Self: Sized + [const] Bulk<Item = &'a T>
3528    {
3529        Cloned::new(self)
3530    }
3531
3532    /// # Safety
3533    ///
3534    /// Same safety conditions as [Pin::new_unchecked].
3535    #[inline]
3536    #[track_caller]
3537    unsafe fn pinned_unchecked(self) -> Pinned<Self>
3538    where
3539        Self: Sized,
3540        Self::Item: Deref
3541    {
3542        unsafe { Pinned::new_unchecked(self) }
3543    }
3544    #[inline]
3545    #[track_caller]
3546    fn pinned(self) -> Pinned<Self>
3547    where
3548        Self: Sized,
3549        Self::Item: Deref<Target: Unpin>
3550    {
3551        Pinned::new(self)
3552    }
3553
3554    /// # Safety
3555    ///
3556    /// Same safety conditions as [Pin::into_inner_unchecked].
3557    #[inline]
3558    #[track_caller]
3559    unsafe fn unpinned_unchecked<T>(self) -> Unpinned<Self, T>
3560    where
3561        Self: Sized + [const] Bulk<Item = Pin<T>>,
3562        T: Deref
3563    {
3564        unsafe { Unpinned::new_unchecked(self) }
3565    }
3566    #[inline]
3567    #[track_caller]
3568    fn unpinned<T>(self) -> Unpinned<Self, T>
3569    where
3570        Self: Sized + [const] Bulk<Item = Pin<T>>,
3571        T: Deref<Target: Unpin>
3572    {
3573        Unpinned::new(self)
3574    }
3575
3576    /// Returns a bulk of `N` elements of the bulk at a time.
3577    ///
3578    /// The chunks do not overlap. If `N` does not divide the length of the
3579    /// bulk, then the last up to `N-1` elements will be omitted or the remainder
3580    /// can then be retrieved from [`.into_remainder()`][crate::ArrayChunks::into_remainder]
3581    /// or [`.collect_with_remainder()`][crate::ArrayChunks::collect_with_remainder]
3582    ///
3583    /// Similar to [`Iterator::array_chunks`].
3584    ///
3585    /// # Panics
3586    ///
3587    /// Panics if `N` is zero.
3588    ///
3589    /// # Examples
3590    ///
3591    /// Basic usage:
3592    ///
3593    /// ```
3594    /// # #![feature(generic_const_exprs)]
3595    /// use bulks::*;
3596    ///
3597    /// let bulk = b"lorem".bulk()
3598    ///     .copied()
3599    ///     .array_chunks();
3600    ///
3601    /// let (c, r) = bulk.collect_with_remainder::<[_; _], _>();
3602    ///
3603    /// let r: Vec<_> = r.collect();
3604    ///
3605    /// assert_eq!(c, [[b'l', b'o'], [b'r', b'e']]);
3606    /// assert_eq!(r, [b'm']);
3607    /// ```
3608    ///
3609    /// ```
3610    /// use bulks::*;
3611    ///
3612    /// let data = [1, 1, 2, -2, 6, 0, 3, 1];
3613    /// //          ^-----^  ^------^
3614    /// for [x, y, z] in data.bulk().array_chunks()
3615    /// {
3616    ///     assert_eq!(x + y + z, 4);
3617    /// }
3618    /// ```
3619    #[inline]
3620    #[track_caller]
3621    fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
3622    where
3623        Self: Sized
3624    {
3625        ArrayChunks::new(self)
3626    }
3627
3628    /// Splits a bulk in two at a specified index.
3629    ///
3630    /// # Example
3631    ///
3632    /// ```
3633    /// # #![feature(generic_const_exprs)]
3634    /// use bulks::*;
3635    ///
3636    /// let a = b"leftright";
3637    ///
3638    /// let (a1, a2) = a.bulk()
3639    ///     .copied()
3640    ///     .split_at([(); 4]);
3641    ///
3642    /// let left: [_; _] = a1.collect();
3643    /// let right: [_; _] = a2.collect();
3644    ///
3645    /// assert_eq!(&left, b"left");
3646    /// assert_eq!(&right, b"right");
3647    /// ```
3648    #[track_caller]
3649    fn split_at<L>(self, n: L) -> (Self::Left, Self::Right)
3650    where
3651        Self: [const] SplitBulk<L> + Sized,
3652        L: LengthValue
3653    {
3654        SplitBulk::split_at(self, n)
3655    }
3656
3657    /// Splits a bulk in two at a specified reversed index.
3658    ///
3659    /// # Example
3660    ///
3661    /// ```
3662    /// # #![feature(generic_const_exprs)]
3663    /// use bulks::*;
3664    ///
3665    /// let a = b"leftright";
3666    ///
3667    /// let (a1, a2) = a.bulk()
3668    ///     .copied()
3669    ///     .rsplit_at([(); 5]);
3670    ///
3671    /// let left: [_; _] = a1.collect();
3672    /// let right: [_; _] = a2.collect();
3673    ///
3674    /// assert_eq!(&left, b"left");
3675    /// assert_eq!(&right, b"right");
3676    /// ```
3677    #[track_caller]
3678    fn rsplit_at<L>(self, n: L) -> (Self::Left, Self::Right)
3679    where
3680        Self: [const] SplitBulk<length::value::SaturatingSub<<BulkLength<Self> as Length>::Value, L>> + Sized,
3681        L: LengthValue
3682    {
3683        let l = self.length();
3684        SplitBulk::split_at(self, length::value::saturating_sub(l, n))
3685    }
3686
3687    /// Consumes the bulk, and swaps two elements of it. Items must be mutably dereferenceable.
3688    ///
3689    /// Panics if either index is out of bounds.
3690    ///
3691    /// # Example
3692    ///
3693    /// ```
3694    /// use bulks::*;
3695    ///
3696    /// let mut a = *b"Com Truise";
3697    ///
3698    /// a.bulk_mut()
3699    ///     .swap::<u8>(0, 4);
3700    ///
3701    /// assert_eq!(&a, b"Tom Cruise");
3702    /// ```
3703    fn swap<S>(self, lhs: impl LengthValue, rhs: impl LengthValue)
3704    where
3705        Self: Sized,
3706        Self::Item: [const] BorrowMut<S> + [const] Destruct
3707    {
3708        match self.try_swap(lhs, rhs)
3709        {
3710            Ok(()) => (),
3711            Err(err) => err.halt()
3712        }
3713    }
3714
3715    /// Consumes the bulk, and swaps two elements of it. Items must be mutably dereferenceable.
3716    ///
3717    /// Returns an error if either index is out of bounds.
3718    ///
3719    /// # Example
3720    ///
3721    /// ```
3722    /// use bulks::*;
3723    ///
3724    /// let mut a = *b"Com Truise";
3725    ///
3726    /// std::assert_matches!(
3727    ///     a.bulk_mut()
3728    ///         .try_swap::<u8>(0, 4),
3729    ///     Ok(())
3730    /// );
3731    /// std::assert_matches!(
3732    ///     a.bulk_mut()
3733    ///         .try_swap::<u8>(4, 10),
3734    ///     Err(OutOfRange { i: 10, len: 10 })
3735    /// );
3736    ///
3737    /// assert_eq!(&a, b"Tom Cruise");
3738    /// ```
3739    fn try_swap<S>(self, lhs: impl LengthValue, rhs: impl LengthValue) -> Result<(), OutOfRange>
3740    where
3741        Self: Sized,
3742        Self::Item: [const] BorrowMut<S> + [const] Destruct
3743    {
3744        let n = self.length();
3745
3746        let j = length::value::min(lhs, rhs);
3747        let i = length::value::max(lhs, rhs);
3748
3749        struct Closure<T>
3750        {
3751            first: Option<T>,
3752            last: Option<T>
3753        }
3754        const impl<T> FnOnce<(T,)> for Closure<T>
3755        where
3756            T: [const] Destruct
3757        {
3758            type Output = ();
3759
3760            extern "rust-call" fn call_once(mut self, args: (T,)) -> Self::Output
3761            {
3762                self.call_mut(args)
3763            }
3764        }
3765        const impl<T> FnMut<(T,)> for Closure<T>
3766        where
3767            T: [const] Destruct
3768        {
3769            extern "rust-call" fn call_mut(&mut self, (x,): (T,)) -> Self::Output
3770            {
3771                if self.first.is_none() { self.first = Some(x) } else { self.last = Some(x) }
3772            }
3773        }
3774
3775        let mut closure = Closure { first: None, last: None };
3776
3777        self.take(length::value::add(i, [(); 1]))
3778            .skip(j)
3779            .step_by(length::value::sub(i, j))
3780            .for_each(&mut closure);
3781
3782        match if length::value::ge(i, n)
3783        {
3784            Err(length::value::len(i))
3785        }
3786        else
3787        {
3788            match (closure.first, closure.last)
3789            {
3790                (Some(mut first), Some(mut last)) =>
3791                {
3792                    core::mem::swap(first.borrow_mut(), last.borrow_mut());
3793                    Ok(())
3794                }
3795                (Some(_), None) if length::value::eq(i, j) => Ok(()),
3796                (Some(_), None) => Err(length::value::len(j)),
3797                (None, None) | (None, Some(_)) => Err(length::value::len(i))
3798            }
3799        }
3800        {
3801            Ok(()) => Ok(()),
3802            Err(i) => Err(OutOfRange { i, len: length::value::len(n) })
3803        }
3804    }
3805
3806    fn sum_from<T>(self, from: T) -> T
3807    where
3808        T: [const] Add<Self::Item, Output = T> + [const] Destruct,
3809        Self: Sized
3810    {
3811        self.fold(from, Add::add)
3812    }
3813
3814    fn product_from<T>(self, from: T) -> T
3815    where
3816        T: [const] Mul<Self::Item, Output = T> + [const] Destruct,
3817        Self: Sized
3818    {
3819        self.fold(from, Mul::mul)
3820    }
3821}
3822
3823#[derive(Clone, Copy, Debug)]
3824pub struct OutOfRange
3825{
3826    pub i: usize,
3827    pub len: usize
3828}
3829
3830impl OutOfRange
3831{
3832    const fn halt(self) -> !
3833    {
3834        fn rt(oor: OutOfRange) -> !
3835        {
3836            panic!("{oor}")
3837        }
3838
3839        const fn ct(_: OutOfRange) -> !
3840        {
3841            panic!("Index out of bounds.")
3842        }
3843
3844        core::intrinsics::const_eval_select((self,), ct, rt)
3845    }
3846}
3847
3848impl Display for OutOfRange
3849{
3850    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
3851    {
3852        let Self { i, len } = self;
3853        write!(f, "Index out of bounds. Index {i} can't be larger than {len}.")
3854    }
3855}
3856impl Error for OutOfRange {}
3857
3858#[cfg(test)]
3859mod test
3860{
3861    use crate::*;
3862
3863    #[test]
3864    fn test_reduce()
3865    {
3866        let a = [1, 5, -3, 7, 9, 3, -1, 3];
3867
3868        let sum = a.into_bulk().reduce(|a, b| a + b).unwrap_or(0);
3869        let product = a.into_bulk().reduce(|a, b| a * b).unwrap_or(1);
3870        let min = a.into_bulk().reduce(|a, b| a.min(b)).unwrap();
3871        let max = a.into_bulk().reduce(|a, b| a.max(b)).unwrap();
3872        let mean = sum as f32 / a.len() as f32;
3873        let variance = a.into_bulk().map(|a| a as f32 - mean).map(|a| a * a).reduce(|a, b| a + b).unwrap_or(0.0).sqrt();
3874
3875        println!("sum = {sum}");
3876        println!("product = {product}");
3877        println!("min = {min}");
3878        println!("max = {max}");
3879
3880        println!("mean = {mean}");
3881        println!("variance = {variance}");
3882    }
3883}