orx_concurrent_vec/concurrent_slice/iter_shorthands.rs
1use crate::{elem::ConcurrentElement, ConcurrentSlice};
2use orx_pinned_vec::IntoConcurrentPinnedVec;
3
4impl<'a, T, P> ConcurrentSlice<'a, T, P>
5where
6 P: IntoConcurrentPinnedVec<ConcurrentElement<T>>,
7{
8 /// Returns an iterator to values obtained by mapping elements of the vec by `f`.
9 ///
10 /// Note that `vec.map(f)` is a shorthand for `vec.iter().map(move |elem| elem.map(|x: &T| f(x)))`.
11 ///
12 /// # Examples
13 ///
14 /// ```rust
15 /// use orx_concurrent_vec::*;
16 ///
17 /// let vec = ConcurrentVec::from_iter(0..4);
18 ///
19 /// let doubles: Vec<_> = vec.map(|x| x * 2).collect();
20 /// assert_eq!(doubles, [0, 2, 4, 6]);
21 /// ```
22 pub fn map<F, U>(&'a self, mut f: F) -> impl Iterator<Item = U> + 'a
23 where
24 F: FnMut(&T) -> U + 'a,
25 {
26 self.iter().map(move |elem| elem.map(|x: &T| f(x)))
27 }
28
29 /// Returns an iterator to elements filtered by using the predicate `f` on the values.
30 ///
31 /// Note that `vec.filter(f)` is a shorthand for `vec.iter().filter(move |elem| elem.map(|x: &T| f(x)))`.
32 ///
33 /// # Examples
34 ///
35 /// ```rust
36 /// use orx_concurrent_vec::*;
37 ///
38 /// let vec = ConcurrentVec::from_iter(0..4);
39 ///
40 /// let mut evens = vec.filter(|x| x % 2 == 0);
41 /// assert_eq!(evens.next().unwrap(), &0);
42 /// assert_eq!(evens.next().unwrap(), &2);
43 /// assert_eq!(evens.next(), None);
44 /// ```
45 pub fn filter<F>(&self, mut f: F) -> impl Iterator<Item = &ConcurrentElement<T>> + '_
46 where
47 F: FnMut(&T) -> bool + 'a,
48 {
49 self.iter().filter(move |elem| elem.map(|x: &T| f(x)))
50 }
51
52 /// Folds the values of the vec starting from the `init` using the fold function `f`.
53 ///
54 /// Note that `vec.fold(f)` is a shorthand for `vec.iter().fold(init, |agg, elem| elem.map(|x| f(agg, x)))`.
55 ///
56 /// # Examples
57 ///
58 /// ```rust
59 /// use orx_concurrent_vec::*;
60 ///
61 /// let vec = ConcurrentVec::from_iter(0..4);
62 ///
63 /// let sum = vec.fold(0, |sum, x| sum + x);
64 /// assert_eq!(sum, 6);
65 /// ```
66 pub fn fold<F, U>(&self, init: U, mut f: F) -> U
67 where
68 F: FnMut(U, &T) -> U,
69 {
70 self.iter().fold(init, |agg, elem| elem.map(|x| f(agg, x)))
71 }
72
73 /// Reduces the values of the slice using the reduction `f`; returns None if the vec is empty.
74 ///
75 /// # Examples
76 ///
77 /// ```rust
78 /// use orx_concurrent_vec::*;
79 ///
80 /// let vec = ConcurrentVec::new();
81 /// let sum = vec.reduce(|a, b| a + b);
82 /// assert_eq!(sum, None);
83 ///
84 /// vec.push(42);
85 /// let sum = vec.reduce(|a, b| a + b);
86 /// assert_eq!(sum, Some(42));
87 ///
88 /// vec.extend([6, 2]);
89 /// let sum = vec.reduce(|a, b| a + b);
90 /// assert_eq!(sum, Some(50));
91 /// ```
92 pub fn reduce<F>(&self, mut f: F) -> Option<T>
93 where
94 T: Clone,
95 F: FnMut(&T, &T) -> T,
96 {
97 let mut iter = self.iter();
98 match iter.next() {
99 Some(first) => {
100 let mut agg = first.cloned();
101 for elem in iter {
102 agg = elem.map(|x| f(&agg, x));
103 }
104 Some(agg)
105 }
106 None => None,
107 }
108 }
109}