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