Clementine
as_invocable.hpp
1 //
2 // execution/detail/as_invocable.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP
12 #define ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include "asio/detail/atomic_count.hpp"
20 #include "asio/detail/memory.hpp"
21 #include "asio/detail/type_traits.hpp"
22 #include "asio/execution/receiver_invocation_error.hpp"
23 #include "asio/execution/set_done.hpp"
24 #include "asio/execution/set_error.hpp"
25 #include "asio/execution/set_value.hpp"
26 
27 #include "asio/detail/push_options.hpp"
28 
29 namespace asio {
30 namespace execution {
31 namespace detail {
32 
33 #if defined(ASIO_HAS_MOVE)
34 
35 template <typename Receiver, typename>
36 struct as_invocable
37 {
38  Receiver* receiver_;
39 
40  explicit as_invocable(Receiver& r) ASIO_NOEXCEPT
41  : receiver_(asio::detail::addressof(r))
42  {
43  }
44 
45  as_invocable(as_invocable&& other) ASIO_NOEXCEPT
46  : receiver_(other.receiver_)
47  {
48  other.receiver_ = 0;
49  }
50 
51  ~as_invocable()
52  {
53  if (receiver_)
54  execution::set_done(ASIO_MOVE_OR_LVALUE(Receiver)(*receiver_));
55  }
56 
57  void operator()() ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT
58  {
59 #if !defined(ASIO_NO_EXCEPTIONS)
60  try
61  {
62 #endif // !defined(ASIO_NO_EXCEPTIONS)
63  execution::set_value(ASIO_MOVE_CAST(Receiver)(*receiver_));
64  receiver_ = 0;
65 #if !defined(ASIO_NO_EXCEPTIONS)
66  }
67  catch (...)
68  {
69 #if defined(ASIO_HAS_STD_EXCEPTION_PTR)
70  execution::set_error(ASIO_MOVE_CAST(Receiver)(*receiver_),
71  std::make_exception_ptr(receiver_invocation_error()));
72  receiver_ = 0;
73 #else // defined(ASIO_HAS_STD_EXCEPTION_PTR)
74  std::terminate();
75 #endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)
76  }
77 #endif // !defined(ASIO_NO_EXCEPTIONS)
78  }
79 };
80 
81 #else // defined(ASIO_HAS_MOVE)
82 
83 template <typename Receiver, typename>
85 {
86  Receiver* receiver_;
87  asio::detail::shared_ptr<asio::detail::atomic_count> ref_count_;
88 
89  explicit as_invocable(Receiver& r,
90  const asio::detail::shared_ptr<
91  asio::detail::atomic_count>& c) ASIO_NOEXCEPT
92  : receiver_(asio::detail::addressof(r)),
93  ref_count_(c)
94  {
95  }
96 
97  as_invocable(const as_invocable& other) ASIO_NOEXCEPT
98  : receiver_(other.receiver_),
99  ref_count_(other.ref_count_)
100  {
101  ++(*ref_count_);
102  }
103 
104  ~as_invocable()
105  {
106  if (--(*ref_count_) == 0)
107  execution::set_done(*receiver_);
108  }
109 
110  void operator()() ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT
111  {
112 #if !defined(ASIO_NO_EXCEPTIONS)
113  try
114  {
115 #endif // !defined(ASIO_NO_EXCEPTIONS)
116  execution::set_value(*receiver_);
117  ++(*ref_count_);
118  }
119 #if !defined(ASIO_NO_EXCEPTIONS)
120  catch (...)
121  {
122 #if defined(ASIO_HAS_STD_EXCEPTION_PTR)
123  execution::set_error(*receiver_,
124  std::make_exception_ptr(receiver_invocation_error()));
125  ++(*ref_count_);
126 #else // defined(ASIO_HAS_STD_EXCEPTION_PTR)
127  std::terminate();
128 #endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)
129  }
130 #endif // !defined(ASIO_NO_EXCEPTIONS)
131  }
132 };
133 
134 #endif // defined(ASIO_HAS_MOVE)
135 
136 template <typename T>
137 struct is_as_invocable : false_type
138 {
139 };
140 
141 template <typename Function, typename T>
142 struct is_as_invocable<as_invocable<Function, T> > : true_type
143 {
144 };
145 
146 } // namespace detail
147 } // namespace execution
148 } // namespace asio
149 
150 #include "asio/detail/pop_options.hpp"
151 
152 #endif // ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP
Definition: as_invocable.hpp:84
Definition: chrono.h:284
Definition: as_invocable.hpp:137
Definition: handler_work.hpp:37
Exception reported via set_error when an exception escapes from set_value.
Definition: receiver_invocation_error.hpp:28
Definition: any_io_executor.hpp:28