Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:24

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/associated_allocator.hpp>
0016 #include <boost/asio/associated_cancellation_slot.hpp>
0017 #include <boost/asio/associated_executor.hpp>
0018 #include <boost/asio/handler_continuation_hook.hpp>
0019 #include <boost/core/ignore_unused.hpp>
0020 #include <boost/mp11/integer_sequence.hpp>
0021 #include <boost/bind/std_placeholders.hpp>
0022 #include <boost/is_placeholder.hpp>
0023 #include <functional>
0024 #include <type_traits>
0025 #include <utility>
0026 
0027 namespace boost {
0028 namespace beast {
0029 namespace detail {
0030 
0031 //------------------------------------------------------------------------------
0032 //
0033 // bind_handler
0034 //
0035 //------------------------------------------------------------------------------
0036 
0037 template<class Handler, class... Args>
0038 class bind_wrapper
0039 {
0040     using args_type = detail::tuple<Args...>;
0041 
0042     Handler h_;
0043     args_type args_;
0044 
0045     template<class T, class Executor>
0046     friend struct net::associated_executor;
0047 
0048     template<class T, class Allocator>
0049     friend struct net::associated_allocator;
0050 
0051     template<class T, class CancellationSlot>
0052     friend struct net::associated_cancellation_slot;
0053 
0054     template<class Arg, class Vals>
0055     static
0056     typename std::enable_if<
0057         std::is_placeholder<typename
0058             std::decay<Arg>::type>::value == 0 &&
0059         boost::is_placeholder<typename
0060             std::decay<Arg>::type>::value == 0,
0061         Arg&&>::type
0062     extract(Arg&& arg, Vals&& vals)
0063     {
0064         boost::ignore_unused(vals);
0065         return std::forward<Arg>(arg);
0066     }
0067 
0068     template<class Arg, class Vals>
0069     static
0070     typename std::enable_if<
0071         std::is_placeholder<typename
0072             std::decay<Arg>::type>::value != 0,
0073         tuple_element<std::is_placeholder<
0074             typename std::decay<Arg>::type>::value - 1,
0075         Vals>>::type&&
0076     extract(Arg&&, Vals&& vals)
0077     {
0078         return detail::get<std::is_placeholder<
0079             typename std::decay<Arg>::type>::value - 1>(
0080                 std::forward<Vals>(vals));
0081     }
0082 
0083     template<class Arg, class Vals>
0084     static
0085     typename std::enable_if<
0086         boost::is_placeholder<typename
0087             std::decay<Arg>::type>::value != 0 &&
0088         std::is_placeholder<typename
0089             std::decay<Arg>::type>::value == 0,
0090         tuple_element<boost::is_placeholder<
0091             typename std::decay<Arg>::type>::value - 1,
0092         Vals>>::type&&
0093     extract(Arg&&, Vals&& vals)
0094     {
0095         return detail::get<boost::is_placeholder<
0096             typename std::decay<Arg>::type>::value - 1>(
0097                 std::forward<Vals>(vals));
0098     }
0099 
0100     template<class ArgsTuple, std::size_t... S>
0101     static
0102     void
0103     invoke(
0104         Handler& h,
0105         ArgsTuple& args,
0106         tuple<>&&,
0107         mp11::index_sequence<S...>)
0108     {
0109         boost::ignore_unused(args);
0110         h(detail::get<S>(std::move(args))...);
0111     }
0112 
0113     template<
0114         class ArgsTuple,
0115         class ValsTuple,
0116         std::size_t... S>
0117     static
0118     void
0119     invoke(
0120         Handler& h,
0121         ArgsTuple& args,
0122         ValsTuple&& vals,
0123         mp11::index_sequence<S...>)
0124     {
0125         boost::ignore_unused(args);
0126         boost::ignore_unused(vals);
0127         h(extract(detail::get<S>(std::move(args)),
0128             std::forward<ValsTuple>(vals))...);
0129     }
0130 
0131 public:
0132     using result_type = void; // asio needs this
0133 
0134     bind_wrapper(bind_wrapper&&) = default;
0135     bind_wrapper(bind_wrapper const&) = default;
0136 
0137     template<
0138         class DeducedHandler,
0139         class... Args_>
0140     explicit
0141     bind_wrapper(
0142         DeducedHandler&& handler,
0143         Args_&&... args)
0144         : h_(std::forward<DeducedHandler>(handler))
0145         , args_(std::forward<Args_>(args)...)
0146     {
0147     }
0148 
0149     template<class... Values>
0150     void
0151     operator()(Values&&... values)
0152     {
0153         invoke(h_, args_,
0154             tuple<Values&&...>(
0155                 std::forward<Values>(values)...),
0156             mp11::index_sequence_for<Args...>());
0157     }
0158 
0159     //
0160 
0161     friend
0162     bool asio_handler_is_continuation(
0163         bind_wrapper* op)
0164     {
0165         using boost::asio::asio_handler_is_continuation;
0166         return asio_handler_is_continuation(
0167                 std::addressof(op->h_));
0168     }
0169 };
0170 
0171 template<class Handler, class... Args>
0172 class bind_back_wrapper;
0173 
0174 template<class Handler, class... Args>
0175 class bind_front_wrapper;
0176 
0177 //------------------------------------------------------------------------------
0178 //
0179 // bind_front
0180 //
0181 //------------------------------------------------------------------------------
0182 
0183 template<class Handler, class... Args>
0184 class bind_front_wrapper
0185 {
0186     Handler h_;
0187     detail::tuple<Args...> args_;
0188 
0189     template<class T, class Executor>
0190     friend struct net::associated_executor;
0191 
0192     template<class T, class Allocator>
0193     friend struct net::associated_allocator;
0194 
0195     template<class T, class CancellationSlot>
0196     friend struct net::associated_cancellation_slot;
0197 
0198 
0199     template<std::size_t... I, class... Ts>
0200     void
0201     invoke(
0202         std::false_type,
0203         mp11::index_sequence<I...>,
0204         Ts&&... ts)
0205     {
0206         h_( detail::get<I>(std::move(args_))...,
0207             std::forward<Ts>(ts)...);
0208     }
0209 
0210     template<std::size_t... I, class... Ts>
0211     void
0212     invoke(
0213         std::true_type,
0214         mp11::index_sequence<I...>,
0215         Ts&&... ts)
0216     {
0217         std::mem_fn(h_)(
0218             detail::get<I>(std::move(args_))...,
0219             std::forward<Ts>(ts)...);
0220     }
0221 
0222 public:
0223     using result_type = void; // asio needs this
0224 
0225     bind_front_wrapper(bind_front_wrapper&&) = default;
0226     bind_front_wrapper(bind_front_wrapper const&) = default;
0227 
0228     template<class Handler_, class... Args_>
0229     bind_front_wrapper(
0230         Handler_&& handler,
0231         Args_&&... args)
0232         : h_(std::forward<Handler_>(handler))
0233         , args_(std::forward<Args_>(args)...)
0234     {
0235     }
0236 
0237     template<class... Ts>
0238     void operator()(Ts&&... ts)
0239     {
0240         invoke(
0241             std::is_member_function_pointer<Handler>{},
0242             mp11::index_sequence_for<Args...>{},
0243             std::forward<Ts>(ts)...);
0244     }
0245 
0246     //
0247 
0248     friend
0249     bool asio_handler_is_continuation(
0250         bind_front_wrapper* op)
0251     {
0252         using boost::asio::asio_handler_is_continuation;
0253         return asio_handler_is_continuation(
0254             std::addressof(op->h_));
0255     }
0256 };
0257 
0258 } // detail
0259 } // beast
0260 } // boost
0261 
0262 //------------------------------------------------------------------------------
0263 
0264 namespace boost {
0265 namespace asio {
0266 
0267 template<class Handler, class... Args, class Executor>
0268 struct associated_executor<
0269     beast::detail::bind_wrapper<Handler, Args...>, Executor>
0270 {
0271     using type = typename
0272         associated_executor<Handler, Executor>::type;
0273 
0274     static
0275     type
0276     get(beast::detail::bind_wrapper<Handler, Args...> const& op,
0277         Executor const& ex = Executor{}) noexcept
0278     {
0279         return associated_executor<
0280             Handler, Executor>::get(op.h_, ex);
0281     }
0282 };
0283 
0284 template<class Handler, class... Args, class Executor>
0285 struct associated_executor<
0286     beast::detail::bind_front_wrapper<Handler, Args...>, Executor>
0287 {
0288     using type = typename
0289         associated_executor<Handler, Executor>::type;
0290 
0291     static
0292     type
0293     get(beast::detail::bind_front_wrapper<Handler, Args...> const& op,
0294         Executor const& ex = Executor{}) noexcept
0295     {
0296         return associated_executor<
0297             Handler, Executor>::get(op.h_, ex);
0298     }
0299 };
0300 
0301 //
0302 
0303 template<class Handler, class... Args, class Allocator>
0304 struct associated_allocator<
0305     beast::detail::bind_wrapper<Handler, Args...>, Allocator>
0306 {
0307     using type = typename
0308         associated_allocator<Handler, Allocator>::type;
0309 
0310     static
0311     type
0312     get(beast::detail::bind_wrapper<Handler, Args...> const& op,
0313         Allocator const& alloc = Allocator{}) noexcept
0314     {
0315         return associated_allocator<
0316             Handler, Allocator>::get(op.h_, alloc);
0317     }
0318 };
0319 
0320 template<class Handler, class... Args, class Allocator>
0321 struct associated_allocator<
0322     beast::detail::bind_front_wrapper<Handler, Args...>, Allocator>
0323 {
0324     using type = typename
0325         associated_allocator<Handler, Allocator>::type;
0326 
0327     static
0328     type
0329     get(beast::detail::bind_front_wrapper<Handler, Args...> const& op,
0330         Allocator const& alloc = Allocator{}) noexcept
0331     {
0332         return associated_allocator<
0333             Handler, Allocator>::get(op.h_, alloc);
0334     }
0335 };
0336 
0337 template<class Handler, class... Args, class CancellationSlot>
0338 struct associated_cancellation_slot<
0339     beast::detail::bind_wrapper<Handler, Args...>, CancellationSlot>
0340 {
0341     using type = typename
0342         associated_cancellation_slot<Handler>::type;
0343 
0344     static
0345     type
0346     get(beast::detail::bind_wrapper<Handler, Args...> const& op,
0347         CancellationSlot const& slot = CancellationSlot{}) noexcept
0348     {
0349         return associated_cancellation_slot<
0350             Handler, CancellationSlot>::get(op.h_, slot);
0351     }
0352 };
0353 
0354 template<class Handler, class... Args, class CancellationSlot>
0355 struct associated_cancellation_slot<
0356     beast::detail::bind_front_wrapper<Handler, Args...>, CancellationSlot>
0357 {
0358     using type = typename
0359         associated_cancellation_slot<Handler>::type;
0360 
0361     static
0362     type
0363     get(beast::detail::bind_front_wrapper<Handler, Args...> const& op,
0364         CancellationSlot const& slot = CancellationSlot{}) noexcept
0365     {
0366         return associated_cancellation_slot<
0367             Handler, CancellationSlot>::get(op.h_, slot);
0368     }
0369 };
0370 
0371 
0372 
0373 } // asio
0374 } // boost
0375 
0376 //------------------------------------------------------------------------------
0377 
0378 namespace std {
0379 
0380 // VFALCO Using std::bind on a completion handler will
0381 // cause undefined behavior later, because the executor
0382 // associated with the handler is not propagated to the
0383 // wrapper returned by std::bind; these overloads are
0384 // deleted to prevent mistakes. If this creates a problem
0385 // please contact me.
0386 
0387 template<class Handler, class... Args>
0388 void
0389 bind(boost::beast::detail::bind_wrapper<
0390     Handler, Args...>, ...) = delete;
0391 
0392 template<class Handler, class... Args>
0393 void
0394 bind(boost::beast::detail::bind_front_wrapper<
0395     Handler, Args...>, ...) = delete;
0396 
0397 } // std
0398 
0399 //------------------------------------------------------------------------------
0400 
0401 #endif