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
22 
23 #ifdef BOOST_MSVC
24 #pragma warning(disable: 4127) // conditional expression is constant
25 #endif
26 
p1()27 int p1()
28 {
29   BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
30   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
31   BOOST_THREAD_LOG << "p1 >"  << BOOST_THREAD_END_LOG;
32   return 1;
33 }
34 
p2(boost::shared_future<int> f)35 int p2(boost::shared_future<int> f)
36 {
37   BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
38   BOOST_TEST(f.valid());
39   int i = f.get();
40   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
41   BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
42   return 2 * i;
43 }
44 
p3(boost::shared_future<int> f)45 void p3(boost::shared_future<int> f)
46 {
47   BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
48   BOOST_TEST(f.valid());
49   int i = f.get();
50   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
51   BOOST_THREAD_LOG << "p3 <" << &f << " " << i << BOOST_THREAD_END_LOG;
52   return ;
53 }
54 
main()55 int main()
56 {
57   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
58   {
59     boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
60     BOOST_TEST(f1.valid());
61     boost::future<int> f2 = f1.then(&p2);
62     BOOST_TEST(f2.valid());
63     try
64     {
65       BOOST_TEST(f2.get()==2);
66     }
67     catch (std::exception& ex)
68     {
69       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
70       BOOST_TEST(false);
71     }
72     catch (...)
73     {
74       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
75       BOOST_TEST(false);
76     }
77   }
78   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
79   {
80     boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
81     BOOST_TEST(f1.valid());
82     boost::future<int> f2 = f1.then(&p2);
83     boost::future<int> f3 = f1.then(&p2);
84     BOOST_TEST(f2.valid());
85     BOOST_TEST(f3.valid());
86     try
87     {
88       BOOST_TEST(f2.get()==2);
89       BOOST_TEST(f3.get()==2);
90     }
91     catch (std::exception& ex)
92     {
93       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
94       BOOST_TEST(false);
95     }
96     catch (...)
97     {
98       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
99       BOOST_TEST(false);
100     }
101   }
102   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
103   {
104     boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
105     BOOST_TEST(f1.valid());
106     boost::future<void> f2 = f1.then(&p3);
107     BOOST_TEST(f2.valid());
108     try
109     {
110       f2.wait();
111     }
112     catch (std::exception& ex)
113     {
114       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
115       BOOST_TEST(false);
116     }
117     catch (...)
118     {
119       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
120       BOOST_TEST(false);
121     }
122   }
123   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
124   {
125     boost::future<int> f2 = boost::async(p1).share().then(&p2);
126     BOOST_TEST(f2.get()==2);
127   }
128   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
129   {
130     boost::shared_future<int> f1 = boost::async(p1).share();
131     boost::shared_future<int> f21 = f1.then(&p2).share();
132     boost::future<int> f2= f21.then(&p2);
133     BOOST_TEST(f2.get()==4);
134   }
135   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
136   {
137     boost::shared_future<int> f1 = boost::async(p1).share();
138     boost::future<int> f2= f1.then(&p2).share().then(&p2);
139     BOOST_TEST(f2.get()==4);
140   }
141   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
142   {
143     boost::future<int> f2 = boost::async(p1).share().then(&p2).share().then(&p2);
144     BOOST_TEST(f2.get()==4);
145   }
146 
147   return boost::report_errors();
148 }
149 
150 #else
151 
main()152 int main()
153 {
154   return 0;
155 }
156 #endif
157