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()27int 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)35int 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)45void 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()55int 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()129int main() 130 { 131 return 0; 132 } 133 #endif 134