get_pass.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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 future<R>
  15. // const R& future::get();
  16. // R& future<R&>::get();
  17. // void future<void>::get();
  18. //#define BOOST_THREAD_VERSION 3
  19. #define BOOST_THREAD_VERSION 4
  20. //#define BOOST_THREAD_USES_LOG
  21. #define BOOST_THREAD_USES_LOG_THREAD_ID
  22. #include <boost/thread/detail/log.hpp>
  23. #include <boost/thread/future.hpp>
  24. #include <boost/thread/thread.hpp>
  25. #include <boost/detail/lightweight_test.hpp>
  26. #if defined BOOST_THREAD_USES_CHRONO
  27. #ifdef BOOST_MSVC
  28. #pragma warning(disable: 4127) // conditional expression is constant
  29. #endif
  30. namespace boost
  31. {
  32. template <typename T>
  33. struct wrap
  34. {
  35. wrap(T const& v) : value(v){}
  36. T value;
  37. };
  38. template <typename T>
  39. exception_ptr make_exception_ptr(T v) {
  40. return copy_exception(wrap<T>(v));
  41. }
  42. }
  43. void func1(boost::promise<int> p)
  44. {
  45. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  46. p.set_value(3);
  47. }
  48. void func2(boost::promise<int> p)
  49. {
  50. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  51. p.set_exception(boost::make_exception_ptr(3));
  52. }
  53. int j = 0;
  54. void func3(boost::promise<int&> p)
  55. {
  56. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  57. j = 5;
  58. p.set_value(j);
  59. }
  60. void func4(boost::promise<int&> p)
  61. {
  62. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  63. p.set_exception(boost::make_exception_ptr(3.5));
  64. }
  65. void func5(boost::promise<void> p)
  66. {
  67. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  68. p.set_value();
  69. }
  70. void func6(boost::promise<void> p)
  71. {
  72. boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
  73. p.set_exception(boost::make_exception_ptr(4));
  74. }
  75. int main()
  76. {
  77. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  78. {
  79. typedef int T;
  80. {
  81. boost::promise<T> p;
  82. boost::future<T> f = p.get_future();
  83. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  84. boost::thread(func1, boost::move(p)).detach();
  85. #else
  86. p.set_value(3);
  87. #endif
  88. BOOST_TEST(f.valid());
  89. BOOST_TEST(f.get() == 3);
  90. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  91. BOOST_TEST(!f.valid());
  92. #endif
  93. }
  94. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  95. {
  96. boost::promise<T> p;
  97. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  98. boost::future<T> f = p.get_future();
  99. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  100. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  101. boost::thread(func2, boost::move(p)).detach();
  102. #else
  103. p.set_exception(boost::make_exception_ptr(3));
  104. #endif
  105. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  106. try
  107. {
  108. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  109. BOOST_TEST(f.valid());
  110. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  111. BOOST_TEST(f.get() == 3);
  112. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  113. BOOST_TEST(false);
  114. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  115. }
  116. catch (boost::wrap<int> const& i)
  117. {
  118. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  119. BOOST_TEST(i.value == 3);
  120. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  121. }
  122. catch (...)
  123. {
  124. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  125. BOOST_TEST(false);
  126. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  127. }
  128. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  129. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  130. BOOST_TEST(!f.valid());
  131. #endif
  132. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  133. }
  134. }
  135. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  136. {
  137. typedef int& T;
  138. {
  139. boost::promise<T> p;
  140. boost::future<T> f = p.get_future();
  141. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  142. boost::thread(func3, boost::move(p)).detach();
  143. #else
  144. int j=5;
  145. p.set_value(j);
  146. #endif
  147. BOOST_TEST(f.valid());
  148. BOOST_TEST(f.get() == 5);
  149. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  150. BOOST_TEST(!f.valid());
  151. #endif
  152. }
  153. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  154. {
  155. boost::promise<T> p;
  156. boost::future<T> f = p.get_future();
  157. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  158. boost::thread(func4, boost::move(p)).detach();
  159. #else
  160. p.set_exception(boost::make_exception_ptr(3.5));
  161. #endif
  162. try
  163. {
  164. BOOST_TEST(f.valid());
  165. BOOST_TEST(f.get() == 3);
  166. BOOST_TEST(false);
  167. }
  168. catch (boost::wrap<double> const& i)
  169. {
  170. BOOST_TEST(i.value == 3.5);
  171. }
  172. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  173. BOOST_TEST(!f.valid());
  174. #endif
  175. }
  176. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  177. {
  178. boost::promise<T> p;
  179. boost::future<T> f = p.get_future();
  180. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  181. boost::thread(func4, boost::move(p)).detach();
  182. #else
  183. p.set_exception(boost::make_exception_ptr(3.5));
  184. #endif
  185. try
  186. {
  187. BOOST_TEST(f.valid());
  188. boost::exception_ptr ptr = f.get_exception_ptr();
  189. }
  190. catch (...)
  191. {
  192. BOOST_TEST(false);
  193. }
  194. BOOST_TEST(f.valid());
  195. }
  196. }
  197. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  198. typedef void T;
  199. {
  200. boost::promise<T> p;
  201. boost::future<T> f = p.get_future();
  202. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  203. boost::thread(func5, boost::move(p)).detach();
  204. #else
  205. p.set_value();
  206. #endif
  207. BOOST_TEST(f.valid());
  208. f.get();
  209. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  210. BOOST_TEST(!f.valid());
  211. #endif
  212. }
  213. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  214. {
  215. boost::promise<T> p;
  216. boost::future<T> f = p.get_future();
  217. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  218. boost::thread(func6, boost::move(p)).detach();
  219. #else
  220. p.set_exception(boost::make_exception_ptr(4));
  221. #endif
  222. try
  223. {
  224. BOOST_TEST(f.valid());
  225. f.get();
  226. BOOST_TEST(false);
  227. }
  228. catch (boost::wrap<int> const& i)
  229. {
  230. BOOST_TEST(i.value == 4);
  231. }
  232. catch (...)
  233. {
  234. BOOST_TEST(false);
  235. }
  236. #ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
  237. BOOST_TEST(!f.valid());
  238. #endif
  239. }
  240. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  241. return boost::report_errors();
  242. }
  243. #else
  244. #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
  245. #endif