Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:27:54

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
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 // bind_handler
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; // asio needs this
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 // bind_front
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; // asio needs this
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 } // detail
0246 } // beast
0247 } // boost
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 } // asio
0295 } // boost
0296 
0297 //------------------------------------------------------------------------------
0298 
0299 namespace std {
0300 
0301 // VFALCO Using std::bind on a completion handler will
0302 // cause undefined behavior later, because the executor
0303 // associated with the handler is not propagated to the
0304 // wrapper returned by std::bind; these overloads are
0305 // deleted to prevent mistakes. If this creates a problem
0306 // please contact me.
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 } // std
0319 
0320 //------------------------------------------------------------------------------
0321 
0322 #endif