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 // template <class ...Args> 20 // void promise::emplace(Args&& ... args); 21 22 #define BOOST_THREAD_VERSION 3 23 24 #include <boost/thread/future.hpp> 25 #include <boost/detail/lightweight_test.hpp> 26 #include <boost/static_assert.hpp> 27 28 struct A 29 { AA30 A() : 31 value(0) 32 { 33 } AA34 A(int i) : 35 value(i) 36 { 37 } AA38 A(int i, int j) : 39 value(i+j) 40 { 41 } 42 BOOST_THREAD_MOVABLE_ONLY(A) 43 AA44 A(BOOST_THREAD_RV_REF(A) rhs) 45 { 46 if(rhs.value==0) 47 throw 9; 48 else 49 { 50 value=rhs.value; 51 rhs.value=0; 52 } 53 } operator =A54 A& operator=(BOOST_THREAD_RV_REF(A) rhs) 55 { 56 if(rhs.value==0) 57 throw 9; 58 else 59 { 60 value=rhs.value; 61 rhs.value=0; 62 } 63 return *this; 64 } 65 int value; 66 }; 67 make(int i)68A make(int i) { 69 return A(i); 70 } make(int i,int j)71A make(int i, int j) { 72 return A(i, j); 73 } 74 75 struct movable2 76 { 77 int value_; 78 BOOST_THREAD_MOVABLE_ONLY(movable2) movable2movable279 movable2() : value_(1){} movable2movable280 movable2(int i) : value_(i){} movable2movable281 movable2(int i, int j) : value_(i+j){} 82 83 //Move constructor and assignment movable2movable284 movable2(BOOST_RV_REF(movable2) m) 85 { value_ = m.value_; m.value_ = 0; } 86 operator =movable287 movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m) 88 { value_ = m.value_; m.value_ = 0; return *this; } 89 movedmovable290 bool moved() const //Observer 91 { return !value_; } 92 valuemovable293 int value() const //Observer 94 { return value_; } 95 }; 96 97 move_return_function2(int i)98movable2 move_return_function2(int i) { 99 return movable2(i); 100 } 101 main()102int main() 103 { 104 #if defined BOOST_NO_CXX11_RVALUE_REFERENCES 105 BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false)); 106 BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true)); 107 BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false)); 108 BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true)); 109 #endif 110 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 111 112 { 113 typedef A T; 114 T i; 115 boost::promise<T> p; 116 boost::future<T> f = p.get_future(); 117 p.emplace(); 118 try 119 { 120 T a = f.get(); (void)a; 121 BOOST_TEST(false); 122 } 123 catch (int j) 124 { 125 BOOST_TEST(j == 9); 126 } 127 catch (...) 128 { 129 BOOST_TEST(false); 130 } 131 } 132 { 133 typedef A T; 134 boost::promise<T> p; 135 boost::future<T> f = p.get_future(); 136 p.emplace(3); 137 BOOST_TEST(f.get().value == 3); 138 try 139 { 140 T j(3); 141 p.set_value(boost::move(j)); 142 BOOST_TEST(false); 143 } 144 catch (const boost::future_error& e) 145 { 146 BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); 147 } 148 catch (...) 149 { 150 BOOST_TEST(false); 151 } 152 153 } 154 { 155 boost::promise<movable2> p; 156 boost::future<movable2> f = p.get_future(); 157 p.emplace(3); 158 BOOST_TEST(f.get().value_ == 3); 159 try 160 { 161 p.emplace(3); 162 BOOST_TEST(false); 163 } 164 catch (const boost::future_error& e) 165 { 166 BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); 167 } 168 catch (...) 169 { 170 BOOST_TEST(false); 171 } 172 173 } 174 { 175 boost::promise<A> p; 176 boost::future<A> f = p.get_future(); 177 p.emplace(1,2); 178 BOOST_TEST(f.get().value == 3); 179 try 180 { 181 p.emplace(1,2); 182 BOOST_TEST(false); 183 } 184 catch (const boost::future_error& e) 185 { 186 BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); 187 } 188 catch (...) 189 { 190 BOOST_TEST(false); 191 } 192 193 } 194 { 195 typedef A T; 196 boost::promise<T> p; 197 boost::future<T> f = p.get_future(); 198 p.emplace(3); 199 boost::promise<T> p2(boost::move(p)); 200 BOOST_TEST(f.get().value == 3); 201 202 } 203 #endif 204 205 return boost::report_errors(); 206 } 207 208