operator_pass.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 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 packaged_task<R>
  15. // void operator()();
  16. //#define BOOST_THREAD_VERSION 3
  17. #define BOOST_THREAD_VERSION 4
  18. #include <boost/thread/future.hpp>
  19. #include <boost/detail/lightweight_test.hpp>
  20. #if defined BOOST_THREAD_USES_CHRONO
  21. #if BOOST_THREAD_VERSION == 4
  22. #define BOOST_THREAD_DETAIL_SIGNATURE double()
  23. #else
  24. #define BOOST_THREAD_DETAIL_SIGNATURE double
  25. #endif
  26. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
  27. #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  28. #define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
  29. #define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
  30. #else
  31. #define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
  32. #define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
  33. #endif
  34. #else
  35. #define BOOST_THREAD_DETAIL_SIGNATURE_2 double
  36. #define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
  37. #endif
  38. class E : public std::exception
  39. {
  40. public:
  41. long data;
  42. explicit E(long i) :
  43. data(i)
  44. {
  45. }
  46. const char* what() const throw() { return ""; }
  47. ~E() throw() {}
  48. };
  49. class A
  50. {
  51. long data_;
  52. public:
  53. explicit A(long i) :
  54. data_(i)
  55. {
  56. }
  57. long operator()() const
  58. {
  59. if (data_ == 0) BOOST_THROW_EXCEPTION(E(6));
  60. return data_;
  61. }
  62. long operator()(long i, long j) const
  63. {
  64. if (j == 'z') BOOST_THROW_EXCEPTION(E(6));
  65. return data_ + i + j;
  66. }
  67. ~A() {}
  68. };
  69. void func0(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
  70. {
  71. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  72. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  73. p(3, 'a');
  74. #else
  75. p();
  76. #endif
  77. }
  78. void func1(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
  79. {
  80. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  81. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  82. p(3, 'z');
  83. #else
  84. p();
  85. #endif
  86. }
  87. void func2(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
  88. {
  89. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  90. p(3, 'a');
  91. #else
  92. p();
  93. #endif
  94. try
  95. {
  96. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  97. p(3, 'c');
  98. #else
  99. p();
  100. #endif
  101. }
  102. catch (const boost::future_error& e)
  103. {
  104. BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
  105. }
  106. }
  107. void func3(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
  108. {
  109. try
  110. {
  111. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  112. p(3, 'a');
  113. #else
  114. p();
  115. #endif
  116. }
  117. catch (const boost::future_error& e)
  118. {
  119. BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
  120. }
  121. }
  122. int main()
  123. {
  124. {
  125. boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
  126. boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
  127. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  128. boost::thread(func0, boost::move(p)).detach();
  129. #else
  130. //p();
  131. #endif
  132. //BOOST_TEST(f.get() == 5.0);
  133. }
  134. {
  135. boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(0));
  136. boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
  137. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  138. boost::thread(func1, boost::move(p)).detach();
  139. #endif
  140. try
  141. {
  142. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  143. #else
  144. p();
  145. #endif
  146. f.get();
  147. BOOST_TEST(false);
  148. }
  149. catch (const E& e)
  150. {
  151. BOOST_TEST(e.data == 6);
  152. }
  153. catch (...)
  154. {
  155. BOOST_TEST(false);
  156. }
  157. }
  158. {
  159. boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
  160. boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
  161. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  162. boost::thread t(func2, boost::move(p));
  163. #else
  164. p();
  165. #endif
  166. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  167. BOOST_TEST(f.get() == 105);
  168. t.join();
  169. #else
  170. BOOST_TEST(f.get() == 5.0);
  171. #endif
  172. }
  173. {
  174. boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p;
  175. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  176. boost::thread t(func3, boost::move(p));
  177. t.join();
  178. #else
  179. try
  180. {
  181. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  182. p(3, 'a');
  183. #else
  184. p();
  185. #endif
  186. }
  187. catch (const boost::future_error& e)
  188. {
  189. BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
  190. }
  191. #endif
  192. }
  193. return boost::report_errors();
  194. }
  195. #else
  196. #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
  197. #endif