• 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 
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::future<int> f)35 int p2(boost::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::future<int> f)45 void p3(boost::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::future<int> f1 = boost::async(boost::launch::async, &p1);
60     BOOST_TEST(f1.valid());
61     boost::future<int> f2 = f1.then(&p2);
62     BOOST_TEST(f2.valid());
63     BOOST_TEST(! f1.valid());
64     try
65     {
66       BOOST_TEST(f2.get()==2);
67     }
68     catch (std::exception& ex)
69     {
70       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
71       BOOST_TEST(false);
72     }
73     catch (...)
74     {
75       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
76       BOOST_TEST(false);
77     }
78   }
79   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
80   {
81     boost::future<int> f1 = boost::async(boost::launch::async, &p1);
82     BOOST_TEST(f1.valid());
83     boost::future<void> f2 = f1.then(&p3);
84     BOOST_TEST(f2.valid());
85     try
86     {
87       f2.wait();
88     }
89     catch (std::exception& ex)
90     {
91       BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
92       BOOST_TEST(false);
93     }
94     catch (...)
95     {
96       BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
97       BOOST_TEST(false);
98     }
99   }
100   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
101   {
102     boost::future<int> f2 = boost::async(p1).then(&p2);
103     BOOST_TEST(f2.get()==2);
104   }
105   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
106   {
107     boost::future<int> f1 = boost::async(p1);
108     boost::future<int> f21 = f1.then(&p2);
109     boost::future<int> f2= f21.then(&p2);
110     BOOST_TEST(f2.get()==4);
111   }
112   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
113   {
114     boost::future<int> f1 = boost::async(p1);
115     boost::future<int> f2= f1.then(&p2).then(&p2);
116     BOOST_TEST(f2.get()==4);
117   }
118   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
119   {
120     boost::future<int> f2 = boost::async(p1).then(&p2).then(&p2);
121     BOOST_TEST(f2.get()==4);
122   }
123 
124   return boost::report_errors();
125 }
126 
127 #else
128 
main()129 int main()
130 {
131   return 0;
132 }
133 #endif
134