emplace_pass.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. // Copyright (C) 2011,2014 Vicente J. Botet Escriba
  10. //
  11. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  12. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  13. // <boost/thread/future.hpp>
  14. // class promise<R>
  15. // template <class ...Args>
  16. // void promise::emplace(Args&& ... args);
  17. #define BOOST_THREAD_VERSION 3
  18. #include <boost/thread/future.hpp>
  19. #include <boost/detail/lightweight_test.hpp>
  20. #include <boost/static_assert.hpp>
  21. struct A
  22. {
  23. A() :
  24. value(0)
  25. {
  26. }
  27. A(int i) :
  28. value(i)
  29. {
  30. }
  31. A(int i, int j) :
  32. value(i+j)
  33. {
  34. }
  35. BOOST_THREAD_MOVABLE_ONLY(A)
  36. A(BOOST_THREAD_RV_REF(A) rhs)
  37. {
  38. if(rhs.value==0)
  39. throw 9;
  40. else
  41. {
  42. value=rhs.value;
  43. rhs.value=0;
  44. }
  45. }
  46. A& operator=(BOOST_THREAD_RV_REF(A) rhs)
  47. {
  48. if(rhs.value==0)
  49. throw 9;
  50. else
  51. {
  52. value=rhs.value;
  53. rhs.value=0;
  54. }
  55. return *this;
  56. }
  57. int value;
  58. };
  59. A make(int i) {
  60. return A(i);
  61. }
  62. A make(int i, int j) {
  63. return A(i, j);
  64. }
  65. struct movable2
  66. {
  67. int value_;
  68. BOOST_THREAD_MOVABLE_ONLY(movable2)
  69. movable2() : value_(1){}
  70. movable2(int i) : value_(i){}
  71. movable2(int i, int j) : value_(i+j){}
  72. //Move constructor and assignment
  73. movable2(BOOST_RV_REF(movable2) m)
  74. { value_ = m.value_; m.value_ = 0; }
  75. movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
  76. { value_ = m.value_; m.value_ = 0; return *this; }
  77. bool moved() const //Observer
  78. { return !value_; }
  79. int value() const //Observer
  80. { return value_; }
  81. };
  82. movable2 move_return_function2(int i) {
  83. return movable2(i);
  84. }
  85. int main()
  86. {
  87. #if defined BOOST_NO_CXX11_RVALUE_REFERENCES
  88. BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
  89. BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
  90. BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false));
  91. BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true));
  92. #endif
  93. #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  94. {
  95. typedef A T;
  96. T i;
  97. boost::promise<T> p;
  98. boost::future<T> f = p.get_future();
  99. p.emplace();
  100. try
  101. {
  102. T a = f.get(); (void)a;
  103. BOOST_TEST(false);
  104. }
  105. catch (int j)
  106. {
  107. BOOST_TEST(j == 9);
  108. }
  109. catch (...)
  110. {
  111. BOOST_TEST(false);
  112. }
  113. }
  114. {
  115. typedef A T;
  116. boost::promise<T> p;
  117. boost::future<T> f = p.get_future();
  118. p.emplace(3);
  119. BOOST_TEST(f.get().value == 3);
  120. try
  121. {
  122. T j(3);
  123. p.set_value(boost::move(j));
  124. BOOST_TEST(false);
  125. }
  126. catch (const boost::future_error& e)
  127. {
  128. BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
  129. }
  130. catch (...)
  131. {
  132. BOOST_TEST(false);
  133. }
  134. }
  135. {
  136. boost::promise<movable2> p;
  137. boost::future<movable2> f = p.get_future();
  138. p.emplace(3);
  139. BOOST_TEST(f.get().value_ == 3);
  140. try
  141. {
  142. p.emplace(3);
  143. BOOST_TEST(false);
  144. }
  145. catch (const boost::future_error& e)
  146. {
  147. BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
  148. }
  149. catch (...)
  150. {
  151. BOOST_TEST(false);
  152. }
  153. }
  154. {
  155. boost::promise<A> p;
  156. boost::future<A> f = p.get_future();
  157. p.emplace(1,2);
  158. BOOST_TEST(f.get().value == 3);
  159. try
  160. {
  161. p.emplace(1,2);
  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. typedef A T;
  175. boost::promise<T> p;
  176. boost::future<T> f = p.get_future();
  177. p.emplace(3);
  178. boost::promise<T> p2(boost::move(p));
  179. BOOST_TEST(f.get().value == 3);
  180. }
  181. #endif
  182. return boost::report_errors();
  183. }