Skip to main content

orx_parallel/option_use/
par.rs

1// TODO: remove this
2#![allow(clippy::type_complexity)]
3
4use crate::infallible_use::fun::{UFnCloned, UFnCopied};
5use crate::infallible_use::{
6    FilMapOf, FilOf, FlatMapOf, FlattenOf, InsOf, MapOf, MappedOf, XapUse,
7};
8use crate::option_use::ParUseOptionIter;
9use crate::option_use::par_core::ParUseOptionCore;
10use crate::runner::ParRunner;
11use crate::sizes::{OneOne, SizePair};
12use crate::{ChunkSize, IterationOrder, NumThreads, ParExtend, Sum};
13use core::cmp::Ordering;
14use orx_concurrent_iter::ExactSizeConcurrentIter;
15
16/// Fallible parallel iterator with worker-local mutable state.
17///
18/// `ParUseOption` combines:
19/// - fallible processing (`Option`-based short-circuiting), and
20/// - mutable worker-local state (`&mut Use` passed to closures).
21///
22/// You can enter this mode from [`ParOption`](crate::ParOption) via
23/// [`use_new`](crate::ParOption::use_new),
24/// [`use_vec`](crate::ParOption::use_vec), or
25/// [`use_slice`](crate::ParOption::use_slice).
26///
27/// Similar to using `?`, this trait keeps pipeline logic focused on successful
28/// values while the computation short-circuits to `None` when any element
29/// evaluates to `None`.
30///
31/// Related traits:
32/// - [`ParOption`](crate::ParOption) for `Option`-fallible pipelines without worker-local state,
33/// - [`ParUse`](crate::ParUse) for worker-local state in infallible pipelines.
34///
35/// # Examples
36///
37/// Reusing a per-worker buffer:
38///
39/// ```
40/// use core::fmt::Write;
41/// use orx_parallel::*;
42///
43/// let out: Option<Vec<usize>> = (0..16usize)
44///     .into_par()
45///     .map(Some)
46///     .into_optional()
47///     .use_new(|_| String::with_capacity(32))
48///     .map(|buffer, x| {
49///         buffer.clear();
50///         write!(buffer, "{x}").unwrap();
51///         buffer.parse::<usize>().unwrap()
52///     })
53///     .collect();
54///
55/// assert_eq!(out, Some((0..16).collect::<Vec<_>>()));
56/// ```
57///
58/// Using RNG as mutable worker-local state:
59///
60/// ```
61/// use orx_parallel::*;
62/// use rand::prelude::*;
63/// use rand_chacha::ChaCha8Rng;
64///
65/// let out: Option<Vec<usize>> = (0..32usize)
66///     .into_par()
67///     .map(Some)
68///     .into_optional()
69///     .use_new(|thread_idx| ChaCha8Rng::seed_from_u64(100 + thread_idx as u64))
70///     .map(|rng, x| x + rng.random_range(0..10))
71///     .collect();
72///
73/// assert_eq!(out.as_ref().map(Vec::len), Some(32));
74/// assert!(out.unwrap().into_iter().enumerate().all(|(i, v)| v >= i));
75/// ```
76pub trait ParUseOption: Sized + ParUseOptionCore {
77    // configuration
78
79    /// Replaces the current parallel runner with `runner`.
80    ///
81    /// # Examples
82    ///
83    /// ```
84    /// use orx_parallel::*;
85    ///
86    /// let par = ["1", "2", "3"]
87    ///     .into_par()
88    ///     .map(|s| s.parse::<usize>().ok())
89    ///     .into_optional()
90    ///     .use_new(|_| ());
91    ///
92    /// let par = par.runner(Runner::fixed());
93    ///
94    /// let out: Option<Vec<_>> = par.collect();
95    /// assert_eq!(out, Some(vec![1, 2, 3]));
96    /// ```
97    fn runner<Q: ParRunner>(
98        self,
99        runner: Q,
100    ) -> impl ParUseOption<
101        Elem = Self::Elem,
102        Use = Self::Use,
103        Xap1 = Self::Xap1,
104        M = Self::M,
105        Xap2 = Self::Xap2,
106        Input = Self::Input,
107        Size = Self::Size,
108    >;
109
110    /// Wraps the current runner with diagnostics-enabled execution.
111    ///
112    /// # Examples
113    ///
114    /// ```
115    /// use orx_parallel::*;
116    ///
117    /// let par = ["1", "2", "3"]
118    ///     .into_par()
119    ///     .map(|s| s.parse::<usize>().ok())
120    ///     .into_optional()
121    ///     .use_new(|_| ());
122    ///
123    /// #[cfg(feature = "std")]
124    /// let par = par.runner_with_diagnostics();
125    ///
126    /// let out: Option<Vec<_>> = par.collect();
127    /// assert_eq!(out, Some(vec![1, 2, 3]));
128    /// ```
129    #[cfg(feature = "std")]
130    fn runner_with_diagnostics(
131        self,
132    ) -> impl ParUseOption<
133        Elem = Self::Elem,
134        Use = Self::Use,
135        Xap1 = Self::Xap1,
136        M = Self::M,
137        Xap2 = Self::Xap2,
138        Input = Self::Input,
139        Size = Self::Size,
140    >;
141
142    /// Sets the maximum number of worker threads for this computation.
143    ///
144    /// # Examples
145    ///
146    /// ```
147    /// use orx_parallel::*;
148    ///
149    /// let out: Option<Vec<_>> = (1..6)
150    ///     .into_par()
151    ///     .map(Some)
152    ///     .into_optional()
153    ///     .use_new(|_| ())
154    ///     .num_threads(1)
155    ///     .collect();
156    ///
157    /// assert_eq!(out, Some(vec![1, 2, 3, 4, 5]));
158    /// ```
159    fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self;
160
161    /// Sets chunk size used when pulling items from the concurrent input.
162    ///
163    /// # Examples
164    ///
165    /// ```
166    /// use orx_parallel::*;
167    ///
168    /// let out: Option<Vec<_>> = (0..8)
169    ///     .into_par()
170    ///     .map(Some)
171    ///     .into_optional()
172    ///     .use_new(|_| ())
173    ///     .chunk_size(2)
174    ///     .collect();
175    ///
176    /// assert_eq!(out, Some((0..8).collect::<Vec<_>>()));
177    /// ```
178    fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self;
179
180    /// Sets iteration-order semantics for order-sensitive operations.
181    ///
182    /// # Examples
183    ///
184    /// ```
185    /// use orx_parallel::*;
186    ///
187    /// let ordered = (1..10_000)
188    ///     .into_par()
189    ///     .map(Some)
190    ///     .into_optional()
191    ///     .use_new(|_| ())
192    ///     .iteration_order(IterationOrder::Ordered)
193    ///     .find(|_, x| x % 3421 == 0);
194    /// assert_eq!(ordered, Some(Some(3421)));
195    /// ```
196    fn iteration_order(self, iteration_order: IterationOrder) -> Self;
197
198    // kind transformations
199
200    /// Copies elements of a reference iterator on the success path.
201    ///
202    /// # Examples
203    ///
204    /// ```
205    /// use orx_parallel::*;
206    ///
207    /// let data = vec![1, 2, 3];
208    /// let out: Option<Vec<_>> = data
209    ///     .par()
210    ///     .map(Some)
211    ///     .into_optional()
212    ///     .use_new(|_| ())
213    ///     .copied()
214    ///     .collect();
215    ///
216    /// assert_eq!(out, Some(vec![1, 2, 3]));
217    /// ```
218    fn copied<'a, O>(
219        self,
220    ) -> impl ParUseOption<
221        Elem = O,
222        Use = Self::Use,
223        Xap1 = Self::Xap1,
224        M = Self::M,
225        Xap2 = MappedOf<Self::Xap2, UFnCopied<'a, Self::Use, O>>,
226        Input = Self::Input,
227        Size = Self::Size,
228    >
229    where
230        Self: ParUseOption<Elem = &'a O>,
231        O: Copy + 'a,
232        Self::Use: 'a,
233    {
234        let (u, iter, x1, x2, exe, _, params) = self.destruct();
235        ParUseOptionIter::new(u, iter, x1, x2.mapped(UFnCopied::new()), exe, params)
236    }
237
238    /// Clones elements of a reference iterator on the success path.
239    ///
240    /// # Examples
241    ///
242    /// ```
243    /// use orx_parallel::*;
244    ///
245    /// let data = vec!["a".to_string(), "b".to_string()];
246    /// let out: Option<Vec<_>> = data
247    ///     .par()
248    ///     .map(Some)
249    ///     .into_optional()
250    ///     .use_new(|_| ())
251    ///     .cloned()
252    ///     .collect();
253    ///
254    /// assert_eq!(out, Some(vec!["a".to_string(), "b".to_string()]));
255    /// ```
256    fn cloned<'a, O>(
257        self,
258    ) -> impl ParUseOption<
259        Elem = O,
260        Use = Self::Use,
261        Xap1 = Self::Xap1,
262        M = Self::M,
263        Xap2 = MappedOf<Self::Xap2, UFnCloned<'a, Self::Use, O>>,
264        Input = Self::Input,
265        Size = Self::Size,
266    >
267    where
268        Self: ParUseOption<Elem = &'a O>,
269        O: Clone + 'a,
270        Self::Use: 'a,
271    {
272        let (u, iter, x1, x2, exe, _, params) = self.destruct();
273        ParUseOptionIter::new(u, iter, x1, x2.mapped(UFnCloned::new()), exe, params)
274    }
275
276    // transformations
277
278    /// Maps each successful element with closure `h`.
279    ///
280    /// # Examples
281    ///
282    /// ```
283    /// use orx_parallel::*;
284    ///
285    /// let out: Option<Vec<_>> = (1..4)
286    ///     .into_par()
287    ///     .map(Some)
288    ///     .into_optional()
289    ///     .use_new(|_| ())
290    ///     .map(|_, x| 2 * x)
291    ///     .collect();
292    ///
293    /// assert_eq!(out, Some(vec![2, 4, 6]));
294    /// ```
295    fn map<Q, H>(
296        self,
297        h: H,
298    ) -> impl ParUseOption<
299        Elem = Q,
300        Use = Self::Use,
301        Xap1 = Self::Xap1,
302        M = Self::M,
303        Xap2 = MapOf<Self::Xap2, Q, H>,
304        Input = Self::Input,
305        Size = Self::Size,
306    >
307    where
308        H: Fn(&mut Self::Use, Self::Elem) -> Q + Copy + Send;
309
310    /// Runs `h` on each successful element and forwards the item unchanged.
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// use orx_parallel::*;
316    ///
317    /// let mut use_vec = UseVec::new(|_| 0usize);
318    /// let out: Option<Vec<_>> = (1..5)
319    ///     .into_par()
320    ///     .map(Some)
321    ///     .into_optional()
322    ///     .use_vec(&mut use_vec)
323    ///     .inspect(|count, _| *count += 1)
324    ///     .collect();
325    ///
326    /// assert_eq!(out, Some(vec![1, 2, 3, 4]));
327    /// assert_eq!(use_vec.into_vec().into_iter().sum::<usize>(), 4);
328    /// ```
329    fn inspect<H>(
330        self,
331        h: H,
332    ) -> impl ParUseOption<
333        Elem = Self::Elem,
334        Use = Self::Use,
335        Xap1 = Self::Xap1,
336        M = Self::M,
337        Xap2 = InsOf<Self::Xap2, H>,
338        Input = Self::Input,
339        Size = Self::Size,
340    >
341    where
342        H: Fn(&mut Self::Use, &Self::Elem) + Copy + Send;
343
344    /// Keeps successful elements satisfying predicate `h`.
345    ///
346    /// # Examples
347    ///
348    /// ```
349    /// use orx_parallel::*;
350    ///
351    /// let out: Option<Vec<_>> = (1..7)
352    ///     .into_par()
353    ///     .map(Some)
354    ///     .into_optional()
355    ///     .use_new(|_| ())
356    ///     .filter(|_, x| x % 2 == 1)
357    ///     .collect();
358    ///
359    /// assert_eq!(out, Some(vec![1, 3, 5]));
360    /// ```
361    fn filter<H>(
362        self,
363        h: H,
364    ) -> impl ParUseOption<
365        Elem = Self::Elem,
366        Use = Self::Use,
367        Xap1 = Self::Xap1,
368        M = Self::M,
369        Xap2 = FilOf<Self::Xap2, H>,
370        Input = Self::Input,
371        Size = <Self::Size as SizePair>::ThenBin,
372    >
373    where
374        H: Fn(&mut Self::Use, &Self::Elem) -> bool + Copy + Send;
375
376    /// Maps and filters successful elements in one pass.
377    ///
378    /// # Examples
379    ///
380    /// ```
381    /// use orx_parallel::*;
382    ///
383    /// let out: Option<Vec<_>> = ["1", "x", "5"]
384    ///     .into_par()
385    ///     .map(|s| Some(s))
386    ///     .into_optional()
387    ///     .use_new(|_| ())
388    ///     .filter_map(|_, s| s.parse::<usize>().ok())
389    ///     .collect();
390    ///
391    /// assert_eq!(out, Some(vec![1, 5]));
392    /// ```
393    fn filter_map<Q, H>(
394        self,
395        h: H,
396    ) -> impl ParUseOption<
397        Elem = Q,
398        Use = Self::Use,
399        Xap1 = Self::Xap1,
400        M = Self::M,
401        Xap2 = FilMapOf<Self::Xap2, Q, H>,
402        Input = Self::Input,
403        Size = <Self::Size as SizePair>::ThenBin,
404    >
405    where
406        H: Fn(&mut Self::Use, Self::Elem) -> Option<Q> + Copy + Send;
407
408    /// Maps each successful element to an iterator and flattens one level.
409    ///
410    /// # Examples
411    ///
412    /// ```
413    /// use orx_parallel::*;
414    ///
415    /// let out: Option<Vec<_>> = (1..4)
416    ///     .into_par()
417    ///     .map(Some)
418    ///     .into_optional()
419    ///     .use_new(|_| ())
420    ///     .flat_map(|_, x| [x, x + 10])
421    ///     .collect();
422    ///
423    /// assert_eq!(out, Some(vec![1, 11, 2, 12, 3, 13]));
424    /// ```
425    fn flat_map<V, H>(
426        self,
427        h: H,
428    ) -> impl ParUseOption<
429        Elem = V::Item,
430        Use = Self::Use,
431        Xap1 = Self::Xap1,
432        M = Self::M,
433        Xap2 = FlatMapOf<Self::Xap2, V, H>,
434        Input = Self::Input,
435        Size = <Self::Size as SizePair>::ThenMany,
436    >
437    where
438        V: IntoIterator,
439        H: Fn(&mut Self::Use, Self::Elem) -> V + Copy + Send;
440
441    /// Flattens one level of nested iterables on the success path.
442    ///
443    /// # Examples
444    ///
445    /// ```
446    /// use orx_parallel::*;
447    ///
448    /// let nested = vec![vec![1, 2], vec![3, 4]];
449    /// let out: Option<Vec<_>> = nested
450    ///     .into_par()
451    ///     .map(Some)
452    ///     .into_optional()
453    ///     .use_new(|_| ())
454    ///     .flatten()
455    ///     .collect();
456    ///
457    /// assert_eq!(out, Some(vec![1, 2, 3, 4]));
458    /// ```
459    fn flatten(
460        self,
461    ) -> impl ParUseOption<
462        Elem = <Self::Elem as IntoIterator>::Item,
463        Use = Self::Use,
464        Xap1 = Self::Xap1,
465        M = Self::M,
466        Xap2 = FlattenOf<Self::Xap2>,
467        Input = Self::Input,
468        Size = <Self::Size as SizePair>::ThenMany,
469    >
470    where
471        Self::Elem: IntoIterator;
472
473    /// Returns a lower and optional upper bound on the number of successful output items.
474    ///
475    /// The bounds follow the usual [`Iterator::size_hint`] convention.
476    /// The upper bound includes items that may be removed by filtering or short-circuiting.
477    ///
478    /// # Examples
479    ///
480    /// ```
481    /// use orx_parallel::*;
482    ///
483    /// let values = (0..4)
484    ///     .into_par()
485    ///     .map(Some)
486    ///     .into_optional()
487    ///     .use_new(|_| ())
488    ///     .filter(|_, x| x % 2 == 0);
489    ///
490    /// assert_eq!(values.size_hint(), (0, Some(4)));
491    /// ```
492    fn size_hint(&self) -> (usize, Option<usize>);
493
494    /// Returns the exact number of output items.
495    fn len(&self) -> usize
496    where
497        Self::Input: ExactSizeConcurrentIter,
498        Self: ParUseOption<Size = OneOne>,
499    {
500        self.size_hint().0
501    }
502
503    /// Returns `true` when the parallel iterator has no output items.
504    fn is_empty(&self) -> bool
505    where
506        Self::Input: ExactSizeConcurrentIter,
507        Self: ParUseOption<Size = OneOne>,
508    {
509        self.len() == 0
510    }
511
512    // compute
513
514    /// Returns the first successful item according to iteration order.
515    ///
516    /// Returns:
517    /// - `None` if computation short-circuits due to a failure
518    /// - `Some(None)` if no successful element exists
519    /// - `Some(Some(x))` for the first successful element
520    ///
521    /// # Examples
522    ///
523    /// ```
524    /// use orx_parallel::*;
525    ///
526    /// let ok = (1..4)
527    ///     .into_par()
528    ///     .map(Some)
529    ///     .into_optional()
530    ///     .use_new(|_| ())
531    ///     .first();
532    /// assert_eq!(ok, Some(Some(1)));
533    ///
534    /// let fail = vec![None, Some(1), Some(3)]
535    ///     .into_par()
536    ///     .into_optional()
537    ///     .use_new(|_| ())
538    ///     .first();
539    /// assert_eq!(fail, None);
540    /// ```
541    fn first(self) -> Option<Option<Self::Elem>>
542    where
543        Self::Elem: Send;
544
545    /// Reduces successful items into one value using `f`.
546    ///
547    /// Returns `None` on short-circuit failure.
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// use orx_parallel::*;
553    ///
554    /// let ok = (1..6)
555    ///     .into_par()
556    ///     .map(Some)
557    ///     .into_optional()
558    ///     .use_new(|_| ())
559    ///     .reduce(|_, a, b| a + b);
560    /// assert_eq!(ok, Some(Some(15)));
561    ///
562    /// let fail = vec![Some(1), None, Some(3)]
563    ///     .into_par()
564    ///     .into_optional()
565    ///     .use_new(|_| ())
566    ///     .reduce(|_, a, b| a + b);
567    /// assert_eq!(fail, None);
568    /// ```
569    fn reduce<F>(self, f: F) -> Option<Option<Self::Elem>>
570    where
571        F: Fn(&mut Self::Use, Self::Elem, Self::Elem) -> Self::Elem + Send + Copy,
572        Self::Elem: Send;
573
574    /// Collects successful items into `dst`.
575    ///
576    /// Returns `None` on short-circuit failure.
577    ///
578    /// # Examples
579    ///
580    /// ```
581    /// use orx_parallel::*;
582    ///
583    /// let mut dst = vec![10usize];
584    /// let ok = (0..3)
585    ///     .into_par()
586    ///     .map(Some)
587    ///     .into_optional()
588    ///     .use_new(|_| ())
589    ///     .collect_into(&mut dst);
590    /// assert_eq!(ok, Some(()));
591    /// assert_eq!(dst, vec![10, 0, 1, 2]);
592    /// ```
593    fn collect_into<P>(self, dst: &mut P) -> Option<()>
594    where
595        P: ParExtend<Self::Elem>,
596        Self::Elem: Send;
597
598    /// Collects successful items into a new collection.
599    ///
600    /// Returns `None` on short-circuit failure.
601    ///
602    /// # Examples
603    ///
604    /// ```
605    /// use orx_parallel::*;
606    ///
607    /// let out: Option<Vec<_>> = (1..4)
608    ///     .into_par()
609    ///     .map(Some)
610    ///     .into_optional()
611    ///     .use_new(|_| ())
612    ///     .collect();
613    ///
614    /// assert_eq!(out, Some(vec![1, 2, 3]));
615    /// ```
616    fn collect<P>(self) -> Option<P>
617    where
618        P: ParExtend<Self::Elem> + Default,
619        Self::Elem: Send,
620    {
621        let mut dst = P::default();
622        self.collect_into(&mut dst)?;
623        Some(dst)
624    }
625
626    // compute - derived
627
628    /// Returns `Some(true)` if all successful items satisfy `f`.
629    ///
630    /// Returns `None` on short-circuit failure.
631    ///
632    /// # Examples
633    ///
634    /// ```
635    /// use orx_parallel::*;
636    ///
637    /// let ok = (1..5)
638    ///     .into_par()
639    ///     .map(Some)
640    ///     .into_optional()
641    ///     .use_new(|_| ())
642    ///     .all(|_, x| x > &0);
643    /// assert_eq!(ok, Some(true));
644    ///
645    /// let fail = vec![Some(1), None, Some(3)]
646    ///     .into_par()
647    ///     .into_optional()
648    ///     .use_new(|_| ())
649    ///     .all(|_, x| x > &0);
650    /// assert_eq!(fail, None);
651    /// ```
652    fn all<F>(self, f: F) -> Option<bool>
653    where
654        Self::Elem: Send,
655        F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
656    {
657        self.map(|u, x| f(u, &x))
658            .find(|_, x| !*x)
659            .map(|x| x.is_none())
660    }
661
662    /// Returns `Some(true)` if any successful item satisfies `f`.
663    ///
664    /// Returns `None` on short-circuit failure.
665    ///
666    /// # Examples
667    ///
668    /// ```
669    /// use orx_parallel::*;
670    ///
671    /// let ok = (1..5)
672    ///     .into_par()
673    ///     .map(Some)
674    ///     .into_optional()
675    ///     .use_new(|_| ())
676    ///     .any(|_, x| x % 2 == 0);
677    /// assert_eq!(ok, Some(true));
678    ///
679    /// let fail = vec![Some(1), None, Some(3)]
680    ///     .into_par()
681    ///     .into_optional()
682    ///     .use_new(|_| ())
683    ///     .any(|_, x| x % 2 == 0);
684    /// assert_eq!(fail, None);
685    /// ```
686    fn any<F>(self, f: F) -> Option<bool>
687    where
688        Self::Elem: Send,
689        F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
690    {
691        self.map(|u, x| f(u, &x))
692            .find(|_, x| *x)
693            .map(|x| x.is_some())
694    }
695
696    /// Counts successful elements.
697    ///
698    /// Returns `None` on short-circuit failure.
699    ///
700    /// # Examples
701    ///
702    /// ```
703    /// use orx_parallel::*;
704    ///
705    /// let ok = (1..11)
706    ///     .into_par()
707    ///     .map(Some)
708    ///     .into_optional()
709    ///     .use_new(|_| ())
710    ///     .filter(|_, x| x % 3 == 0)
711    ///     .count();
712    /// assert_eq!(ok, Some(3));
713    /// ```
714    fn count(self) -> Option<usize> {
715        self.map(|_, _| 1)
716            .reduce(|_, a, b| a + b)
717            .map(|x| x.unwrap_or(0))
718    }
719
720    /// Finds first (ordered) or any (arbitrary) successful item satisfying `f`.
721    ///
722    /// Returns `None` on short-circuit failure.
723    ///
724    /// # Examples
725    ///
726    /// ```
727    /// use orx_parallel::*;
728    ///
729    /// let found = (1..101)
730    ///     .into_par()
731    ///     .map(Some)
732    ///     .into_optional()
733    ///     .use_new(|_| ())
734    ///     .find(|_, x| x % 17 == 0);
735    /// assert_eq!(found, Some(Some(17)));
736    /// ```
737    fn find<F>(self, f: F) -> Option<Option<Self::Elem>>
738    where
739        Self::Elem: Send,
740        F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
741    {
742        self.filter(&f).first()
743    }
744
745    /// Executes `f` for each successful element.
746    ///
747    /// Returns `None` on short-circuit failure.
748    ///
749    /// # Examples
750    ///
751    /// ```
752    /// use orx_parallel::*;
753    ///
754    /// let mut sums = UseVec::new(|_| 0usize);
755    ///
756    /// let result = (1..5)
757    ///     .into_par()
758    ///     .map(Some)
759    ///     .into_optional()
760    ///     .use_vec(&mut sums)
761    ///     .for_each(|local, x| *local += x);
762    ///
763    /// assert_eq!(result, Some(()));
764    /// assert_eq!(sums.into_vec().into_iter().sum::<usize>(), 10);
765    /// ```
766    fn for_each<F>(self, f: F) -> Option<()>
767    where
768        F: Fn(&mut Self::Use, Self::Elem) + Send + Copy,
769    {
770        self.map(f).reduce(|_, _, _| {}).map(|_| ())
771    }
772
773    /// Returns maximum successful element.
774    ///
775    /// Returns `None` on short-circuit failure.
776    ///
777    /// # Examples
778    ///
779    /// ```
780    /// use orx_parallel::*;
781    ///
782    /// let m = (1..5)
783    ///     .into_par()
784    ///     .map(Some)
785    ///     .into_optional()
786    ///     .use_new(|_| ())
787    ///     .max();
788    /// assert_eq!(m, Some(Some(4)));
789    /// ```
790    fn max(self) -> Option<Option<Self::Elem>>
791    where
792        Self::Elem: Ord + Send,
793    {
794        self.reduce(|_, a, b| Ord::max(a, b))
795    }
796
797    /// Returns successful element considered maximum by comparator `f`.
798    ///
799    /// Returns `None` on short-circuit failure.
800    ///
801    /// # Examples
802    ///
803    /// ```
804    /// use orx_parallel::*;
805    ///
806    /// let x = vec![-3_i32, 0, 1, 5, -10]
807    ///     .into_par()
808    ///     .map(Some)
809    ///     .into_optional()
810    ///     .use_new(|_| ())
811    ///     .max_by(|_, a, b| a.cmp(b));
812    /// assert_eq!(x, Some(Some(5)));
813    /// ```
814    fn max_by<F>(self, f: F) -> Option<Option<Self::Elem>>
815    where
816        Self::Elem: Send,
817        F: Fn(&mut Self::Use, &Self::Elem, &Self::Elem) -> Ordering + Sync,
818    {
819        let reduce = |u: &mut Self::Use, x, y| match f(u, &x, &y) {
820            Ordering::Greater | Ordering::Equal => x,
821            Ordering::Less => y,
822        };
823        self.reduce(reduce)
824    }
825
826    /// Returns successful element with maximum key value.
827    ///
828    /// Returns `None` on short-circuit failure.
829    ///
830    /// # Examples
831    ///
832    /// ```
833    /// use orx_parallel::*;
834    ///
835    /// let x = vec![-3_i32, 0, 1, 5, -10]
836    ///     .into_par()
837    ///     .map(Some)
838    ///     .into_optional()
839    ///     .use_new(|_| ())
840    ///     .max_by_key(|_, x| x.abs());
841    /// assert_eq!(x, Some(Some(-10)));
842    /// ```
843    fn max_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>>
844    where
845        Self::Elem: Send,
846        B: Ord,
847        F: Fn(&mut Self::Use, &Self::Elem) -> B + Sync,
848    {
849        let reduce = |u: &mut Self::Use, x, y| match f(u, &x).cmp(&f(u, &y)) {
850            Ordering::Greater | Ordering::Equal => x,
851            Ordering::Less => y,
852        };
853        self.reduce(reduce)
854    }
855
856    /// Returns minimum successful element.
857    ///
858    /// Returns `None` on short-circuit failure.
859    ///
860    /// # Examples
861    ///
862    /// ```
863    /// use orx_parallel::*;
864    ///
865    /// let m = (1..5)
866    ///     .into_par()
867    ///     .map(Some)
868    ///     .into_optional()
869    ///     .use_new(|_| ())
870    ///     .min();
871    /// assert_eq!(m, Some(Some(1)));
872    /// ```
873    fn min(self) -> Option<Option<Self::Elem>>
874    where
875        Self::Elem: Ord + Send,
876    {
877        self.reduce(|_, a, b| Ord::min(a, b))
878    }
879
880    /// Returns successful element considered minimum by comparator `f`.
881    ///
882    /// Returns `None` on short-circuit failure.
883    ///
884    /// # Examples
885    ///
886    /// ```
887    /// use orx_parallel::*;
888    ///
889    /// let x = vec![-3_i32, 0, 1, 5, -10]
890    ///     .into_par()
891    ///     .map(Some)
892    ///     .into_optional()
893    ///     .use_new(|_| ())
894    ///     .min_by(|_, a, b| a.cmp(b));
895    /// assert_eq!(x, Some(Some(-10)));
896    /// ```
897    fn min_by<F>(self, f: F) -> Option<Option<Self::Elem>>
898    where
899        Self::Elem: Send,
900        F: Fn(&mut Self::Use, &Self::Elem, &Self::Elem) -> Ordering + Sync,
901    {
902        let reduce = |u: &mut Self::Use, x, y| match f(u, &x, &y) {
903            Ordering::Less | Ordering::Equal => x,
904            Ordering::Greater => y,
905        };
906        self.reduce(reduce)
907    }
908
909    /// Returns successful element with minimum key value.
910    ///
911    /// Returns `None` on short-circuit failure.
912    ///
913    /// # Examples
914    ///
915    /// ```
916    /// use orx_parallel::*;
917    ///
918    /// let x = vec![-3_i32, 0, 1, 5, -10]
919    ///     .into_par()
920    ///     .map(Some)
921    ///     .into_optional()
922    ///     .use_new(|_| ())
923    ///     .min_by_key(|_, x| x.abs());
924    /// assert_eq!(x, Some(Some(0)));
925    /// ```
926    fn min_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>>
927    where
928        Self::Elem: Send,
929        B: Ord,
930        F: Fn(&mut Self::Use, &Self::Elem) -> B + Sync,
931    {
932        let reduce = |u: &mut Self::Use, x, y| match f(u, &x).cmp(&f(u, &y)) {
933            Ordering::Less | Ordering::Equal => x,
934            Ordering::Greater => y,
935        };
936        self.reduce(reduce)
937    }
938
939    /// Sums successful elements using [`Sum`] implementation.
940    ///
941    /// Returns `None` on short-circuit failure.
942    ///
943    /// # Examples
944    ///
945    /// ```
946    /// use orx_parallel::*;
947    ///
948    /// let s: Option<usize> = (1..5)
949    ///     .into_par()
950    ///     .map(Some)
951    ///     .into_optional()
952    ///     .use_new(|_| ())
953    ///     .sum();
954    /// assert_eq!(s, Some(10));
955    /// ```
956    fn sum<S>(self) -> Option<S>
957    where
958        Self::Elem: Sum<S>,
959        S: Send,
960    {
961        self.map(|_, x| Self::Elem::owned(x))
962            .reduce(|_, a, b| Self::Elem::add(a, b))
963            .map(|x| x.unwrap_or(Self::Elem::zero()))
964    }
965}