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 
p1()33 int p1()
34 {
35   return 123;
36 }
37 
thr()38 int thr()
39 {
40   throw std::logic_error("123");
41 }
42 
main()43 int main()
44 {
45 #if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
46   if (0) // todo not yet implemented
47   { // invalid future copy-constructible
48     boost::future<int> f1;
49     BOOST_TEST(! f1.valid());
50     boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
51     BOOST_TEST(! f1.valid());
52     BOOST_TEST(all.valid());
53     boost::csbl::tuple<boost::future<int> > res = all.get();
54     BOOST_TEST(boost::csbl::get<0>(res).valid());
55     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
56     // has exception
57     //BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
58   }
59   { // is_ready future copy-constructible
60     boost::future<int> f1 = boost::make_ready_future(123);
61     BOOST_TEST(f1.valid());
62     BOOST_TEST(f1.is_ready());
63     boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
64     BOOST_TEST(! f1.valid());
65     BOOST_TEST(all.valid());
66     if (0) // todo FAILS not yet implemented
67     BOOST_TEST(all.is_ready());
68     boost::csbl::tuple<boost::future<int> > res = all.get();
69     BOOST_TEST(boost::csbl::get<0>(res).valid());
70     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
71     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
72   }
73   { // is_ready shared_future copy-constructible
74     boost::shared_future<int> f1 = boost::make_ready_future(123).share();
75     BOOST_TEST(f1.valid());
76     BOOST_TEST(f1.is_ready());
77     boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
78     BOOST_TEST(f1.valid());
79     BOOST_TEST(all.valid());
80     if (0) // todo FAILS not yet implemented
81     BOOST_TEST(all.is_ready());
82     boost::csbl::tuple<boost::shared_future<int> > res = all.get();
83     BOOST_TEST(boost::csbl::get<0>(res).valid());
84     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
85     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
86   }
87   { // packaged_task future copy-constructible
88     boost::packaged_task<int()> pt1(&p1);
89     boost::future<int> f1 = pt1.get_future();
90     BOOST_TEST(f1.valid());
91     boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
92     BOOST_TEST(! f1.valid());
93     BOOST_TEST(all.valid());
94     pt1();
95     boost::csbl::tuple<boost::future<int> > res = all.get();
96     BOOST_TEST(boost::csbl::get<0>(res).valid());
97     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
98     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
99   }
100   { // packaged_task shared_future copy-constructible
101     boost::packaged_task<int()> pt1(&p1);
102     boost::shared_future<int> f1 = pt1.get_future().share();
103     BOOST_TEST(f1.valid());
104     boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
105     BOOST_TEST(f1.valid());
106     BOOST_TEST(all.valid());
107     pt1();
108     boost::csbl::tuple<boost::shared_future<int> > res = all.get();
109     BOOST_TEST(boost::csbl::get<0>(res).valid());
110     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
111     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
112   }
113   { // packaged_task future copy-constructible
114     boost::packaged_task<int()> pt1(&thr);
115     boost::future<int> f1 = pt1.get_future();
116     BOOST_TEST(f1.valid());
117     boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
118     BOOST_TEST(! f1.valid());
119     BOOST_TEST(all.valid());
120     pt1();
121     boost::csbl::tuple<boost::future<int> > res = all.get();
122     BOOST_TEST(boost::csbl::get<0>(res).valid());
123     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
124     try {
125       boost::csbl::get<0>(res).get();
126       BOOST_TEST(false);
127     } catch (std::logic_error& ex) {
128       BOOST_TEST(ex.what() == std::string("123"));
129     } catch (...) {
130       BOOST_TEST(false);
131     }
132   }
133   { // async future copy-constructible
134     boost::future<int> f1 = boost::async(boost::launch::async, &p1);
135     BOOST_TEST(f1.valid());
136     boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
137     BOOST_TEST(! f1.valid());
138     BOOST_TEST(all.valid());
139     boost::csbl::tuple<boost::future<int> > res = all.get();
140     BOOST_TEST(boost::csbl::get<0>(res).valid());
141     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
142     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
143   }
144   { // async shared_future copy-constructible
145     boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
146     BOOST_TEST(f1.valid());
147     boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
148     BOOST_TEST(f1.valid());
149     BOOST_TEST(all.valid());
150     boost::csbl::tuple<boost::shared_future<int> > res = all.get();
151     BOOST_TEST(boost::csbl::get<0>(res).valid());
152     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
153     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
154   }
155 #if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
156   // fixme darwin-4.8.0_11 terminate called without an active exception
157   { // deferred future copy-constructible
158     boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
159     boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
160     BOOST_TEST(! f1.valid());
161     BOOST_TEST(all.valid());
162     boost::csbl::tuple<boost::future<int> > res = all.get();
163     BOOST_TEST(boost::csbl::get<0>(res).valid());
164     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
165     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
166   }
167   // fixme darwin-4.8.0_11 terminate called without an active exception
168   { // deferred shared_future copy-constructible
169     boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
170     boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
171     BOOST_TEST(f1.valid());
172     BOOST_TEST(all.valid());
173     boost::csbl::tuple<boost::shared_future<int> > res = all.get();
174     BOOST_TEST(boost::csbl::get<0>(res).valid());
175     BOOST_TEST(boost::csbl::get<0>(res).is_ready());
176     BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
177   }
178 #endif
179 #endif
180   return boost::report_errors();
181 }
182 
183