1 // Copyright (C) 2012-2013 Vicente Botet
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // <boost/thread/future.hpp>
7 
8 // class future<R>
9 
10 // template<typename F>
11 // auto then(F&& func) -> future<decltype(func(*this))>;
12 
13 #define BOOST_THREAD_VERSION 4
14 //#define BOOST_THREAD_USES_LOG
15 #define BOOST_THREAD_USES_LOG_THREAD_ID
16 #include <boost/thread/detail/log.hpp>
17 
18 #include <boost/thread/future.hpp>
19 #include <boost/detail/lightweight_test.hpp>
20 
21 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
22 
23 
p1()24 int p1()
25 {
26   BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
27   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
28   BOOST_THREAD_LOG << "p1 >"  << BOOST_THREAD_END_LOG;
29   return 1;
30 }
31 
p2(boost::future<int> f)32 int p2(boost::future<int> f)
33 {
34   BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
35   BOOST_TEST(f.valid());
36   int i = f.get();
37   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
38   BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
39   return 2 * i;
40 }
41 
p3(boost::future<int> f)42 void p3(boost::future<int> f)
43 {
44   BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
45   BOOST_TEST(f.valid());
46   int i = f.get();
47   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
48   BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG;
49   return;
50 }
51 
main()52 int main()
53 {
54   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
55   {
56     try
57     {
58       boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
59       BOOST_TEST(f1.valid());
60       {
61       boost::future<int> f2 = f1.then(&p2);
62       BOOST_TEST(f2.valid());
63       }
64       BOOST_TEST(! f1.valid());
65     }
66     catch (std::exception& ex)
67     {
68       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
69       BOOST_TEST(false);
70     }
71     catch (...)
72     {
73       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
74       BOOST_TEST(false);
75     }
76   }
77   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
78   {
79     boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
80     BOOST_TEST(f1.valid());
81     boost::future<int> f2 = f1.then(&p2);
82     BOOST_TEST(f2.valid());
83     BOOST_TEST(! f1.valid());
84     try
85     {
86       BOOST_TEST(f2.get()==2);
87     }
88     catch (std::exception& ex)
89     {
90       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
91       BOOST_TEST(false);
92     }
93     catch (...)
94     {
95       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
96       BOOST_TEST(false);
97     }
98   }
99   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
100   {
101     boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
102     BOOST_TEST(f1.valid());
103     boost::future<void> f2 = f1.then(&p3);
104     BOOST_TEST(f2.valid());
105     try
106     {
107       f2.wait();
108     }
109     catch (std::exception& ex)
110     {
111       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
112       BOOST_TEST(false);
113     }
114     catch (...)
115     {
116       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
117       BOOST_TEST(false);
118     }
119   }
120   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
121   {
122     boost::future<int> f2 = boost::async(boost::launch::deferred, p1).then(&p2);
123     BOOST_TEST(f2.get()==2);
124   }
125   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
126   {
127     boost::future<int> f1 = boost::async(boost::launch::deferred, p1);
128     boost::future<int> f21 = f1.then(&p2);
129     boost::future<int> f2= f21.then(&p2);
130     BOOST_TEST(f2.get()==4);
131   }
132   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
133   {
134     boost::future<int> f1 = boost::async(boost::launch::deferred, p1);
135     boost::future<int> f2= f1.then(&p2).then(&p2);
136     BOOST_TEST(f2.get()==4);
137   }
138   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
139   {
140     boost::future<int> f2 = boost::async(boost::launch::deferred, p1).then(&p2).then(&p2);
141     BOOST_TEST(f2.get()==4);
142   }
143 
144   return boost::report_errors();
145 }
146 
147 #else
148 
main()149 int main()
150 {
151   return 0;
152 }
153 #endif
154