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