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 template <typename T> 32 struct wrap 33 { wrapwrap34 wrap(T const& v) : value(v){} 35 T value; 36 37 }; 38 39 template <typename T> make_exception_ptr(T v)40boost::exception_ptr make_exception_ptr(T v) { 41 return boost::copy_exception(wrap<T>(v)); 42 } 43 func1(boost::promise<int> p)44void func1(boost::promise<int> p) 45 { 46 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 47 p.set_value(3); 48 } 49 func2(boost::promise<int> p)50void func2(boost::promise<int> p) 51 { 52 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 53 p.set_exception(::make_exception_ptr(3)); 54 } 55 56 int j = 0; 57 func3(boost::promise<int &> p)58void func3(boost::promise<int&> p) 59 { 60 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 61 j = 5; 62 p.set_value(j); 63 } 64 func4(boost::promise<int &> p)65void func4(boost::promise<int&> p) 66 { 67 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 68 p.set_exception(::make_exception_ptr(3.5)); 69 } 70 func5(boost::promise<void> p)71void func5(boost::promise<void> p) 72 { 73 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 74 p.set_value(); 75 } 76 func6(boost::promise<void> p)77void func6(boost::promise<void> p) 78 { 79 boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); 80 p.set_exception(::make_exception_ptr(4)); 81 } 82 83 main()84int main() 85 { 86 { 87 typedef int T; 88 { 89 boost::promise<T> p; 90 boost::shared_future<T> f((p.get_future())); 91 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 92 boost::thread(func1, boost::move(p)).detach(); 93 #else 94 p.set_value(3); 95 #endif 96 BOOST_TEST(f.valid()); 97 BOOST_TEST(f.get() == 3); 98 BOOST_TEST(f.valid()); 99 } 100 { 101 boost::promise<T> p; 102 boost::shared_future<T> f((p.get_future())); 103 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 104 boost::thread(func2, boost::move(p)).detach(); 105 #else 106 p.set_exception(::make_exception_ptr(3)); 107 #endif 108 try 109 { 110 BOOST_TEST(f.valid()); 111 BOOST_TEST(f.get() == 3); 112 BOOST_TEST(false); 113 } 114 catch (::wrap<int> const& i) 115 { 116 BOOST_TEST(i.value == 3); 117 } 118 catch (...) 119 { 120 BOOST_TEST(false); 121 } 122 BOOST_TEST(f.valid()); 123 } 124 } 125 { 126 typedef int& T; 127 { 128 boost::promise<T> p; 129 boost::shared_future<T> f((p.get_future())); 130 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 131 boost::thread(func3, boost::move(p)).detach(); 132 #else 133 int j=5; 134 p.set_value(j); 135 #endif 136 BOOST_TEST(f.valid()); 137 BOOST_TEST(f.get() == 5); 138 BOOST_TEST(f.valid()); 139 } 140 { 141 boost::promise<T> p; 142 boost::shared_future<T> f((p.get_future())); 143 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 144 boost::thread(func4, boost::move(p)).detach(); 145 #else 146 p.set_exception(::make_exception_ptr(3.5)); 147 #endif 148 try 149 { 150 BOOST_TEST(f.valid()); 151 BOOST_TEST(f.get() == 3); 152 BOOST_TEST(false); 153 } 154 catch (::wrap<double> const& i) 155 { 156 BOOST_TEST(i.value == 3.5); 157 } 158 BOOST_TEST(f.valid()); 159 } 160 } 161 162 typedef void T; 163 { 164 boost::promise<T> p; 165 boost::shared_future<T> f((p.get_future())); 166 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 167 boost::thread(func5, boost::move(p)).detach(); 168 #else 169 p.set_value(); 170 #endif 171 BOOST_TEST(f.valid()); 172 f.get(); 173 BOOST_TEST(f.valid()); 174 } 175 { 176 boost::promise<T> p; 177 boost::shared_future<T> f((p.get_future())); 178 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) 179 boost::thread(func6, boost::move(p)).detach(); 180 #else 181 p.set_exception(::make_exception_ptr(4)); 182 #endif 183 try 184 { 185 BOOST_TEST(f.valid()); 186 f.get(); 187 BOOST_TEST(false); 188 } 189 catch (::wrap<int> const& i) 190 { 191 BOOST_TEST(i.value == 4); 192 } 193 catch (...) 194 { 195 BOOST_TEST(false); 196 } 197 BOOST_TEST(f.valid()); 198 } 199 200 return boost::report_errors(); 201 } 202 203 #else 204 #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" 205 #endif 206