]> git.proxmox.com Git - rustc.git/blob - src/vendor/rustc-rayon/src/iter/find.rs
New upstream version 1.28.0~beta.14+dfsg1
[rustc.git] / src / vendor / rustc-rayon / src / iter / find.rs
1 use std::sync::atomic::{AtomicBool, Ordering};
2 use super::plumbing::*;
3 use super::*;
4
5 pub fn find<I, P>(pi: I, find_op: P) -> Option<I::Item>
6 where I: ParallelIterator,
7 P: Fn(&I::Item) -> bool + Sync
8 {
9 let found = AtomicBool::new(false);
10 let consumer = FindConsumer::new(&find_op, &found);
11 pi.drive_unindexed(consumer)
12 }
13
14 struct FindConsumer<'p, P: 'p> {
15 find_op: &'p P,
16 found: &'p AtomicBool,
17 }
18
19 impl<'p, P> FindConsumer<'p, P> {
20 fn new(find_op: &'p P, found: &'p AtomicBool) -> Self {
21 FindConsumer {
22 find_op: find_op,
23 found: found,
24 }
25 }
26 }
27
28 impl<'p, T, P: 'p> Consumer<T> for FindConsumer<'p, P>
29 where T: Send,
30 P: Fn(&T) -> bool + Sync
31 {
32 type Folder = FindFolder<'p, T, P>;
33 type Reducer = FindReducer;
34 type Result = Option<T>;
35
36 fn split_at(self, _index: usize) -> (Self, Self, Self::Reducer) {
37 (self.split_off_left(), self, FindReducer)
38 }
39
40 fn into_folder(self) -> Self::Folder {
41 FindFolder {
42 find_op: self.find_op,
43 found: self.found,
44 item: None,
45 }
46 }
47
48 fn full(&self) -> bool {
49 self.found.load(Ordering::Relaxed)
50 }
51 }
52
53
54 impl<'p, T, P: 'p> UnindexedConsumer<T> for FindConsumer<'p, P>
55 where T: Send,
56 P: Fn(&T) -> bool + Sync
57 {
58 fn split_off_left(&self) -> Self {
59 FindConsumer::new(self.find_op, self.found)
60 }
61
62 fn to_reducer(&self) -> Self::Reducer {
63 FindReducer
64 }
65 }
66
67
68 struct FindFolder<'p, T, P: 'p> {
69 find_op: &'p P,
70 found: &'p AtomicBool,
71 item: Option<T>,
72 }
73
74 impl<'p, T, P> Folder<T> for FindFolder<'p, T, P>
75 where P: Fn(&T) -> bool + 'p
76 {
77 type Result = Option<T>;
78
79 fn consume(mut self, item: T) -> Self {
80 if (self.find_op)(&item) {
81 self.found.store(true, Ordering::Relaxed);
82 self.item = Some(item);
83 }
84 self
85 }
86
87 fn complete(self) -> Self::Result {
88 self.item
89 }
90
91 fn full(&self) -> bool {
92 self.found.load(Ordering::Relaxed)
93 }
94 }
95
96
97 struct FindReducer;
98
99 impl<T> Reducer<Option<T>> for FindReducer {
100 fn reduce(self, left: Option<T>, right: Option<T>) -> Option<T> {
101 left.or(right)
102 }
103 }