1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // Copyright (C) 2014 Vicente J. Botet Escriba 11 // 12 // Distributed under the Boost Software License, Version 1.0. (See accompanying 13 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 14 15 // <boost/thread/future.hpp> 16 17 // template <class T, class Ts> 18 // future<tuple<T>> when_all(T&&); 19 20 #include <boost/config.hpp> 21 22 #if ! defined BOOST_NO_CXX11_DECLTYPE 23 #define BOOST_RESULT_OF_USE_DECLTYPE 24 #endif 25 26 27 #define BOOST_THREAD_VERSION 4 28 29 #include <boost/thread/future.hpp> 30 #include <boost/detail/lightweight_test.hpp> 31 #include <stdexcept> 32 33 #ifdef BOOST_MSVC 34 #pragma warning(disable: 4127) // conditional expression is constant 35 #endif 36 p1()37int p1() 38 { 39 return 123; 40 } 41 thr()42int thr() 43 { 44 throw std::logic_error("123"); 45 } 46 main()47int main() 48 { 49 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY 50 if (0) // todo not yet implemented 51 { // invalid future copy-constructible 52 boost::future<int> f1; 53 BOOST_TEST(! f1.valid()); 54 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); 55 BOOST_TEST(! f1.valid()); 56 BOOST_TEST(all.valid()); 57 boost::csbl::tuple<boost::future<int> > res = all.get(); 58 BOOST_TEST(boost::csbl::get<0>(res).valid()); 59 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 60 // has exception 61 //BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 62 } 63 { // is_ready future copy-constructible 64 boost::future<int> f1 = boost::make_ready_future(123); 65 BOOST_TEST(f1.valid()); 66 BOOST_TEST(f1.is_ready()); 67 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); 68 BOOST_TEST(! f1.valid()); 69 BOOST_TEST(all.valid()); 70 if (0) // todo FAILS not yet implemented 71 BOOST_TEST(all.is_ready()); 72 boost::csbl::tuple<boost::future<int> > res = all.get(); 73 BOOST_TEST(boost::csbl::get<0>(res).valid()); 74 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 75 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 76 } 77 { // is_ready shared_future copy-constructible 78 boost::shared_future<int> f1 = boost::make_ready_future(123).share(); 79 BOOST_TEST(f1.valid()); 80 BOOST_TEST(f1.is_ready()); 81 boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); 82 BOOST_TEST(f1.valid()); 83 BOOST_TEST(all.valid()); 84 if (0) // todo FAILS not yet implemented 85 BOOST_TEST(all.is_ready()); 86 boost::csbl::tuple<boost::shared_future<int> > res = all.get(); 87 BOOST_TEST(boost::csbl::get<0>(res).valid()); 88 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 89 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 90 } 91 { // packaged_task future copy-constructible 92 boost::packaged_task<int()> pt1(&p1); 93 boost::future<int> f1 = pt1.get_future(); 94 BOOST_TEST(f1.valid()); 95 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); 96 BOOST_TEST(! f1.valid()); 97 BOOST_TEST(all.valid()); 98 pt1(); 99 boost::csbl::tuple<boost::future<int> > res = all.get(); 100 BOOST_TEST(boost::csbl::get<0>(res).valid()); 101 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 102 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 103 } 104 { // packaged_task shared_future copy-constructible 105 boost::packaged_task<int()> pt1(&p1); 106 boost::shared_future<int> f1 = pt1.get_future().share(); 107 BOOST_TEST(f1.valid()); 108 boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); 109 BOOST_TEST(f1.valid()); 110 BOOST_TEST(all.valid()); 111 pt1(); 112 boost::csbl::tuple<boost::shared_future<int> > res = all.get(); 113 BOOST_TEST(boost::csbl::get<0>(res).valid()); 114 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 115 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 116 } 117 { // packaged_task future copy-constructible 118 boost::packaged_task<int()> pt1(&thr); 119 boost::future<int> f1 = pt1.get_future(); 120 BOOST_TEST(f1.valid()); 121 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); 122 BOOST_TEST(! f1.valid()); 123 BOOST_TEST(all.valid()); 124 pt1(); 125 boost::csbl::tuple<boost::future<int> > res = all.get(); 126 BOOST_TEST(boost::csbl::get<0>(res).valid()); 127 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 128 try { 129 boost::csbl::get<0>(res).get(); 130 BOOST_TEST(false); 131 } catch (std::logic_error& ex) { 132 BOOST_TEST(ex.what() == std::string("123")); 133 } catch (...) { 134 BOOST_TEST(false); 135 } 136 } 137 { // async future copy-constructible 138 boost::future<int> f1 = boost::async(boost::launch::async, &p1); 139 BOOST_TEST(f1.valid()); 140 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); 141 BOOST_TEST(! f1.valid()); 142 BOOST_TEST(all.valid()); 143 boost::csbl::tuple<boost::future<int> > res = all.get(); 144 BOOST_TEST(boost::csbl::get<0>(res).valid()); 145 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 146 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 147 } 148 { // async shared_future copy-constructible 149 boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); 150 BOOST_TEST(f1.valid()); 151 boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); 152 BOOST_TEST(f1.valid()); 153 BOOST_TEST(all.valid()); 154 boost::csbl::tuple<boost::shared_future<int> > res = all.get(); 155 BOOST_TEST(boost::csbl::get<0>(res).valid()); 156 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 157 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 158 } 159 #if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD 160 // fixme darwin-4.8.0_11 terminate called without an active exception 161 { // deferred future copy-constructible 162 boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); 163 boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); 164 BOOST_TEST(! f1.valid()); 165 BOOST_TEST(all.valid()); 166 boost::csbl::tuple<boost::future<int> > res = all.get(); 167 BOOST_TEST(boost::csbl::get<0>(res).valid()); 168 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 169 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 170 } 171 // fixme darwin-4.8.0_11 terminate called without an active exception 172 { // deferred shared_future copy-constructible 173 boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share(); 174 boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); 175 BOOST_TEST(f1.valid()); 176 BOOST_TEST(all.valid()); 177 boost::csbl::tuple<boost::shared_future<int> > res = all.get(); 178 BOOST_TEST(boost::csbl::get<0>(res).valid()); 179 BOOST_TEST(boost::csbl::get<0>(res).is_ready()); 180 BOOST_TEST(boost::csbl::get<0>(res).get() == 123); 181 } 182 #endif 183 #endif 184 return boost::report_errors(); 185 } 186 187