1 //  Copyright (c) 2007-2015 Hartmut Kaiser
2 //  Copyright (c) 2013 Agustin Berge
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
5 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 
7 /// \file lcos/wait_any.hpp
8 
9 #if !defined(HPX_LCOS_WAIT_ANY_APR_17_2012_1143AM)
10 #define HPX_LCOS_WAIT_ANY_APR_17_2012_1143AM
11 
12 #if defined(DOXYGEN)
13 namespace hpx
14 {
15     /// The function \a wait_any is a non-deterministic choice operator. It
16     /// OR-composes all future objects given and returns after one future of
17     /// that list finishes execution.
18     ///
19     /// \param first    [in] The iterator pointing to the first element of a
20     ///                 sequence of \a future or \a shared_future objects for
21     ///                 which \a wait_any should wait.
22     /// \param last     [in] The iterator pointing to the last element of a
23     ///                 sequence of \a future or \a shared_future objects for
24     ///                 which \a wait_any should wait.
25     /// \param ec       [in,out] this represents the error status on exit, if
26     ///                 this is pre-initialized to \a hpx#throws the function
27     ///                 will throw on error instead.
28     ///
29     /// \note The function \a wait_any returns after at least one future has
30     ///       become ready. All input futures are still valid after \a wait_any
31     ///       returns.
32     ///
33     /// \note     As long as \a ec is not pre-initialized to \a hpx::throws this
34     ///           function doesn't throw but returns the result code using the
35     ///           parameter \a ec. Otherwise it throws an instance of
36     ///           \a hpx::exception.
37     ///
38     /// \note     None of the futures in the input sequence are invalidated.
39     template <typename InputIter>
40     void wait_any(InputIter first, InputIter last, error_code& ec = throws);
41 
42     /// The function \a wait_any is a non-deterministic choice operator. It
43     /// OR-composes all future objects given and returns after one future of
44     /// that list finishes execution.
45     ///
46     /// \param futures  [in] A vector holding an arbitrary amount of \a future or
47     ///                 \a shared_future objects for which \a wait_any should
48     ///                 wait.
49     /// \param ec       [in,out] this represents the error status on exit, if
50     ///                 this is pre-initialized to \a hpx#throws the function
51     ///                 will throw on error instead.
52     ///
53     /// \note The function \a wait_any returns after at least one future has
54     ///       become ready. All input futures are still valid after \a wait_any
55     ///       returns.
56     ///
57     /// \note     As long as \a ec is not pre-initialized to \a hpx::throws this
58     ///           function doesn't throw but returns the result code using the
59     ///           parameter \a ec. Otherwise it throws an instance of
60     ///           \a hpx::exception.
61     ///
62     /// \note     None of the futures in the input sequence are invalidated.
63     template <typename R>
64     void wait_any(std::vector<future<R>>& futures, error_code& ec = throws);
65 
66     /// The function \a wait_any is a non-deterministic choice operator. It
67     /// OR-composes all future objects given and returns after one future of
68     /// that list finishes execution.
69     ///
70     /// \param futures  [in] Amn array holding an arbitrary amount of \a future or
71     ///                 \a shared_future objects for which \a wait_any should
72     ///                 wait.
73     /// \param ec       [in,out] this represents the error status on exit, if
74     ///                 this is pre-initialized to \a hpx#throws the function
75     ///                 will throw on error instead.
76     ///
77     /// \note The function \a wait_any returns after at least one future has
78     ///       become ready. All input futures are still valid after \a wait_any
79     ///       returns.
80     ///
81     /// \note     As long as \a ec is not pre-initialized to \a hpx::throws this
82     ///           function doesn't throw but returns the result code using the
83     ///           parameter \a ec. Otherwise it throws an instance of
84     ///           \a hpx::exception.
85     ///
86     /// \note     None of the futures in the input sequence are invalidated.
87     template <typename R, std:;size_t N>
88     void wait_any(std::array<future<R>, N>& futures, error_code& ec = throws);
89 
90     /// The function \a wait_any is a non-deterministic choice operator. It
91     /// OR-composes all future objects given and returns after one future of
92     /// that list finishes execution.
93     ///
94     /// \param futures  [in] An arbitrary number of \a future or \a shared_future
95     ///                 objects, possibly holding different types for which
96     ///                 \a wait_any should wait.
97     /// \param ec       [in,out] this represents the error status on exit, if
98     ///                 this is pre-initialized to \a hpx#throws the function
99     ///                 will throw on error instead.
100     ///
101     /// \note The function \a wait_any returns after at least one future has
102     ///       become ready. All input futures are still valid after \a wait_any
103     ///       returns.
104     ///
105     /// \note     As long as \a ec is not pre-initialized to \a hpx::throws this
106     ///           function doesn't throw but returns the result code using the
107     ///           parameter \a ec. Otherwise it throws an instance of
108     ///           \a hpx::exception.
109     ///
110     /// \note     None of the futures in the input sequence are invalidated.
111     template <typename ...T>
112     void wait_any(error_code& ec, T&&... futures);
113 
114     /// The function \a wait_any is a non-deterministic choice operator. It
115     /// OR-composes all future objects given and returns after one future of
116     /// that list finishes execution.
117     ///
118     /// \param futures  [in] An arbitrary number of \a future or \a shared_future
119     ///                 objects, possibly holding different types for which
120     ///                 \a wait_any should wait.
121     ///
122     /// \note The function \a wait_any returns after at least one future has
123     ///       become ready. All input futures are still valid after \a wait_any
124     ///       returns.
125     ///
126     /// \note     None of the futures in the input sequence are invalidated.
127     template <typename ...T>
128     void wait_any(T&&... futures);
129 
130     /// The function \a wait_any_n is a non-deterministic choice operator. It
131     /// OR-composes all future objects given and returns after one future of
132     /// that list finishes execution.
133     ///
134     /// \param first    [in] The iterator pointing to the first element of a
135     ///                 sequence of \a future or \a shared_future objects for
136     ///                 which \a wait_any_n should wait.
137     /// \param count    [in] The number of elements in the sequence starting at
138     ///                 \a first.
139     /// \param ec       [in,out] this represents the error status on exit, if
140     ///                 this is pre-initialized to \a hpx#throws the function
141     ///                 will throw on error instead.
142     ///
143     /// \note The function \a wait_any_n returns after at least one future has
144     ///       become ready. All input futures are still valid after \a wait_any_n
145     ///       returns.
146     ///
147     /// \return         The function \a wait_all_n will return an iterator
148     ///                 referring to the first element in the input sequence
149     ///                 after the last processed element.
150     ///
151     /// \note     As long as \a ec is not pre-initialized to \a hpx::throws this
152     ///           function doesn't throw but returns the result code using the
153     ///           parameter \a ec. Otherwise it throws an instance of
154     ///           \a hpx::exception.
155     ///
156     /// \note     None of the futures in the input sequence are invalidated.
157     template <typename InputIter>
158     InputIter wait_any_n(InputIter first, std::size_t count,
159         error_code& ec = throws);
160 }
161 
162 #else // DOXYGEN
163 
164 #include <hpx/config.hpp>
165 #include <hpx/lcos/future.hpp>
166 #include <hpx/lcos/wait_some.hpp>
167 #include <hpx/runtime/threads/thread.hpp>
168 #include <hpx/util/always_void.hpp>
169 #include <hpx/util/detail/pp/strip_parens.hpp>
170 #include <hpx/util/tuple.hpp>
171 
172 #include <boost/utility/swap.hpp>
173 
174 #include <array>
175 #include <cstddef>
176 #include <utility>
177 #include <vector>
178 
179 ///////////////////////////////////////////////////////////////////////////////
180 namespace hpx { namespace lcos
181 {
182     ///////////////////////////////////////////////////////////////////////////
183     template <typename Future>
wait_any(std::vector<Future> const & futures,error_code & ec=throws)184     void wait_any(std::vector<Future> const& futures, error_code& ec = throws)
185     {
186         return lcos::wait_some(1, futures, ec);
187     }
188 
189     template <typename Future>
wait_any(std::vector<Future> & lazy_values,error_code & ec=throws)190     void wait_any(std::vector<Future>& lazy_values, error_code& ec = throws)
191     {
192         return lcos::wait_any(
193             const_cast<std::vector<Future> const&>(lazy_values), ec);
194     }
195 
196     template <typename Future>
wait_any(std::vector<Future> && lazy_values,error_code & ec=throws)197     void wait_any(std::vector<Future> && lazy_values, error_code& ec = throws)
198     {
199         return lcos::wait_any(
200             const_cast<std::vector<Future> const&>(lazy_values), ec);
201     }
202 
203     ///////////////////////////////////////////////////////////////////////////
204     template <typename Future, std::size_t N>
wait_any(std::array<Future,N> const & futures,error_code & ec=throws)205     void wait_any(std::array<Future, N> const& futures, error_code& ec = throws)
206     {
207         return lcos::wait_some(1, futures, ec);
208     }
209 
210     template <typename Future, std::size_t N>
wait_any(std::array<Future,N> & lazy_values,error_code & ec=throws)211     void wait_any(std::array<Future, N>& lazy_values, error_code& ec = throws)
212     {
213         return lcos::wait_any(
214             const_cast<std::array<Future, N> const&>(lazy_values), ec);
215     }
216 
217     template <typename Future, std::size_t N>
wait_any(std::array<Future,N> && lazy_values,error_code & ec=throws)218     void wait_any(std::array<Future, N> && lazy_values, error_code& ec = throws)
219     {
220         return lcos::wait_any(
221             const_cast<std::array<Future, N> const&>(lazy_values), ec);
222     }
223 
224     ///////////////////////////////////////////////////////////////////////////
225     template <typename Iterator>
226     typename util::always_void<
227         typename lcos::detail::future_iterator_traits<Iterator>::type
228     >::type
wait_any(Iterator begin,Iterator end,error_code & ec=throws)229     wait_any(Iterator begin, Iterator end, error_code& ec = throws)
230     {
231         return lcos::wait_some(1, begin, end, ec);
232     }
233 
wait_any(error_code & ec=throws)234     inline void wait_any(error_code& ec = throws)
235     {
236         return lcos::wait_some(1, ec);
237     }
238 
239     ///////////////////////////////////////////////////////////////////////////
240     template <typename Iterator>
241     Iterator
wait_any_n(Iterator begin,std::size_t count,error_code & ec=throws)242     wait_any_n(Iterator begin, std::size_t count,
243         error_code& ec = throws)
244     {
245         return wait_some_n(1, begin, count, ec);
246     }
247 
248     ///////////////////////////////////////////////////////////////////////////
249     template <typename... Ts>
wait_any(error_code & ec,Ts &&...ts)250     void wait_any(error_code& ec, Ts&&... ts)
251     {
252         return lcos::wait_some(1, ec, std::forward<Ts>(ts)...);
253     }
254 
255     template <typename... Ts>
wait_any(Ts &&...ts)256     void wait_any(Ts&&... ts)
257     {
258         return lcos::wait_some(1, std::forward<Ts>(ts)...);
259     }
260 }}
261 
262 namespace hpx
263 {
264     using lcos::wait_any;
265     using lcos::wait_any_n;
266 }
267 
268 #endif // DOXYGEN
269 #endif
270