2017
[folly.git] / folly / fibers / WhenN.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17
18 #include <iterator>
19 #include <memory>
20 #include <type_traits>
21 #include <utility>
22 #include <vector>
23
24 namespace folly {
25 namespace fibers {
26
27 /**
28  * Schedules several tasks and blocks until n of these tasks are completed.
29  * If any of these n tasks throws an exception, this exception will be
30  * re-thrown, but only when n tasks are complete. If several tasks throw
31  * exceptions one of them will be re-thrown.
32  *
33  * @param first Range of tasks to be scheduled
34  * @param last
35  * @param n Number of tasks to wait for
36  *
37  * @return vector of pairs (task index, return value of task)
38  */
39 template <class InputIterator>
40 typename std::vector<
41     typename std::enable_if<
42         !std::is_same<
43             typename std::result_of<typename std::iterator_traits<
44                 InputIterator>::value_type()>::type,
45             void>::value,
46         typename std::pair<
47             size_t,
48             typename std::result_of<typename std::iterator_traits<
49                 InputIterator>::value_type()>::type>>::
50         type> inline collectN(InputIterator first, InputIterator last, size_t n);
51
52 /**
53  * collectN specialization for functions returning void
54  *
55  * @param first Range of tasks to be scheduled
56  * @param last
57  * @param n Number of tasks to wait for
58  *
59  * @return vector of completed task indices
60  */
61 template <class InputIterator>
62 typename std::enable_if<
63     std::is_same<
64         typename std::result_of<
65             typename std::iterator_traits<InputIterator>::value_type()>::type,
66         void>::value,
67     std::vector<size_t>>::
68     type inline collectN(InputIterator first, InputIterator last, size_t n);
69
70 /**
71  * Schedules several tasks and blocks until all of these tasks are completed.
72  * If any of the tasks throws an exception, this exception will be re-thrown,
73  * but only when all the tasks are complete. If several tasks throw exceptions
74  * one of them will be re-thrown.
75  *
76  * @param first Range of tasks to be scheduled
77  * @param last
78  *
79  * @return vector of values returned by tasks
80  */
81 template <class InputIterator>
82 typename std::vector<typename std::enable_if<
83     !std::is_same<
84         typename std::result_of<
85             typename std::iterator_traits<InputIterator>::value_type()>::type,
86         void>::value,
87     typename std::result_of<
88         typename std::iterator_traits<InputIterator>::value_type()>::
89         type>::type> inline collectAll(InputIterator first, InputIterator last);
90
91 /**
92  * collectAll specialization for functions returning void
93  *
94  * @param first Range of tasks to be scheduled
95  * @param last
96  */
97 template <class InputIterator>
98 typename std::enable_if<
99     std::is_same<
100         typename std::result_of<
101             typename std::iterator_traits<InputIterator>::value_type()>::type,
102         void>::value,
103     void>::type inline collectAll(InputIterator first, InputIterator last);
104
105 /**
106  * Schedules several tasks and blocks until one of them is completed.
107  * If this task throws an exception, this exception will be re-thrown.
108  * Exceptions thrown by all other tasks will be ignored.
109  *
110  * @param first Range of tasks to be scheduled
111  * @param last
112  *
113  * @return pair of index of the first completed task and its return value
114  */
115 template <class InputIterator>
116 typename std::enable_if<
117     !std::is_same<
118         typename std::result_of<
119             typename std::iterator_traits<InputIterator>::value_type()>::type,
120         void>::value,
121     typename std::pair<
122         size_t,
123         typename std::result_of<typename std::iterator_traits<
124             InputIterator>::value_type()>::type>>::
125     type inline collectAny(InputIterator first, InputIterator last);
126
127 /**
128  * WhenAny specialization for functions returning void.
129  *
130  * @param first Range of tasks to be scheduled
131  * @param last
132  *
133  * @return index of the first completed task
134  */
135 template <class InputIterator>
136 typename std::enable_if<
137     std::is_same<
138         typename std::result_of<
139             typename std::iterator_traits<InputIterator>::value_type()>::type,
140         void>::value,
141     size_t>::type inline collectAny(InputIterator first, InputIterator last);
142 }
143 }
144
145 #include <folly/fibers/WhenN-inl.h>