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}