]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/executor.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / executor.hpp
1 //
2 // executor.hpp
3 // ~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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 BOOST_ASIO_EXECUTOR_HPP
12 #define BOOST_ASIO_EXECUTOR_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19 #include <typeinfo>
20 #include <boost/asio/detail/cstddef.hpp>
21 #include <boost/asio/detail/memory.hpp>
22 #include <boost/asio/detail/throw_exception.hpp>
23 #include <boost/asio/execution_context.hpp>
24
25 #include <boost/asio/detail/push_options.hpp>
26
27 namespace boost {
28 namespace asio {
29
30 /// Exception thrown when trying to access an empty polymorphic executor.
31 class bad_executor
32 : public std::exception
33 {
34 public:
35 /// Constructor.
36 BOOST_ASIO_DECL bad_executor() BOOST_ASIO_NOEXCEPT;
37
38 /// Obtain message associated with exception.
39 BOOST_ASIO_DECL virtual const char* what() const
40 BOOST_ASIO_NOEXCEPT_OR_NOTHROW;
41 };
42
43 /// Polymorphic wrapper for executors.
44 class executor
45 {
46 public:
47 /// Default constructor.
48 executor() BOOST_ASIO_NOEXCEPT
49 : impl_(0)
50 {
51 }
52
53 /// Construct from nullptr.
54 executor(nullptr_t) BOOST_ASIO_NOEXCEPT
55 : impl_(0)
56 {
57 }
58
59 /// Copy constructor.
60 executor(const executor& other) BOOST_ASIO_NOEXCEPT
61 : impl_(other.clone())
62 {
63 }
64
65 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
66 /// Move constructor.
67 executor(executor&& other) BOOST_ASIO_NOEXCEPT
68 : impl_(other.impl_)
69 {
70 other.impl_ = 0;
71 }
72 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
73
74 /// Construct a polymorphic wrapper for the specified executor.
75 template <typename Executor>
76 executor(Executor e);
77
78 /// Allocator-aware constructor to create a polymorphic wrapper for the
79 /// specified executor.
80 template <typename Executor, typename Allocator>
81 executor(allocator_arg_t, const Allocator& a, Executor e);
82
83 /// Destructor.
84 ~executor()
85 {
86 destroy();
87 }
88
89 /// Assignment operator.
90 executor& operator=(const executor& other) BOOST_ASIO_NOEXCEPT
91 {
92 destroy();
93 impl_ = other.clone();
94 return *this;
95 }
96
97 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
98 // Move assignment operator.
99 executor& operator=(executor&& other) BOOST_ASIO_NOEXCEPT
100 {
101 destroy();
102 impl_ = other.impl_;
103 other.impl_ = 0;
104 return *this;
105 }
106 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
107
108 /// Assignment operator for nullptr_t.
109 executor& operator=(nullptr_t) BOOST_ASIO_NOEXCEPT
110 {
111 destroy();
112 impl_ = 0;
113 return *this;
114 }
115
116 /// Assignment operator to create a polymorphic wrapper for the specified
117 /// executor.
118 template <typename Executor>
119 executor& operator=(BOOST_ASIO_MOVE_ARG(Executor) e) BOOST_ASIO_NOEXCEPT
120 {
121 executor tmp(BOOST_ASIO_MOVE_CAST(Executor)(e));
122 destroy();
123 impl_ = tmp.impl_;
124 tmp.impl_ = 0;
125 return *this;
126 }
127
128 /// Obtain the underlying execution context.
129 execution_context& context() const BOOST_ASIO_NOEXCEPT
130 {
131 return get_impl()->context();
132 }
133
134 /// Inform the executor that it has some outstanding work to do.
135 void on_work_started() const BOOST_ASIO_NOEXCEPT
136 {
137 get_impl()->on_work_started();
138 }
139
140 /// Inform the executor that some work is no longer outstanding.
141 void on_work_finished() const BOOST_ASIO_NOEXCEPT
142 {
143 get_impl()->on_work_finished();
144 }
145
146 /// Request the executor to invoke the given function object.
147 /**
148 * This function is used to ask the executor to execute the given function
149 * object. The function object is executed according to the rules of the
150 * target executor object.
151 *
152 * @param f The function object to be called. The executor will make a copy
153 * of the handler object as required. The function signature of the function
154 * object must be: @code void function(); @endcode
155 *
156 * @param a An allocator that may be used by the executor to allocate the
157 * internal storage needed for function invocation.
158 */
159 template <typename Function, typename Allocator>
160 void dispatch(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
161
162 /// Request the executor to invoke the given function object.
163 /**
164 * This function is used to ask the executor to execute the given function
165 * object. The function object is executed according to the rules of the
166 * target executor object.
167 *
168 * @param f The function object to be called. The executor will make
169 * a copy of the handler object as required. The function signature of the
170 * function object must be: @code void function(); @endcode
171 *
172 * @param a An allocator that may be used by the executor to allocate the
173 * internal storage needed for function invocation.
174 */
175 template <typename Function, typename Allocator>
176 void post(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
177
178 /// Request the executor to invoke the given function object.
179 /**
180 * This function is used to ask the executor to execute the given function
181 * object. The function object is executed according to the rules of the
182 * target executor object.
183 *
184 * @param f The function object to be called. The executor will make
185 * a copy of the handler object as required. The function signature of the
186 * function object must be: @code void function(); @endcode
187 *
188 * @param a An allocator that may be used by the executor to allocate the
189 * internal storage needed for function invocation.
190 */
191 template <typename Function, typename Allocator>
192 void defer(BOOST_ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
193
194 struct unspecified_bool_type_t {};
195 typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
196 static void unspecified_bool_true(unspecified_bool_type_t) {}
197
198 /// Operator to test if the executor contains a valid target.
199 operator unspecified_bool_type() const BOOST_ASIO_NOEXCEPT
200 {
201 return impl_ ? &executor::unspecified_bool_true : 0;
202 }
203
204 /// Obtain type information for the target executor object.
205 /**
206 * @returns If @c *this has a target type of type @c T, <tt>typeid(T)</tt>;
207 * otherwise, <tt>typeid(void)</tt>.
208 */
209 #if !defined(BOOST_ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
210 const std::type_info& target_type() const BOOST_ASIO_NOEXCEPT
211 {
212 return impl_ ? impl_->target_type() : typeid(void);
213 }
214 #else // !defined(BOOST_ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
215 const void* target_type() const BOOST_ASIO_NOEXCEPT
216 {
217 return impl_ ? impl_->target_type() : 0;
218 }
219 #endif // !defined(BOOST_ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
220
221 /// Obtain a pointer to the target executor object.
222 /**
223 * @returns If <tt>target_type() == typeid(T)</tt>, a pointer to the stored
224 * executor target; otherwise, a null pointer.
225 */
226 template <typename Executor>
227 Executor* target() BOOST_ASIO_NOEXCEPT;
228
229 /// Obtain a pointer to the target executor object.
230 /**
231 * @returns If <tt>target_type() == typeid(T)</tt>, a pointer to the stored
232 * executor target; otherwise, a null pointer.
233 */
234 template <typename Executor>
235 const Executor* target() const BOOST_ASIO_NOEXCEPT;
236
237 /// Compare two executors for equality.
238 friend bool operator==(const executor& a,
239 const executor& b) BOOST_ASIO_NOEXCEPT
240 {
241 if (a.impl_ == b.impl_)
242 return true;
243 if (!a.impl_ || !b.impl_)
244 return false;
245 return a.impl_->equals(b.impl_);
246 }
247
248 /// Compare two executors for inequality.
249 friend bool operator!=(const executor& a,
250 const executor& b) BOOST_ASIO_NOEXCEPT
251 {
252 return !(a == b);
253 }
254
255 private:
256 #if !defined(GENERATING_DOCUMENTATION)
257 class function;
258 template <typename, typename> class impl;
259
260 #if !defined(BOOST_ASIO_NO_TYPEID)
261 typedef const std::type_info& type_id_result_type;
262 #else // !defined(BOOST_ASIO_NO_TYPEID)
263 typedef const void* type_id_result_type;
264 #endif // !defined(BOOST_ASIO_NO_TYPEID)
265
266 template <typename T>
267 static type_id_result_type type_id()
268 {
269 #if !defined(BOOST_ASIO_NO_TYPEID)
270 return typeid(T);
271 #else // !defined(BOOST_ASIO_NO_TYPEID)
272 static int unique_id;
273 return &unique_id;
274 #endif // !defined(BOOST_ASIO_NO_TYPEID)
275 }
276
277 // Base class for all polymorphic executor implementations.
278 class impl_base
279 {
280 public:
281 virtual impl_base* clone() const BOOST_ASIO_NOEXCEPT = 0;
282 virtual void destroy() BOOST_ASIO_NOEXCEPT = 0;
283 virtual execution_context& context() BOOST_ASIO_NOEXCEPT = 0;
284 virtual void on_work_started() BOOST_ASIO_NOEXCEPT = 0;
285 virtual void on_work_finished() BOOST_ASIO_NOEXCEPT = 0;
286 virtual void dispatch(BOOST_ASIO_MOVE_ARG(function)) = 0;
287 virtual void post(BOOST_ASIO_MOVE_ARG(function)) = 0;
288 virtual void defer(BOOST_ASIO_MOVE_ARG(function)) = 0;
289 virtual type_id_result_type target_type() const BOOST_ASIO_NOEXCEPT = 0;
290 virtual void* target() BOOST_ASIO_NOEXCEPT = 0;
291 virtual const void* target() const BOOST_ASIO_NOEXCEPT = 0;
292 virtual bool equals(const impl_base* e) const BOOST_ASIO_NOEXCEPT = 0;
293
294 protected:
295 impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {}
296 virtual ~impl_base() {}
297
298 private:
299 friend class executor;
300 const bool fast_dispatch_;
301 };
302
303 // Helper function to check and return the implementation pointer.
304 impl_base* get_impl() const
305 {
306 if (!impl_)
307 {
308 bad_executor ex;
309 boost::asio::detail::throw_exception(ex);
310 }
311 return impl_;
312 }
313
314 // Helper function to clone another implementation.
315 impl_base* clone() const BOOST_ASIO_NOEXCEPT
316 {
317 return impl_ ? impl_->clone() : 0;
318 }
319
320 // Helper function to destroy an implementation.
321 void destroy() BOOST_ASIO_NOEXCEPT
322 {
323 if (impl_)
324 impl_->destroy();
325 }
326
327 impl_base* impl_;
328 #endif // !defined(GENERATING_DOCUMENTATION)
329 };
330
331 } // namespace asio
332 } // namespace boost
333
334 BOOST_ASIO_USES_ALLOCATOR(boost::asio::executor)
335
336 #include <boost/asio/detail/pop_options.hpp>
337
338 #include <boost/asio/impl/executor.hpp>
339 #if defined(BOOST_ASIO_HEADER_ONLY)
340 # include <boost/asio/impl/executor.ipp>
341 #endif // defined(BOOST_ASIO_HEADER_ONLY)
342
343 #endif // BOOST_ASIO_EXECUTOR_HPP