File indexing completed on 2025-01-30 09:33:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_COMPOSE_HPP
0012 #define BOOST_ASIO_COMPOSE_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, typename Handler, typename Signature>
0033 class composed_op;
0034
0035 template <typename Impl, typename Work, typename Handler,
0036 typename R, typename... Args>
0037 class composed_op<Impl, Work, Handler, R(Args...)>
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 void complete(Args... args)
0096 {
0097 this->work_.reset();
0098 static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);
0099 }
0100
0101 void reset_cancellation_state()
0102 {
0103 base_from_cancellation_state<Handler>::reset_cancellation_state(handler_);
0104 }
0105
0106 template <typename Filter>
0107 void reset_cancellation_state(Filter&& filter)
0108 {
0109 base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,
0110 static_cast<Filter&&>(filter));
0111 }
0112
0113 template <typename InFilter, typename OutFilter>
0114 void reset_cancellation_state(InFilter&& in_filter,
0115 OutFilter&& out_filter)
0116 {
0117 base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,
0118 static_cast<InFilter&&>(in_filter),
0119 static_cast<OutFilter&&>(out_filter));
0120 }
0121
0122 cancellation_type_t cancelled() const noexcept
0123 {
0124 return base_from_cancellation_state<Handler>::cancelled();
0125 }
0126
0127
0128 Impl impl_;
0129 Work work_;
0130 Handler handler_;
0131 unsigned invocations_;
0132 };
0133
0134 template <typename Impl, typename Work, typename Handler, typename Signature>
0135 inline bool asio_handler_is_continuation(
0136 composed_op<Impl, Work, Handler, Signature>* this_handler)
0137 {
0138 return this_handler->invocations_ > 1 ? true
0139 : boost_asio_handler_cont_helpers::is_continuation(
0140 this_handler->handler_);
0141 }
0142
0143 template <typename Signature, typename Executors>
0144 class initiate_composed_op
0145 {
0146 public:
0147 typedef typename composed_io_executors<Executors>::head_type executor_type;
0148
0149 template <typename T>
0150 explicit initiate_composed_op(int, T&& executors)
0151 : executors_(static_cast<T&&>(executors))
0152 {
0153 }
0154
0155 executor_type get_executor() const noexcept
0156 {
0157 return executors_.head_;
0158 }
0159
0160 template <typename Handler, typename Impl>
0161 void operator()(Handler&& handler,
0162 Impl&& impl) const
0163 {
0164 composed_op<decay_t<Impl>, composed_work<Executors>,
0165 decay_t<Handler>, Signature>(
0166 static_cast<Impl&&>(impl),
0167 composed_work<Executors>(executors_),
0168 static_cast<Handler&&>(handler))();
0169 }
0170
0171 private:
0172 composed_io_executors<Executors> executors_;
0173 };
0174
0175 template <typename Signature, typename Executors>
0176 inline initiate_composed_op<Signature, Executors> make_initiate_composed_op(
0177 composed_io_executors<Executors>&& executors)
0178 {
0179 return initiate_composed_op<Signature, Executors>(0,
0180 static_cast<composed_io_executors<Executors>&&>(executors));
0181 }
0182
0183 }
0184
0185 #if !defined(GENERATING_DOCUMENTATION)
0186
0187 template <template <typename, typename> class Associator,
0188 typename Impl, typename Work, typename Handler,
0189 typename Signature, typename DefaultCandidate>
0190 struct associator<Associator,
0191 detail::composed_op<Impl, Work, Handler, Signature>,
0192 DefaultCandidate>
0193 : Associator<Handler, DefaultCandidate>
0194 {
0195 static typename Associator<Handler, DefaultCandidate>::type get(
0196 const detail::composed_op<Impl, Work, Handler, Signature>& h) noexcept
0197 {
0198 return Associator<Handler, DefaultCandidate>::get(h.handler_);
0199 }
0200
0201 static auto get(const detail::composed_op<Impl, Work, Handler, Signature>& h,
0202 const DefaultCandidate& c) noexcept
0203 -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))
0204 {
0205 return Associator<Handler, DefaultCandidate>::get(h.handler_, c);
0206 }
0207 };
0208
0209 #endif
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 template <typename CompletionToken, typename Signature,
0294 typename Implementation, typename... IoObjectsOrExecutors>
0295 auto async_compose(Implementation&& implementation,
0296 type_identity_t<CompletionToken>& token,
0297 IoObjectsOrExecutors&&... io_objects_or_executors)
0298 -> decltype(
0299 async_initiate<CompletionToken, Signature>(
0300 detail::make_initiate_composed_op<Signature>(
0301 detail::make_composed_io_executors(
0302 detail::get_composed_io_executor(
0303 static_cast<IoObjectsOrExecutors&&>(
0304 io_objects_or_executors))...)),
0305 token, static_cast<Implementation&&>(implementation)))
0306 {
0307 return async_initiate<CompletionToken, Signature>(
0308 detail::make_initiate_composed_op<Signature>(
0309 detail::make_composed_io_executors(
0310 detail::get_composed_io_executor(
0311 static_cast<IoObjectsOrExecutors&&>(
0312 io_objects_or_executors))...)),
0313 token, static_cast<Implementation&&>(implementation));
0314 }
0315
0316 }
0317 }
0318
0319 #include <boost/asio/detail/pop_options.hpp>
0320
0321 #endif