Clementine
executor.hpp
1 //
2 // executor.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_EXECUTOR_HPP
12 #define 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 "asio/detail/config.hpp"
19 
20 #if !defined(ASIO_NO_TS_EXECUTORS)
21 
22 #include <typeinfo>
23 #include "asio/detail/cstddef.hpp"
24 #include "asio/detail/executor_function.hpp"
25 #include "asio/detail/memory.hpp"
26 #include "asio/detail/throw_exception.hpp"
27 #include "asio/execution_context.hpp"
28 
29 #include "asio/detail/push_options.hpp"
30 
31 namespace asio {
32 
35  : public std::exception
36 {
37 public:
39  ASIO_DECL bad_executor() ASIO_NOEXCEPT;
40 
42  ASIO_DECL virtual const char* what() const
43  ASIO_NOEXCEPT_OR_NOTHROW;
44 };
45 
47 class executor
48 {
49 public:
51  executor() ASIO_NOEXCEPT
52  : impl_(0)
53  {
54  }
55 
57  executor(nullptr_t) ASIO_NOEXCEPT
58  : impl_(0)
59  {
60  }
61 
63  executor(const executor& other) ASIO_NOEXCEPT
64  : impl_(other.clone())
65  {
66  }
67 
68 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
69  executor(executor&& other) ASIO_NOEXCEPT
71  : impl_(other.impl_)
72  {
73  other.impl_ = 0;
74  }
75 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
76 
78  template <typename Executor>
79  executor(Executor e);
80 
83  template <typename Executor, typename Allocator>
84  executor(allocator_arg_t, const Allocator& a, Executor e);
85 
88  {
89  destroy();
90  }
91 
93  executor& operator=(const executor& other) ASIO_NOEXCEPT
94  {
95  destroy();
96  impl_ = other.clone();
97  return *this;
98  }
99 
100 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
101  // Move assignment operator.
102  executor& operator=(executor&& other) ASIO_NOEXCEPT
103  {
104  destroy();
105  impl_ = other.impl_;
106  other.impl_ = 0;
107  return *this;
108  }
109 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
110 
112  executor& operator=(nullptr_t) ASIO_NOEXCEPT
113  {
114  destroy();
115  impl_ = 0;
116  return *this;
117  }
118 
121  template <typename Executor>
122  executor& operator=(ASIO_MOVE_ARG(Executor) e) ASIO_NOEXCEPT
123  {
124  executor tmp(ASIO_MOVE_CAST(Executor)(e));
125  destroy();
126  impl_ = tmp.impl_;
127  tmp.impl_ = 0;
128  return *this;
129  }
130 
132  execution_context& context() const ASIO_NOEXCEPT
133  {
134  return get_impl()->context();
135  }
136 
138  void on_work_started() const ASIO_NOEXCEPT
139  {
140  get_impl()->on_work_started();
141  }
142 
144  void on_work_finished() const ASIO_NOEXCEPT
145  {
146  get_impl()->on_work_finished();
147  }
148 
150 
162  template <typename Function, typename Allocator>
163  void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
164 
166 
178  template <typename Function, typename Allocator>
179  void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
180 
182 
194  template <typename Function, typename Allocator>
195  void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;
196 
198  typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
199  static void unspecified_bool_true(unspecified_bool_type_t) {}
200 
202  operator unspecified_bool_type() const ASIO_NOEXCEPT
203  {
204  return impl_ ? &executor::unspecified_bool_true : 0;
205  }
206 
208 
212 #if !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
213  const std::type_info& target_type() const ASIO_NOEXCEPT
214  {
215  return impl_ ? impl_->target_type() : typeid(void);
216  }
217 #else // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
218  const void* target_type() const ASIO_NOEXCEPT
219  {
220  return impl_ ? impl_->target_type() : 0;
221  }
222 #endif // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
223 
225 
229  template <typename Executor>
230  Executor* target() ASIO_NOEXCEPT;
231 
233 
237  template <typename Executor>
238  const Executor* target() const ASIO_NOEXCEPT;
239 
241  friend bool operator==(const executor& a,
242  const executor& b) ASIO_NOEXCEPT
243  {
244  if (a.impl_ == b.impl_)
245  return true;
246  if (!a.impl_ || !b.impl_)
247  return false;
248  return a.impl_->equals(b.impl_);
249  }
250 
252  friend bool operator!=(const executor& a,
253  const executor& b) ASIO_NOEXCEPT
254  {
255  return !(a == b);
256  }
257 
258 private:
259 #if !defined(GENERATING_DOCUMENTATION)
260  typedef detail::executor_function function;
261  template <typename, typename> class impl;
262 
263 #if !defined(ASIO_NO_TYPEID)
264  typedef const std::type_info& type_id_result_type;
265 #else // !defined(ASIO_NO_TYPEID)
266  typedef const void* type_id_result_type;
267 #endif // !defined(ASIO_NO_TYPEID)
268 
269  template <typename T>
270  static type_id_result_type type_id()
271  {
272 #if !defined(ASIO_NO_TYPEID)
273  return typeid(T);
274 #else // !defined(ASIO_NO_TYPEID)
275  static int unique_id;
276  return &unique_id;
277 #endif // !defined(ASIO_NO_TYPEID)
278  }
279 
280  // Base class for all polymorphic executor implementations.
281  class impl_base
282  {
283  public:
284  virtual impl_base* clone() const ASIO_NOEXCEPT = 0;
285  virtual void destroy() ASIO_NOEXCEPT = 0;
286  virtual execution_context& context() ASIO_NOEXCEPT = 0;
287  virtual void on_work_started() ASIO_NOEXCEPT = 0;
288  virtual void on_work_finished() ASIO_NOEXCEPT = 0;
289  virtual void dispatch(ASIO_MOVE_ARG(function)) = 0;
290  virtual void post(ASIO_MOVE_ARG(function)) = 0;
291  virtual void defer(ASIO_MOVE_ARG(function)) = 0;
292  virtual type_id_result_type target_type() const ASIO_NOEXCEPT = 0;
293  virtual void* target() ASIO_NOEXCEPT = 0;
294  virtual const void* target() const ASIO_NOEXCEPT = 0;
295  virtual bool equals(const impl_base* e) const ASIO_NOEXCEPT = 0;
296 
297  protected:
298  impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {}
299  virtual ~impl_base() {}
300 
301  private:
302  friend class executor;
303  const bool fast_dispatch_;
304  };
305 
306  // Helper function to check and return the implementation pointer.
307  impl_base* get_impl() const
308  {
309  if (!impl_)
310  {
311  bad_executor ex;
312  asio::detail::throw_exception(ex);
313  }
314  return impl_;
315  }
316 
317  // Helper function to clone another implementation.
318  impl_base* clone() const ASIO_NOEXCEPT
319  {
320  return impl_ ? impl_->clone() : 0;
321  }
322 
323  // Helper function to destroy an implementation.
324  void destroy() ASIO_NOEXCEPT
325  {
326  if (impl_)
327  impl_->destroy();
328  }
329 
330  impl_base* impl_;
331 #endif // !defined(GENERATING_DOCUMENTATION)
332 };
333 
334 } // namespace asio
335 
336 ASIO_USES_ALLOCATOR(asio::executor)
337 
338 #include "asio/detail/pop_options.hpp"
339 
340 #include "asio/impl/executor.hpp"
341 #if defined(ASIO_HEADER_ONLY)
342 # include "asio/impl/executor.ipp"
343 #endif // defined(ASIO_HEADER_ONLY)
344 
345 #endif // !defined(ASIO_NO_TS_EXECUTORS)
346 
347 #endif // ASIO_EXECUTOR_HPP
executor & operator=(const executor &other) ASIO_NOEXCEPT
Assignment operator.
Definition: executor.hpp:93
virtual ASIO_DECL const char * what() const ASIO_NOEXCEPT_OR_NOTHROW
Obtain message associated with exception.
Definition: executor.ipp:32
void on_work_finished() const ASIO_NOEXCEPT
Inform the executor that some work is no longer outstanding.
Definition: executor.hpp:144
Exception thrown when trying to access an empty polymorphic executor.
Definition: executor.hpp:34
executor & operator=(nullptr_t) ASIO_NOEXCEPT
Assignment operator for nullptr_t.
Definition: executor.hpp:112
ASIO_DECL bad_executor() ASIO_NOEXCEPT
Constructor.
Definition: executor.ipp:28
friend bool operator!=(const executor &a, const executor &b) ASIO_NOEXCEPT
Compare two executors for inequality.
Definition: executor.hpp:252
Definition: executor.hpp:197
Polymorphic wrapper for executors.
Definition: executor.hpp:47
A context for function object execution.
Definition: execution_context.hpp:105
void on_work_started() const ASIO_NOEXCEPT
Inform the executor that it has some outstanding work to do.
Definition: executor.hpp:138
const std::type_info & target_type() const ASIO_NOEXCEPT
Obtain type information for the target executor object.
Definition: executor.hpp:213
Definition: cstddef.hpp:26
~executor()
Destructor.
Definition: executor.hpp:87
Definition: executor_function.hpp:125
Definition: memory.hpp:64
friend bool operator==(const executor &a, const executor &b) ASIO_NOEXCEPT
Compare two executors for equality.
Definition: executor.hpp:241
executor(const executor &other) ASIO_NOEXCEPT
Copy constructor.
Definition: executor.hpp:63
executor() ASIO_NOEXCEPT
Default constructor.
Definition: executor.hpp:51
execution_context & context() const ASIO_NOEXCEPT
Obtain the underlying execution context.
Definition: executor.hpp:132
executor & operator=(ASIO_MOVE_ARG(Executor) e) ASIO_NOEXCEPT
Assignment operator to create a polymorphic wrapper for the specified executor.
Definition: executor.hpp:122
Definition: any_io_executor.hpp:28
executor(nullptr_t) ASIO_NOEXCEPT
Construct from nullptr.
Definition: executor.hpp:57