/usr/include/boost/beast/core/detail
Edit: /usr/include/boost/beast/core/detail/bind_handler.hpp (10959B)
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_DETAIL_BIND_HANDLER_HPP
#define BOOST_BEAST_DETAIL_BIND_HANDLER_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost {
namespace beast {
namespace detail {
//------------------------------------------------------------------------------
//
// bind_handler
//
//------------------------------------------------------------------------------
template
class bind_wrapper
{
using args_type = detail::tuple;
Handler h_;
args_type args_;
template
friend struct net::associated_executor;
template
friend struct net::associated_allocator;
template
static
typename std::enable_if<
std::is_placeholder::type>::value == 0 &&
boost::is_placeholder::type>::value == 0,
Arg&&>::type
extract(Arg&& arg, Vals&& vals)
{
boost::ignore_unused(vals);
return std::forward(arg);
}
template
static
typename std::enable_if<
std::is_placeholder::type>::value != 0,
tuple_element::type>::value - 1,
Vals>>::type&&
extract(Arg&&, Vals&& vals)
{
return detail::get::type>::value - 1>(
std::forward(vals));
}
template
static
typename std::enable_if<
boost::is_placeholder::type>::value != 0,
tuple_element::type>::value - 1,
Vals>>::type&&
extract(Arg&&, Vals&& vals)
{
return detail::get::type>::value - 1>(
std::forward(vals));
}
template
static
void
invoke(
Handler& h,
ArgsTuple& args,
tuple<>&&,
mp11::index_sequence)
{
boost::ignore_unused(args);
h(detail::get(std::move(args))...);
}
template<
class ArgsTuple,
class ValsTuple,
std::size_t... S>
static
void
invoke(
Handler& h,
ArgsTuple& args,
ValsTuple&& vals,
mp11::index_sequence)
{
boost::ignore_unused(args);
boost::ignore_unused(vals);
h(extract(detail::get(std::move(args)),
std::forward(vals))...);
}
public:
using result_type = void; // asio needs this
bind_wrapper(bind_wrapper&&) = default;
bind_wrapper(bind_wrapper const&) = default;
template<
class DeducedHandler,
class... Args_>
explicit
bind_wrapper(
DeducedHandler&& handler,
Args_&&... args)
: h_(std::forward(handler))
, args_(std::forward(args)...)
{
}
template
void
operator()(Values&&... values)
{
invoke(h_, args_,
tuple(
std::forward(values)...),
mp11::index_sequence_for());
}
//
template
friend
boost::asio::asio_handler_invoke_is_deprecated
asio_handler_invoke(
Function&& f, bind_wrapper* op)
{
using boost::asio::asio_handler_invoke;
return asio_handler_invoke(f, std::addressof(op->h_));
}
friend
bool asio_handler_is_continuation(
bind_wrapper* op)
{
using boost::asio::asio_handler_is_continuation;
return asio_handler_is_continuation(
std::addressof(op->h_));
}
friend
boost::asio::asio_handler_allocate_is_deprecated
asio_handler_allocate(
std::size_t size, bind_wrapper* op)
{
using boost::asio::asio_handler_allocate;
return asio_handler_allocate(
size, std::addressof(op->h_));
}
friend
boost::asio::asio_handler_deallocate_is_deprecated
asio_handler_deallocate(
void* p, std::size_t size, bind_wrapper* op)
{
using boost::asio::asio_handler_deallocate;
return asio_handler_deallocate(
p, size, std::addressof(op->h_));
}
};
template
class bind_back_wrapper;
template
class bind_front_wrapper;
//------------------------------------------------------------------------------
//
// bind_front
//
//------------------------------------------------------------------------------
template
class bind_front_wrapper
{
Handler h_;
detail::tuple args_;
template
friend struct net::associated_executor;
template
friend struct net::associated_allocator;
template
void
invoke(
std::false_type,
mp11::index_sequence,
Ts&&... ts)
{
h_( detail::get(std::move(args_))...,
std::forward(ts)...);
}
template
void
invoke(
std::true_type,
mp11::index_sequence,
Ts&&... ts)
{
std::mem_fn(h_)(
detail::get(std::move(args_))...,
std::forward(ts)...);
}
public:
using result_type = void; // asio needs this
bind_front_wrapper(bind_front_wrapper&&) = default;
bind_front_wrapper(bind_front_wrapper const&) = default;
template
bind_front_wrapper(
Handler_&& handler,
Args_&&... args)
: h_(std::forward(handler))
, args_(std::forward(args)...)
{
}
template
void operator()(Ts&&... ts)
{
invoke(
std::is_member_function_pointer{},
mp11::index_sequence_for{},
std::forward(ts)...);
}
//
template
friend
boost::asio::asio_handler_invoke_is_deprecated
asio_handler_invoke(
Function&& f, bind_front_wrapper* op)
{
using boost::asio::asio_handler_invoke;
return asio_handler_invoke(f, std::addressof(op->h_));
}
friend
bool asio_handler_is_continuation(
bind_front_wrapper* op)
{
using boost::asio::asio_handler_is_continuation;
return asio_handler_is_continuation(
std::addressof(op->h_));
}
friend
boost::asio::asio_handler_allocate_is_deprecated
asio_handler_allocate(
std::size_t size, bind_front_wrapper* op)
{
using boost::asio::asio_handler_allocate;
return asio_handler_allocate(
size, std::addressof(op->h_));
}
friend
boost::asio::asio_handler_deallocate_is_deprecated
asio_handler_deallocate(
void* p, std::size_t size, bind_front_wrapper* op)
{
using boost::asio::asio_handler_deallocate;
return asio_handler_deallocate(
p, size, std::addressof(op->h_));
}
};
} // detail
} // beast
} // boost
//------------------------------------------------------------------------------
namespace boost {
namespace asio {
template
struct associated_executor<
beast::detail::bind_wrapper, Executor>
{
using type = typename
associated_executor::type;
static
type
get(beast::detail::bind_wrapper const& op,
Executor const& ex = Executor{}) noexcept
{
return associated_executor<
Handler, Executor>::get(op.h_, ex);
}
};
template
struct associated_executor<
beast::detail::bind_front_wrapper, Executor>
{
using type = typename
associated_executor::type;
static
type
get(beast::detail::bind_front_wrapper const& op,
Executor const& ex = Executor{}) noexcept
{
return associated_executor<
Handler, Executor>::get(op.h_, ex);
}
};
//
template
struct associated_allocator<
beast::detail::bind_wrapper, Allocator>
{
using type = typename
associated_allocator::type;
static
type
get(beast::detail::bind_wrapper const& op,
Allocator const& alloc = Allocator{}) noexcept
{
return associated_allocator<
Handler, Allocator>::get(op.h_, alloc);
}
};
template
struct associated_allocator<
beast::detail::bind_front_wrapper, Allocator>
{
using type = typename
associated_allocator::type;
static
type
get(beast::detail::bind_front_wrapper const& op,
Allocator const& alloc = Allocator{}) noexcept
{
return associated_allocator<
Handler, Allocator>::get(op.h_, alloc);
}
};
} // asio
} // boost
//------------------------------------------------------------------------------
namespace std {
// VFALCO Using std::bind on a completion handler will
// cause undefined behavior later, because the executor
// associated with the handler is not propagated to the
// wrapper returned by std::bind; these overloads are
// deleted to prevent mistakes. If this creates a problem
// please contact me.
template
void
bind(boost::beast::detail::bind_wrapper<
Handler, Args...>, ...) = delete;
template
void
bind(boost::beast::detail::bind_front_wrapper<
Handler, Args...>, ...) = delete;
} // std
//------------------------------------------------------------------------------
#endif