File indexing completed on 2025-07-05 08:27:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BEAST_DETAIL_BIND_HANDLER_HPP
0011 #define BOOST_BEAST_DETAIL_BIND_HANDLER_HPP
0012
0013 #include <boost/beast/core/error.hpp>
0014 #include <boost/beast/core/detail/tuple.hpp>
0015 #include <boost/asio/associator.hpp>
0016 #include <boost/asio/handler_continuation_hook.hpp>
0017 #include <boost/core/ignore_unused.hpp>
0018 #include <boost/mp11/integer_sequence.hpp>
0019 #include <boost/bind/std_placeholders.hpp>
0020 #include <boost/is_placeholder.hpp>
0021 #include <functional>
0022 #include <type_traits>
0023 #include <utility>
0024
0025 namespace boost {
0026 namespace beast {
0027 namespace detail {
0028
0029
0030
0031
0032
0033
0034
0035 template<class Handler, class... Args>
0036 class bind_wrapper
0037 {
0038 using args_type = detail::tuple<Args...>;
0039
0040 Handler h_;
0041 args_type args_;
0042
0043 template <template <typename, typename> class,
0044 typename, typename, typename>
0045 friend struct net::associator;
0046
0047 template<class Arg, class Vals>
0048 static
0049 typename std::enable_if<
0050 std::is_placeholder<typename
0051 std::decay<Arg>::type>::value == 0 &&
0052 boost::is_placeholder<typename
0053 std::decay<Arg>::type>::value == 0,
0054 Arg&&>::type
0055 extract(Arg&& arg, Vals&& vals)
0056 {
0057 boost::ignore_unused(vals);
0058 return std::forward<Arg>(arg);
0059 }
0060
0061 template<class Arg, class Vals>
0062 static
0063 typename std::enable_if<
0064 std::is_placeholder<typename
0065 std::decay<Arg>::type>::value != 0,
0066 tuple_element<std::is_placeholder<
0067 typename std::decay<Arg>::type>::value - 1,
0068 Vals>>::type&&
0069 extract(Arg&&, Vals&& vals)
0070 {
0071 return detail::get<std::is_placeholder<
0072 typename std::decay<Arg>::type>::value - 1>(
0073 std::forward<Vals>(vals));
0074 }
0075
0076 template<class Arg, class Vals>
0077 static
0078 typename std::enable_if<
0079 boost::is_placeholder<typename
0080 std::decay<Arg>::type>::value != 0 &&
0081 std::is_placeholder<typename
0082 std::decay<Arg>::type>::value == 0,
0083 tuple_element<boost::is_placeholder<
0084 typename std::decay<Arg>::type>::value - 1,
0085 Vals>>::type&&
0086 extract(Arg&&, Vals&& vals)
0087 {
0088 return detail::get<boost::is_placeholder<
0089 typename std::decay<Arg>::type>::value - 1>(
0090 std::forward<Vals>(vals));
0091 }
0092
0093 template<class ArgsTuple, std::size_t... S>
0094 static
0095 void
0096 invoke(
0097 Handler& h,
0098 ArgsTuple& args,
0099 tuple<>&&,
0100 mp11::index_sequence<S...>)
0101 {
0102 boost::ignore_unused(args);
0103 h(detail::get<S>(std::move(args))...);
0104 }
0105
0106 template<
0107 class ArgsTuple,
0108 class ValsTuple,
0109 std::size_t... S>
0110 static
0111 void
0112 invoke(
0113 Handler& h,
0114 ArgsTuple& args,
0115 ValsTuple&& vals,
0116 mp11::index_sequence<S...>)
0117 {
0118 boost::ignore_unused(args);
0119 boost::ignore_unused(vals);
0120 h(extract(detail::get<S>(std::move(args)),
0121 std::forward<ValsTuple>(vals))...);
0122 }
0123
0124 public:
0125 using result_type = void;
0126
0127 bind_wrapper(bind_wrapper&&) = default;
0128 bind_wrapper(bind_wrapper const&) = default;
0129
0130 template<
0131 class DeducedHandler,
0132 class... Args_>
0133 explicit
0134 bind_wrapper(
0135 DeducedHandler&& handler,
0136 Args_&&... args)
0137 : h_(std::forward<DeducedHandler>(handler))
0138 , args_(std::forward<Args_>(args)...)
0139 {
0140 }
0141
0142 template<class... Values>
0143 void
0144 operator()(Values&&... values)
0145 {
0146 invoke(h_, args_,
0147 tuple<Values&&...>(
0148 std::forward<Values>(values)...),
0149 mp11::index_sequence_for<Args...>());
0150 }
0151
0152
0153
0154 friend
0155 bool asio_handler_is_continuation(
0156 bind_wrapper* op)
0157 {
0158 using boost::asio::asio_handler_is_continuation;
0159 return asio_handler_is_continuation(
0160 std::addressof(op->h_));
0161 }
0162 };
0163
0164 template<class Handler, class... Args>
0165 class bind_back_wrapper;
0166
0167 template<class Handler, class... Args>
0168 class bind_front_wrapper;
0169
0170
0171
0172
0173
0174
0175
0176 template<class Handler, class... Args>
0177 class bind_front_wrapper
0178 {
0179 Handler h_;
0180 detail::tuple<Args...> args_;
0181
0182 template <template <typename, typename> class,
0183 typename, typename, typename>
0184 friend struct net::associator;
0185
0186 template<std::size_t... I, class... Ts>
0187 void
0188 invoke(
0189 std::false_type,
0190 mp11::index_sequence<I...>,
0191 Ts&&... ts)
0192 {
0193 h_( detail::get<I>(std::move(args_))...,
0194 std::forward<Ts>(ts)...);
0195 }
0196
0197 template<std::size_t... I, class... Ts>
0198 void
0199 invoke(
0200 std::true_type,
0201 mp11::index_sequence<I...>,
0202 Ts&&... ts)
0203 {
0204 std::mem_fn(h_)(
0205 detail::get<I>(std::move(args_))...,
0206 std::forward<Ts>(ts)...);
0207 }
0208
0209 public:
0210 using result_type = void;
0211
0212 bind_front_wrapper(bind_front_wrapper&&) = default;
0213 bind_front_wrapper(bind_front_wrapper const&) = default;
0214
0215 template<class Handler_, class... Args_>
0216 bind_front_wrapper(
0217 Handler_&& handler,
0218 Args_&&... args)
0219 : h_(std::forward<Handler_>(handler))
0220 , args_(std::forward<Args_>(args)...)
0221 {
0222 }
0223
0224 template<class... Ts>
0225 void operator()(Ts&&... ts)
0226 {
0227 invoke(
0228 std::is_member_function_pointer<Handler>{},
0229 mp11::index_sequence_for<Args...>{},
0230 std::forward<Ts>(ts)...);
0231 }
0232
0233
0234
0235 friend
0236 bool asio_handler_is_continuation(
0237 bind_front_wrapper* op)
0238 {
0239 using boost::asio::asio_handler_is_continuation;
0240 return asio_handler_is_continuation(
0241 std::addressof(op->h_));
0242 }
0243 };
0244
0245 }
0246 }
0247 }
0248
0249
0250
0251 namespace boost {
0252 namespace asio {
0253
0254 template <template <typename, typename> class Associator,
0255 typename Handler, typename... Args, typename DefaultCandidate>
0256 struct associator<Associator,
0257 beast::detail::bind_wrapper<Handler, Args...>, DefaultCandidate>
0258 : Associator<Handler, DefaultCandidate>
0259 {
0260 static typename Associator<Handler, DefaultCandidate>::type get(
0261 const beast::detail::bind_wrapper<Handler, Args...>& h) noexcept
0262 {
0263 return Associator<Handler, DefaultCandidate>::get(h.h_);
0264 }
0265
0266 static auto get(const beast::detail::bind_wrapper<Handler, Args...>& h,
0267 const DefaultCandidate& c) noexcept
0268 -> decltype(Associator<Handler, DefaultCandidate>::get(h.h_, c))
0269 {
0270 return Associator<Handler, DefaultCandidate>::get(h.h_, c);
0271 }
0272 };
0273
0274 template <template <typename, typename> class Associator,
0275 typename Handler, typename... Args, typename DefaultCandidate>
0276 struct associator<Associator,
0277 beast::detail::bind_front_wrapper<Handler, Args...>, DefaultCandidate>
0278 : Associator<Handler, DefaultCandidate>
0279 {
0280 static typename Associator<Handler, DefaultCandidate>::type get(
0281 const beast::detail::bind_front_wrapper<Handler, Args...>& h) noexcept
0282 {
0283 return Associator<Handler, DefaultCandidate>::get(h.h_);
0284 }
0285
0286 static auto get(const beast::detail::bind_front_wrapper<Handler, Args...>& h,
0287 const DefaultCandidate& c) noexcept
0288 -> decltype(Associator<Handler, DefaultCandidate>::get(h.h_, c))
0289 {
0290 return Associator<Handler, DefaultCandidate>::get(h.h_, c);
0291 }
0292 };
0293
0294 }
0295 }
0296
0297
0298
0299 namespace std {
0300
0301
0302
0303
0304
0305
0306
0307
0308 template<class Handler, class... Args>
0309 void
0310 bind(boost::beast::detail::bind_wrapper<
0311 Handler, Args...>, ...) = delete;
0312
0313 template<class Handler, class... Args>
0314 void
0315 bind(boost::beast::detail::bind_front_wrapper<
0316 Handler, Args...>, ...) = delete;
0317
0318 }
0319
0320
0321
0322 #endif