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,2014 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/future.hpp> 16 17 // class promise<R> 18 19 // void promise::set_value(R&& r); 20 21 #define BOOST_THREAD_VERSION 3 22 23 #include <boost/thread/future.hpp> 24 #include <boost/detail/lightweight_test.hpp> 25 #include <boost/static_assert.hpp> 26 27 struct A 28 { AA29 A() : 30 value(0) 31 { 32 } AA33 A(int i) : 34 value(i) 35 { 36 } 37 BOOST_THREAD_MOVABLE_ONLY(A) 38 AA39 A(BOOST_THREAD_RV_REF(A) rhs) 40 { 41 if(rhs.value==0) 42 throw 9; 43 else 44 { 45 value=rhs.value; 46 rhs.value=0; 47 } 48 } operator =A49 A& operator=(BOOST_THREAD_RV_REF(A) rhs) 50 { 51 if(rhs.value==0) 52 throw 9; 53 else 54 { 55 value=rhs.value; 56 rhs.value=0; 57 } 58 return *this; 59 } 60 int value; 61 }; 62 make(int i)63A make(int i) { 64 return A(i); 65 } 66 67 struct movable2 68 { 69 int value_; 70 BOOST_THREAD_MOVABLE_ONLY(movable2) movable2movable271 movable2() : value_(1){} movable2movable272 movable2(int i) : value_(i){} 73 74 //Move constructor and assignment movable2movable275 movable2(BOOST_RV_REF(movable2) m) 76 { value_ = m.value_; m.value_ = 0; } 77 operator =movable278 movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m) 79 { value_ = m.value_; m.value_ = 0; return *this; } 80 movedmovable281 bool moved() const //Observer 82 { return !value_; } 83 valuemovable284 int value() const //Observer 85 { return value_; } 86 }; 87 88 move_return_function2(int i)89movable2 move_return_function2(int i) { 90 return movable2(i); 91 } 92 main()93int main() 94 { 95 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES 96 BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false)); 97 BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true)); 98 BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false)); 99 BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true)); 100 #endif 101 102 { 103 typedef A T; 104 T i; 105 boost::promise<T> p; 106 boost::future<T> f = p.get_future(); 107 try 108 { 109 p.set_value(boost::move(i)); 110 BOOST_TEST(false); 111 } 112 catch (int j) 113 { 114 BOOST_TEST(j == 9); 115 } 116 catch (...) 117 { 118 BOOST_TEST(false); 119 } 120 } 121 { 122 typedef A T; 123 T i; 124 boost::promise<T> p; 125 boost::future<T> f = p.get_future(); 126 try 127 { 128 p.set_value_deferred(boost::move(i)); 129 BOOST_TEST(!f.is_ready()); 130 p.notify_deferred(); 131 132 BOOST_TEST(false); 133 } 134 catch (int j) 135 { 136 BOOST_TEST(j == 9); 137 } 138 catch (...) 139 { 140 BOOST_TEST(false); 141 } 142 } 143 { 144 typedef A T; 145 T i; 146 boost::promise<T> p; 147 boost::future<T> f = p.get_future(); 148 try 149 { 150 p.set_value((T())); 151 BOOST_TEST(false); 152 } 153 catch (int j) 154 { 155 BOOST_TEST(j == 9); 156 } 157 catch (...) 158 { 159 BOOST_TEST(false); 160 } 161 } 162 { 163 typedef A T; 164 T i; 165 boost::promise<T> p; 166 boost::future<T> f = p.get_future(); 167 try 168 { 169 p.set_value_deferred((T())); 170 BOOST_TEST(false); 171 } 172 catch (int j) 173 { 174 BOOST_TEST(j == 9); 175 } 176 catch (...) 177 { 178 BOOST_TEST(false); 179 } 180 } 181 { 182 typedef A T; 183 T i(3); 184 boost::promise<T> p; 185 boost::future<T> f = p.get_future(); 186 p.set_value(boost::move(i)); 187 BOOST_TEST(f.get().value == 3); 188 try 189 { 190 T j(3); 191 p.set_value(boost::move(j)); 192 BOOST_TEST(false); 193 } 194 catch (const boost::future_error& e) 195 { 196 BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); 197 } 198 catch (...) 199 { 200 BOOST_TEST(false); 201 } 202 203 } 204 { 205 movable2 i(3); 206 boost::promise<movable2> p; 207 boost::future<movable2> f = p.get_future(); 208 p.set_value(move_return_function2(3)); 209 BOOST_TEST(f.get().value_ == 3); 210 try 211 { 212 movable2 j(3); 213 p.set_value(boost::move(j)); 214 BOOST_TEST(false); 215 } 216 catch (const boost::future_error& e) 217 { 218 BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); 219 } 220 catch (...) 221 { 222 BOOST_TEST(false); 223 } 224 225 } 226 { 227 boost::promise<A> p; 228 boost::future<A> f = p.get_future(); 229 p.set_value(make(3)); 230 BOOST_TEST(f.get().value == 3); 231 try 232 { 233 A j(3); 234 p.set_value(boost::move(j)); 235 BOOST_TEST(false); 236 } 237 catch (const boost::future_error& e) 238 { 239 BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); 240 } 241 catch (...) 242 { 243 BOOST_TEST(false); 244 } 245 246 } 247 { 248 typedef A T; 249 T i(3); 250 boost::promise<T> p; 251 boost::future<T> f = p.get_future(); 252 p.set_value(boost::move(i)); 253 BOOST_TEST(i.value == 0); 254 boost::promise<T> p2(boost::move(p)); 255 BOOST_TEST(f.get().value == 3); 256 257 } 258 { 259 typedef A T; 260 T i(3); 261 boost::promise<T> p; 262 boost::future<T> f = p.get_future(); 263 p.set_value(boost::move(i)); 264 BOOST_TEST(i.value == 0); 265 boost::promise<T> p2(boost::move(p)); 266 boost::future<T> f2(boost::move(f)); 267 BOOST_TEST(f2.get().value == 3); 268 269 } 270 { 271 typedef A T; 272 T i(3); 273 boost::promise<T> p; 274 p.set_value(boost::move(i)); 275 BOOST_TEST(i.value == 0); 276 boost::promise<T> p2(boost::move(p)); 277 boost::future<T> f = p2.get_future(); 278 BOOST_TEST(f.get().value == 3); 279 280 } 281 282 { 283 typedef boost::future<int> T; 284 boost::promise<int> pi; 285 T fi=pi.get_future(); 286 pi.set_value(3); 287 288 boost::promise<T> p; 289 boost::future<T> f = p.get_future(); 290 p.set_value(boost::move(fi)); 291 boost::future<T> f2(boost::move(f)); 292 BOOST_TEST(f2.get().get() == 3); 293 } 294 295 return boost::report_errors(); 296 } 297 298