File indexing completed on 2025-04-26 08:25:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_COMPOSED_HPP
0012 #define BOOST_ASIO_COMPOSED_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/associated_executor.hpp>
0020 #include <boost/asio/async_result.hpp>
0021 #include <boost/asio/detail/base_from_cancellation_state.hpp>
0022 #include <boost/asio/detail/composed_work.hpp>
0023 #include <boost/asio/detail/handler_cont_helpers.hpp>
0024 #include <boost/asio/detail/type_traits.hpp>
0025
0026 #include <boost/asio/detail/push_options.hpp>
0027
0028 namespace boost {
0029 namespace asio {
0030 namespace detail {
0031
0032 template <typename Impl, typename Work,
0033 typename Handler, typename... Signatures>
0034 class composed_op;
0035
0036 template <typename Impl, typename Work, typename Handler>
0037 class composed_op<Impl, Work, Handler>
0038 : public base_from_cancellation_state<Handler>
0039 {
0040 public:
0041 template <typename I, typename W, typename H>
0042 composed_op(I&& impl,
0043 W&& work,
0044 H&& handler)
0045 : base_from_cancellation_state<Handler>(
0046 handler, enable_terminal_cancellation()),
0047 impl_(static_cast<I&&>(impl)),
0048 work_(static_cast<W&&>(work)),
0049 handler_(static_cast<H&&>(handler)),
0050 invocations_(0)
0051 {
0052 }
0053
0054 composed_op(composed_op&& other)
0055 : base_from_cancellation_state<Handler>(
0056 static_cast<base_from_cancellation_state<Handler>&&>(other)),
0057 impl_(static_cast<Impl&&>(other.impl_)),
0058 work_(static_cast<Work&&>(other.work_)),
0059 handler_(static_cast<Handler&&>(other.handler_)),
0060 invocations_(other.invocations_)
0061 {
0062 }
0063
0064 typedef typename composed_work_guard<
0065 typename Work::head_type>::executor_type io_executor_type;
0066
0067 io_executor_type get_io_executor() const noexcept
0068 {
0069 return work_.head_.get_executor();
0070 }
0071
0072 typedef associated_executor_t<Handler, io_executor_type> executor_type;
0073
0074 executor_type get_executor() const noexcept
0075 {
0076 return (get_associated_executor)(handler_, work_.head_.get_executor());
0077 }
0078
0079 typedef associated_allocator_t<Handler, std::allocator<void>> allocator_type;
0080
0081 allocator_type get_allocator() const noexcept
0082 {
0083 return (get_associated_allocator)(handler_, std::allocator<void>());
0084 }
0085
0086 template <typename... T>
0087 void operator()(T&&... t)
0088 {
0089 if (invocations_ < ~0u)
0090 ++invocations_;
0091 this->get_cancellation_state().slot().clear();
0092 impl_(*this, static_cast<T&&>(t)...);
0093 }
0094
0095 template <typename... Args>
0096 auto complete(Args&&... args)
0097 -> decltype(declval<Handler>()(static_cast<Args&&>(args)...))
0098 {
0099 return static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);
0100 }
0101
0102 void reset_cancellation_state()
0103 {
0104 base_from_cancellation_state<Handler>::reset_cancellation_state(handler_);
0105 }
0106
0107 template <typename Filter>
0108 void reset_cancellation_state(Filter&& filter)
0109 {
0110 base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,
0111 static_cast<Filter&&>(filter));
0112 }
0113
0114 template <typename InFilter, typename OutFilter>
0115 void reset_cancellation_state(InFilter&& in_filter,
0116 OutFilter&& out_filter)
0117 {
0118 base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,
0119 static_cast<InFilter&&>(in_filter),
0120 static_cast<OutFilter&&>(out_filter));
0121 }
0122
0123 cancellation_type_t cancelled() const noexcept
0124 {
0125 return base_from_cancellation_state<Handler>::cancelled();
0126 }
0127
0128
0129 Impl impl_;
0130 Work work_;
0131 Handler handler_;
0132 unsigned invocations_;
0133 };
0134
0135 template <typename Impl, typename Work, typename Handler,
0136 typename R, typename... Args>
0137 class composed_op<Impl, Work, Handler, R(Args...)>
0138 : public composed_op<Impl, Work, Handler>
0139 {
0140 public:
0141 using composed_op<Impl, Work, Handler>::composed_op;
0142
0143 template <typename... T>
0144 void operator()(T&&... t)
0145 {
0146 if (this->invocations_ < ~0u)
0147 ++this->invocations_;
0148 this->get_cancellation_state().slot().clear();
0149 this->impl_(*this, static_cast<T&&>(t)...);
0150 }
0151
0152 void complete(Args... args)
0153 {
0154 this->work_.reset();
0155 static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);
0156 }
0157 };
0158
0159 template <typename Impl, typename Work, typename Handler,
0160 typename R, typename... Args, typename... Signatures>
0161 class composed_op<Impl, Work, Handler, R(Args...), Signatures...>
0162 : public composed_op<Impl, Work, Handler, Signatures...>
0163 {
0164 public:
0165 using composed_op<Impl, Work, Handler, Signatures...>::composed_op;
0166
0167 template <typename... T>
0168 void operator()(T&&... t)
0169 {
0170 if (this->invocations_ < ~0u)
0171 ++this->invocations_;
0172 this->get_cancellation_state().slot().clear();
0173 this->impl_(*this, static_cast<T&&>(t)...);
0174 }
0175
0176 using composed_op<Impl, Work, Handler, Signatures...>::complete;
0177
0178 void complete(Args... args)
0179 {
0180 this->work_.reset();
0181 static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);
0182 }
0183 };
0184
0185 template <typename Impl, typename Work, typename Handler, typename Signature>
0186 inline bool asio_handler_is_continuation(
0187 composed_op<Impl, Work, Handler, Signature>* this_handler)
0188 {
0189 return this_handler->invocations_ > 1 ? true
0190 : boost_asio_handler_cont_helpers::is_continuation(
0191 this_handler->handler_);
0192 }
0193
0194 template <typename Implementation, typename Executors, typename... Signatures>
0195 class initiate_composed
0196 {
0197 public:
0198 typedef typename composed_io_executors<Executors>::head_type executor_type;
0199
0200 template <typename I>
0201 initiate_composed(I&& impl, composed_io_executors<Executors>&& executors)
0202 : implementation_(std::forward<I>(impl)),
0203 executors_(std::move(executors))
0204 {
0205 }
0206
0207 executor_type get_executor() const noexcept
0208 {
0209 return executors_.head_;
0210 }
0211
0212 template <typename Handler, typename... Args>
0213 void operator()(Handler&& handler, Args&&... args) const &
0214 {
0215 composed_op<decay_t<Implementation>, composed_work<Executors>,
0216 decay_t<Handler>, Signatures...>(implementation_,
0217 composed_work<Executors>(executors_),
0218 static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);
0219 }
0220
0221 template <typename Handler, typename... Args>
0222 void operator()(Handler&& handler, Args&&... args) &&
0223 {
0224 composed_op<decay_t<Implementation>, composed_work<Executors>,
0225 decay_t<Handler>, Signatures...>(
0226 static_cast<Implementation&&>(implementation_),
0227 composed_work<Executors>(executors_),
0228 static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);
0229 }
0230
0231 private:
0232 Implementation implementation_;
0233 composed_io_executors<Executors> executors_;
0234 };
0235
0236 template <typename Implementation, typename... Signatures>
0237 class initiate_composed<Implementation, void(), Signatures...>
0238 {
0239 public:
0240 template <typename I>
0241 initiate_composed(I&& impl, composed_io_executors<void()>&&)
0242 : implementation_(std::forward<I>(impl))
0243 {
0244 }
0245
0246 template <typename Handler, typename... Args>
0247 void operator()(Handler&& handler, Args&&... args) const &
0248 {
0249 composed_op<decay_t<Implementation>, composed_work<void()>,
0250 decay_t<Handler>, Signatures...>(implementation_,
0251 composed_work<void()>(composed_io_executors<void()>()),
0252 static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);
0253 }
0254
0255 template <typename Handler, typename... Args>
0256 void operator()(Handler&& handler, Args&&... args) &&
0257 {
0258 composed_op<decay_t<Implementation>, composed_work<void()>,
0259 decay_t<Handler>, Signatures...>(
0260 static_cast<Implementation&&>(implementation_),
0261 composed_work<void()>(composed_io_executors<void()>()),
0262 static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);
0263 }
0264
0265 private:
0266 Implementation implementation_;
0267 };
0268
0269 template <typename... Signatures, typename Implementation, typename Executors>
0270 inline initiate_composed<Implementation, Executors, Signatures...>
0271 make_initiate_composed(Implementation&& implementation,
0272 composed_io_executors<Executors>&& executors)
0273 {
0274 return initiate_composed<decay_t<Implementation>, Executors, Signatures...>(
0275 static_cast<Implementation&&>(implementation),
0276 static_cast<composed_io_executors<Executors>&&>(executors));
0277 }
0278
0279 }
0280
0281 #if !defined(GENERATING_DOCUMENTATION)
0282
0283 template <template <typename, typename> class Associator,
0284 typename Impl, typename Work, typename Handler,
0285 typename Signature, typename DefaultCandidate>
0286 struct associator<Associator,
0287 detail::composed_op<Impl, Work, Handler, Signature>,
0288 DefaultCandidate>
0289 : Associator<Handler, DefaultCandidate>
0290 {
0291 static typename Associator<Handler, DefaultCandidate>::type get(
0292 const detail::composed_op<Impl, Work, Handler, Signature>& h) noexcept
0293 {
0294 return Associator<Handler, DefaultCandidate>::get(h.handler_);
0295 }
0296
0297 static auto get(const detail::composed_op<Impl, Work, Handler, Signature>& h,
0298 const DefaultCandidate& c) noexcept
0299 -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
0300 {
0301 return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
0302 }
0303 };
0304
0305 #endif
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390 template <BOOST_ASIO_COMPLETION_SIGNATURE... Signatures,
0391 typename Implementation, typename... IoObjectsOrExecutors>
0392 inline auto composed(Implementation&& implementation,
0393 IoObjectsOrExecutors&&... io_objects_or_executors)
0394 -> decltype(
0395 detail::make_initiate_composed<Signatures...>(
0396 static_cast<Implementation&&>(implementation),
0397 detail::make_composed_io_executors(
0398 detail::get_composed_io_executor(
0399 static_cast<IoObjectsOrExecutors&&>(
0400 io_objects_or_executors))...)))
0401 {
0402 return detail::make_initiate_composed<Signatures...>(
0403 static_cast<Implementation&&>(implementation),
0404 detail::make_composed_io_executors(
0405 detail::get_composed_io_executor(
0406 static_cast<IoObjectsOrExecutors&&>(
0407 io_objects_or_executors))...));
0408 }
0409
0410 }
0411 }
0412
0413 #include <boost/asio/detail/pop_options.hpp>
0414
0415 #endif