1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::par::par_empty::ParEmpty;
use orx_concurrent_iter::*;

/// Conversion into a parallel iterator.
///
/// Every regular iterator implementing [`Iterator`] also implements `IterIntoPar`.
///
/// See [`crate::IntoPar`] for conversion of common collections into parallel iterator.
///
/// Converting into a parallel iterator is achieved using the `par()` method.
///
/// # Examples
///
/// ```rust
/// use orx_parallel::*;
///
/// let numbers = || (0..24).filter(|x| x % 2 == 0);
/// let seq: usize = numbers().sum();
/// let par = numbers().par().sum();
/// assert_eq!(seq, par);
///
/// let numbers: Vec<_> = (10..420).collect();
/// let iter = || numbers.iter().cloned().skip(10);
/// let seq: Vec<_> = iter()
///     .filter(|x| x % 3 == 1)
///     .map(|x| x * 4)
///     .filter(|x| x < &456)
///     .flat_map(|x| [x, x + 1, x * 7])
///     .collect();
/// let par = iter()
///     .par()
///     .filter(|x| x % 3 == 1)
///     .map(|x| x * 4)
///     .filter(|x| x < &456)
///     .flat_map(|x| [x, x + 1, x * 7])
///     .collect_vec();
/// assert_eq!(par, seq);
/// ```
pub trait IterIntoPar<Iter: Iterator>
where
    Iter::Item: Send + Sync,
{
    /// Underlying concurrent iterator which provides the input elements to the defined parallel computation.
    type ConIter: ConcurrentIter;

    /// Conversion into a parallel iterator.
    ///
    /// Every regular iterator implementing [`Iterator`] also implements `IterIntoPar`.
    ///
    /// See [`crate::IntoPar`] for conversion of common collections into parallel iterator.
    ///
    /// Converting into a parallel iterator is achieved using the `par()` method.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use orx_parallel::*;
    ///
    /// let numbers = || (0..24).filter(|x| x % 2 == 0);
    /// let seq: usize = numbers().sum();
    /// let par = numbers().par().sum();
    /// assert_eq!(seq, par);
    ///
    /// let numbers: Vec<_> = (10..420).collect();
    /// let iter = || numbers.iter().cloned().skip(10);
    /// let seq: Vec<_> = iter()
    ///     .filter(|x| x % 3 == 1)
    ///     .map(|x| x * 4)
    ///     .filter(|x| x < &456)
    ///     .flat_map(|x| [x, x + 1, x * 7])
    ///     .collect();
    /// let par = iter()
    ///     .par()
    ///     .filter(|x| x % 3 == 1)
    ///     .map(|x| x * 4)
    ///     .filter(|x| x < &456)
    ///     .flat_map(|x| [x, x + 1, x * 7])
    ///     .collect_vec();
    /// assert_eq!(par, seq);
    /// ```
    fn par(self) -> ParEmpty<Self::ConIter>;
}

// iter

impl<Iter: Iterator> IterIntoPar<Iter> for Iter
where
    Iter::Item: Send + Sync,
{
    type ConIter = ConIterOfIter<Iter::Item, Iter>;

    fn par(self) -> ParEmpty<Self::ConIter> {
        ParEmpty::new(self.into_con_iter())
    }
}

impl<Iter: Iterator> IterIntoPar<Iter> for ConIterOfIter<Iter::Item, Iter>
where
    Iter::Item: Send + Sync,
{
    type ConIter = ConIterOfIter<Iter::Item, Iter>;

    fn par(self) -> ParEmpty<Self::ConIter> {
        ParEmpty::new(self)
    }
}