1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // Copyright (C) 2011 Vicente J. Botet Escriba 11 // 12 // Distributed under the Boost Software License, Version 1.0. (See accompanying 13 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 14 15 // <boost/thread/shared_future.hpp> 16 17 // class shared_future<R> 18 19 // const R& shared_future::get(); 20 // R& shared_future<R&>::get(); 21 // void shared_future<void>::get(); 22 //#define BOOST_THREAD_VERSION 3 23 #define BOOST_THREAD_VERSION 4 24 25 #include <boost/thread/future.hpp> 26 #include <boost/thread/thread.hpp> 27 #include <boost/detail/lightweight_test.hpp> 28 29 #if defined BOOST_THREAD_USES_CHRONO 30 31 namespace boost 32 { 33 template <typename T> 34 struct wrap 35 { wrapboost::wrap36 wrap(T const& v) : value(v){} 37 T value; 38 39 }; 40 41 template <typename T> make_exception_ptr(T v)42exception_ptr make_exception_ptr(T v) { 43 return copy_exception(wrap<T>(v)); 44 } 45 } 46 func1(boost::promise<int> p)47void func1(boost::promise<int> p) 48 { 49 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 50 p.set_value(3); 51 } 52 func2(boost::promise<int> p)53void func2(boost::promise<int> p) 54 { 55 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 56 p.set_exception(boost::make_exception_ptr(3)); 57 } 58 59 int j = 0; 60 func3(boost::promise<int &> p)61void func3(boost::promise<int&> p) 62 { 63 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 64 j = 5; 65 p.set_value(j); 66 } 67 func4(boost::promise<int &> p)68void func4(boost::promise<int&> p) 69 { 70 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 71 p.set_exception(boost::make_exception_ptr(3.5)); 72 } 73 func5(boost::promise<void> p)74void func5(boost::promise<void> p) 75 { 76 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 77 p.set_value(); 78 } 79 func6(boost::promise<void> p)80void func6(boost::promise<void> p) 81 { 82 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 83 p.set_exception(boost::make_exception_ptr(4)); 84 } 85 86 main()87int main() 88 { 89 { 90 typedef int T; 91 { 92 boost::promise<T> p; 93 boost::shared_future<T> f((p.get_future())); 94 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 95 boost::thread(func1, boost::move(p)).detach(); 96 #else 97 p.set_value(3); 98 #endif 99 BOOST_TEST(f.valid()); 100 BOOST_TEST(f.get() == 3); 101 BOOST_TEST(f.valid()); 102 } 103 { 104 boost::promise<T> p; 105 boost::shared_future<T> f((p.get_future())); 106 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 107 boost::thread(func2, boost::move(p)).detach(); 108 #else 109 p.set_exception(boost::make_exception_ptr(3)); 110 #endif 111 try 112 { 113 BOOST_TEST(f.valid()); 114 BOOST_TEST(f.get() == 3); 115 BOOST_TEST(false); 116 } 117 catch (boost::wrap<int> const& i) 118 { 119 BOOST_TEST(i.value == 3); 120 } 121 catch (...) 122 { 123 BOOST_TEST(false); 124 } 125 BOOST_TEST(f.valid()); 126 } 127 } 128 { 129 typedef int& T; 130 { 131 boost::promise<T> p; 132 boost::shared_future<T> f((p.get_future())); 133 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 134 boost::thread(func3, boost::move(p)).detach(); 135 #else 136 int j=5; 137 p.set_value(j); 138 #endif 139 BOOST_TEST(f.valid()); 140 BOOST_TEST(f.get() == 5); 141 BOOST_TEST(f.valid()); 142 } 143 { 144 boost::promise<T> p; 145 boost::shared_future<T> f((p.get_future())); 146 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 147 boost::thread(func4, boost::move(p)).detach(); 148 #else 149 p.set_exception(boost::make_exception_ptr(3.5)); 150 #endif 151 try 152 { 153 BOOST_TEST(f.valid()); 154 BOOST_TEST(f.get() == 3); 155 BOOST_TEST(false); 156 } 157 catch (boost::wrap<double> const& i) 158 { 159 BOOST_TEST(i.value == 3.5); 160 } 161 BOOST_TEST(f.valid()); 162 } 163 } 164 165 typedef void T; 166 { 167 boost::promise<T> p; 168 boost::shared_future<T> f((p.get_future())); 169 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 170 boost::thread(func5, boost::move(p)).detach(); 171 #else 172 p.set_value(); 173 #endif 174 BOOST_TEST(f.valid()); 175 f.get(); 176 BOOST_TEST(f.valid()); 177 } 178 { 179 boost::promise<T> p; 180 boost::shared_future<T> f((p.get_future())); 181 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 182 boost::thread(func6, boost::move(p)).detach(); 183 #else 184 p.set_exception(boost::make_exception_ptr(4)); 185 #endif 186 try 187 { 188 BOOST_TEST(f.valid()); 189 f.get(); 190 BOOST_TEST(false); 191 } 192 catch (boost::wrap<int> const& i) 193 { 194 BOOST_TEST(i.value == 4); 195 } 196 catch (...) 197 { 198 BOOST_TEST(false); 199 } 200 BOOST_TEST(f.valid()); 201 } 202 203 return boost::report_errors(); 204 } 205 206 #else 207 #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" 208 #endif 209