File indexing completed on 2025-01-18 09:29:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_EXECUTOR_HPP
0012 #define BOOST_ASIO_EXECUTOR_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019
0020 #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
0021
0022 #include <new>
0023 #include <typeinfo>
0024 #include <boost/asio/detail/cstddef.hpp>
0025 #include <boost/asio/detail/executor_function.hpp>
0026 #include <boost/asio/detail/memory.hpp>
0027 #include <boost/asio/detail/throw_exception.hpp>
0028 #include <boost/asio/execution_context.hpp>
0029
0030 #include <boost/asio/detail/push_options.hpp>
0031
0032 namespace boost {
0033 namespace asio {
0034
0035
0036 class bad_executor
0037 : public std::exception
0038 {
0039 public:
0040
0041 BOOST_ASIO_DECL bad_executor() noexcept;
0042
0043
0044 BOOST_ASIO_DECL virtual const char* what() const
0045 noexcept;
0046 };
0047
0048
0049 class executor
0050 {
0051 public:
0052
0053 executor() noexcept
0054 : impl_(0)
0055 {
0056 }
0057
0058
0059 executor(nullptr_t) noexcept
0060 : impl_(0)
0061 {
0062 }
0063
0064
0065 executor(const executor& other) noexcept
0066 : impl_(other.clone())
0067 {
0068 }
0069
0070
0071 executor(executor&& other) noexcept
0072 : impl_(other.impl_)
0073 {
0074 other.impl_ = 0;
0075 }
0076
0077
0078 template <typename Executor>
0079 executor(Executor e);
0080
0081
0082
0083 executor(std::nothrow_t, const executor& other) noexcept
0084 : impl_(other.clone())
0085 {
0086 }
0087
0088
0089
0090 executor(std::nothrow_t, executor&& other) noexcept
0091 : impl_(other.impl_)
0092 {
0093 other.impl_ = 0;
0094 }
0095
0096
0097 template <typename Executor>
0098 executor(std::nothrow_t, Executor e) noexcept;
0099
0100
0101
0102 template <typename Executor, typename Allocator>
0103 executor(allocator_arg_t, const Allocator& a, Executor e);
0104
0105
0106 ~executor()
0107 {
0108 destroy();
0109 }
0110
0111
0112 executor& operator=(const executor& other) noexcept
0113 {
0114 destroy();
0115 impl_ = other.clone();
0116 return *this;
0117 }
0118
0119
0120 executor& operator=(executor&& other) noexcept
0121 {
0122 destroy();
0123 impl_ = other.impl_;
0124 other.impl_ = 0;
0125 return *this;
0126 }
0127
0128
0129 executor& operator=(nullptr_t) noexcept
0130 {
0131 destroy();
0132 impl_ = 0;
0133 return *this;
0134 }
0135
0136
0137
0138 template <typename Executor>
0139 executor& operator=(Executor&& e) noexcept
0140 {
0141 executor tmp(static_cast<Executor&&>(e));
0142 destroy();
0143 impl_ = tmp.impl_;
0144 tmp.impl_ = 0;
0145 return *this;
0146 }
0147
0148
0149 execution_context& context() const noexcept
0150 {
0151 return get_impl()->context();
0152 }
0153
0154
0155 void on_work_started() const noexcept
0156 {
0157 get_impl()->on_work_started();
0158 }
0159
0160
0161 void on_work_finished() const noexcept
0162 {
0163 get_impl()->on_work_finished();
0164 }
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179 template <typename Function, typename Allocator>
0180 void dispatch(Function&& f, const Allocator& a) const;
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 template <typename Function, typename Allocator>
0196 void post(Function&& f, const Allocator& a) const;
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 template <typename Function, typename Allocator>
0212 void defer(Function&& f, const Allocator& a) const;
0213
0214 struct unspecified_bool_type_t {};
0215 typedef void (*unspecified_bool_type)(unspecified_bool_type_t);
0216 static void unspecified_bool_true(unspecified_bool_type_t) {}
0217
0218
0219 operator unspecified_bool_type() const noexcept
0220 {
0221 return impl_ ? &executor::unspecified_bool_true : 0;
0222 }
0223
0224
0225
0226
0227
0228
0229 #if !defined(BOOST_ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)
0230 const std::type_info& target_type() const noexcept
0231 {
0232 return impl_ ? impl_->target_type() : typeid(void);
0233 }
0234 #else
0235 const void* target_type() const noexcept
0236 {
0237 return impl_ ? impl_->target_type() : 0;
0238 }
0239 #endif
0240
0241
0242
0243
0244
0245
0246 template <typename Executor>
0247 Executor* target() noexcept;
0248
0249
0250
0251
0252
0253
0254 template <typename Executor>
0255 const Executor* target() const noexcept;
0256
0257
0258 friend bool operator==(const executor& a,
0259 const executor& b) noexcept
0260 {
0261 if (a.impl_ == b.impl_)
0262 return true;
0263 if (!a.impl_ || !b.impl_)
0264 return false;
0265 return a.impl_->equals(b.impl_);
0266 }
0267
0268
0269 friend bool operator!=(const executor& a,
0270 const executor& b) noexcept
0271 {
0272 return !(a == b);
0273 }
0274
0275 private:
0276 #if !defined(GENERATING_DOCUMENTATION)
0277 typedef detail::executor_function function;
0278 template <typename, typename> class impl;
0279
0280 #if !defined(BOOST_ASIO_NO_TYPEID)
0281 typedef const std::type_info& type_id_result_type;
0282 #else
0283 typedef const void* type_id_result_type;
0284 #endif
0285
0286 template <typename T>
0287 static type_id_result_type type_id()
0288 {
0289 #if !defined(BOOST_ASIO_NO_TYPEID)
0290 return typeid(T);
0291 #else
0292 static int unique_id;
0293 return &unique_id;
0294 #endif
0295 }
0296
0297
0298 class impl_base
0299 {
0300 public:
0301 virtual impl_base* clone() const noexcept = 0;
0302 virtual void destroy() noexcept = 0;
0303 virtual execution_context& context() noexcept = 0;
0304 virtual void on_work_started() noexcept = 0;
0305 virtual void on_work_finished() noexcept = 0;
0306 virtual void dispatch(function&&) = 0;
0307 virtual void post(function&&) = 0;
0308 virtual void defer(function&&) = 0;
0309 virtual type_id_result_type target_type() const noexcept = 0;
0310 virtual void* target() noexcept = 0;
0311 virtual const void* target() const noexcept = 0;
0312 virtual bool equals(const impl_base* e) const noexcept = 0;
0313
0314 protected:
0315 impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {}
0316 virtual ~impl_base() {}
0317
0318 private:
0319 friend class executor;
0320 const bool fast_dispatch_;
0321 };
0322
0323
0324 impl_base* get_impl() const
0325 {
0326 if (!impl_)
0327 {
0328 bad_executor ex;
0329 boost::asio::detail::throw_exception(ex);
0330 }
0331 return impl_;
0332 }
0333
0334
0335 impl_base* clone() const noexcept
0336 {
0337 return impl_ ? impl_->clone() : 0;
0338 }
0339
0340
0341 void destroy() noexcept
0342 {
0343 if (impl_)
0344 impl_->destroy();
0345 }
0346
0347 impl_base* impl_;
0348 #endif
0349 };
0350
0351 }
0352 }
0353
0354 BOOST_ASIO_USES_ALLOCATOR(boost::asio::executor)
0355
0356 #include <boost/asio/detail/pop_options.hpp>
0357
0358 #include <boost/asio/impl/executor.hpp>
0359 #if defined(BOOST_ASIO_HEADER_ONLY)
0360 # include <boost/asio/impl/executor.ipp>
0361 #endif
0362
0363 #endif
0364
0365 #endif