Coverage Report

Created: 2025-12-05 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rayon-1.11.0/src/iter/flatten.rs
Line
Count
Source
1
use super::plumbing::*;
2
use super::*;
3
4
/// `Flatten` turns each element to a parallel iterator, then flattens these iterators
5
/// together. This struct is created by the [`flatten()`] method on [`ParallelIterator`].
6
///
7
/// [`flatten()`]: ParallelIterator::flatten()
8
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
9
#[derive(Debug, Clone)]
10
pub struct Flatten<I> {
11
    base: I,
12
}
13
14
impl<I> Flatten<I> {
15
    /// Creates a new `Flatten` iterator.
16
0
    pub(super) fn new(base: I) -> Self {
17
0
        Flatten { base }
18
0
    }
19
}
20
21
impl<I> ParallelIterator for Flatten<I>
22
where
23
    I: ParallelIterator<Item: IntoParallelIterator>,
24
{
25
    type Item = <I::Item as IntoParallelIterator>::Item;
26
27
0
    fn drive_unindexed<C>(self, consumer: C) -> C::Result
28
0
    where
29
0
        C: UnindexedConsumer<Self::Item>,
30
    {
31
0
        let consumer = FlattenConsumer::new(consumer);
32
0
        self.base.drive_unindexed(consumer)
33
0
    }
34
}
35
36
// ////////////////////////////////////////////////////////////////////////
37
// Consumer implementation
38
39
struct FlattenConsumer<C> {
40
    base: C,
41
}
42
43
impl<C> FlattenConsumer<C> {
44
0
    fn new(base: C) -> Self {
45
0
        FlattenConsumer { base }
46
0
    }
47
}
48
49
impl<T, C> Consumer<T> for FlattenConsumer<C>
50
where
51
    C: UnindexedConsumer<T::Item>,
52
    T: IntoParallelIterator,
53
{
54
    type Folder = FlattenFolder<C, C::Result>;
55
    type Reducer = C::Reducer;
56
    type Result = C::Result;
57
58
0
    fn split_at(self, index: usize) -> (Self, Self, C::Reducer) {
59
0
        let (left, right, reducer) = self.base.split_at(index);
60
0
        (
61
0
            FlattenConsumer::new(left),
62
0
            FlattenConsumer::new(right),
63
0
            reducer,
64
0
        )
65
0
    }
66
67
0
    fn into_folder(self) -> Self::Folder {
68
0
        FlattenFolder {
69
0
            base: self.base,
70
0
            previous: None,
71
0
        }
72
0
    }
73
74
0
    fn full(&self) -> bool {
75
0
        self.base.full()
76
0
    }
77
}
78
79
impl<T, C> UnindexedConsumer<T> for FlattenConsumer<C>
80
where
81
    C: UnindexedConsumer<T::Item>,
82
    T: IntoParallelIterator,
83
{
84
0
    fn split_off_left(&self) -> Self {
85
0
        FlattenConsumer::new(self.base.split_off_left())
86
0
    }
87
88
0
    fn to_reducer(&self) -> Self::Reducer {
89
0
        self.base.to_reducer()
90
0
    }
91
}
92
93
struct FlattenFolder<C, R> {
94
    base: C,
95
    previous: Option<R>,
96
}
97
98
impl<T, C> Folder<T> for FlattenFolder<C, C::Result>
99
where
100
    C: UnindexedConsumer<T::Item>,
101
    T: IntoParallelIterator,
102
{
103
    type Result = C::Result;
104
105
0
    fn consume(self, item: T) -> Self {
106
0
        let par_iter = item.into_par_iter();
107
0
        let consumer = self.base.split_off_left();
108
0
        let result = par_iter.drive_unindexed(consumer);
109
110
0
        let previous = match self.previous {
111
0
            None => Some(result),
112
0
            Some(previous) => {
113
0
                let reducer = self.base.to_reducer();
114
0
                Some(reducer.reduce(previous, result))
115
            }
116
        };
117
118
0
        FlattenFolder {
119
0
            base: self.base,
120
0
            previous,
121
0
        }
122
0
    }
123
124
0
    fn complete(self) -> Self::Result {
125
0
        match self.previous {
126
0
            Some(previous) => previous,
127
0
            None => self.base.into_folder().complete(),
128
        }
129
0
    }
130
131
0
    fn full(&self) -> bool {
132
0
        self.base.full()
133
0
    }
134
}