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()37 int p1()
38 {
39   return 123;
40 }
41 
thr()42 int thr()
43 {
44   throw std::logic_error("123");
45 }
46 
main()47 int 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