capture.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef BOOST_LEAF_CAPTURE_HPP_INCLUDED
  2. #define BOOST_LEAF_CAPTURE_HPP_INCLUDED
  3. // Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc.
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/leaf/config.hpp>
  7. #include <boost/leaf/handle_errors.hpp>
  8. #if BOOST_LEAF_CFG_CAPTURE
  9. namespace boost { namespace leaf {
  10. namespace leaf_detail
  11. {
  12. template <class R, bool IsResult = is_result_type<R>::value>
  13. struct is_result_tag;
  14. template <class R>
  15. struct is_result_tag<R, false>
  16. {
  17. };
  18. template <class R>
  19. struct is_result_tag<R, true>
  20. {
  21. };
  22. }
  23. #ifdef BOOST_LEAF_NO_EXCEPTIONS
  24. namespace leaf_detail
  25. {
  26. template <class R, class F, class... A>
  27. inline
  28. decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
  29. capture_impl(is_result_tag<R, false>, F && f, A... a) noexcept
  30. {
  31. return std::forward<F>(f)(std::forward<A>(a)...);
  32. }
  33. template <class R, class Future>
  34. inline
  35. decltype(std::declval<Future>().get())
  36. future_get_impl(is_result_tag<R, false>, Future & fut) noexcept
  37. {
  38. return fut.get();
  39. }
  40. }
  41. #else
  42. namespace leaf_detail
  43. {
  44. // Not defined, no longer supported. Please use try_capture_all instead of make_shared_context/capture.
  45. template <class R, class F, class... A>
  46. decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
  47. capture_impl(is_result_tag<R, false>, F && f, A... a);
  48. // Not defined, no longer supported. Please use try_capture_all instead of make_shared_context/capture.
  49. template <class R, class Future>
  50. decltype(std::declval<Future>().get())
  51. future_get_impl(is_result_tag<R, false>, Future & fut );
  52. }
  53. #endif
  54. namespace leaf_detail
  55. {
  56. template <class R, class F, class... A>
  57. inline
  58. decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
  59. capture_impl(is_result_tag<R, true>, F && f, A... a) noexcept
  60. {
  61. return try_capture_all(
  62. [&]
  63. {
  64. return std::forward<F>(f)(std::forward<A>(a)...);
  65. } );
  66. }
  67. template <class R, class Future>
  68. inline
  69. decltype(std::declval<Future>().get())
  70. future_get_impl(is_result_tag<R, true>, Future & fut) noexcept
  71. {
  72. if( auto r = fut.get() )
  73. return r;
  74. else
  75. {
  76. r.unload();
  77. return r;
  78. }
  79. }
  80. }
  81. template <class F, class... A>
  82. inline
  83. decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
  84. capture(context_ptr &&, F && f, A... a)
  85. {
  86. using namespace leaf_detail;
  87. return capture_impl(is_result_tag<decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))>(), std::forward<F>(f), std::forward<A>(a)...);
  88. }
  89. template <class Future>
  90. inline
  91. decltype(std::declval<Future>().get())
  92. future_get( Future & fut )
  93. {
  94. using namespace leaf_detail;
  95. return future_get_impl(is_result_tag<decltype(std::declval<Future>().get())>(), fut);
  96. }
  97. } }
  98. #endif
  99. #endif