diff options
Diffstat (limited to 'boost/beast/core/impl/async_base.hpp')
-rw-r--r-- | boost/beast/core/impl/async_base.hpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/boost/beast/core/impl/async_base.hpp b/boost/beast/core/impl/async_base.hpp new file mode 100644 index 0000000000..ec17b1cc1e --- /dev/null +++ b/boost/beast/core/impl/async_base.hpp @@ -0,0 +1,156 @@ +// +// 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_CORE_IMPL_ASYNC_BASE_HPP +#define BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP + +#include <boost/core/exchange.hpp> + +namespace boost { +namespace beast { + +namespace detail { + +template<class State, class Allocator> +struct allocate_stable_state final + : stable_base + , boost::empty_value<Allocator> +{ + State value; + + template<class... Args> + explicit + allocate_stable_state( + Allocator const& alloc, + Args&&... args) + : boost::empty_value<Allocator>( + boost::empty_init_t{}, alloc) + , value{std::forward<Args>(args)...} + { + } + + void destroy() override + { + using A = typename allocator_traits< + Allocator>::template rebind_alloc< + allocate_stable_state>; + + A a(this->get()); + detail::allocator_traits<A>::destroy(a, this); + detail::allocator_traits<A>::deallocate(a, this, 1); + } +}; + +} // detail + +template< + class Handler, + class Executor1, + class Allocator, + class Function> +void asio_handler_invoke( + Function&& f, + async_base<Handler, Executor1, Allocator>* p) +{ + using net::asio_handler_invoke; + asio_handler_invoke(f, + p->get_legacy_handler_pointer()); +} + +template< + class Handler, + class Executor1, + class Allocator> +void* +asio_handler_allocate( + std::size_t size, + async_base<Handler, Executor1, Allocator>* p) +{ + using net::asio_handler_allocate; + return asio_handler_allocate(size, + p->get_legacy_handler_pointer()); +} + +template< + class Handler, + class Executor1, + class Allocator> +void +asio_handler_deallocate( + void* mem, std::size_t size, + async_base<Handler, Executor1, Allocator>* p) +{ + using net::asio_handler_deallocate; + asio_handler_deallocate(mem, size, + p->get_legacy_handler_pointer()); +} + +template< + class Handler, + class Executor1, + class Allocator> +bool +asio_handler_is_continuation( + async_base<Handler, Executor1, Allocator>* p) +{ + using net::asio_handler_is_continuation; + return asio_handler_is_continuation( + p->get_legacy_handler_pointer()); +} + +template< + class State, + class Handler, + class Executor1, + class Allocator, + class... Args> +State& +allocate_stable( + stable_async_base< + Handler, Executor1, Allocator>& base, + Args&&... args) +{ + using allocator_type = typename stable_async_base< + Handler, Executor1, Allocator>::allocator_type; + + using A = typename detail::allocator_traits< + allocator_type>::template rebind_alloc< + detail::allocate_stable_state< + State, allocator_type>>; + + struct deleter + { + allocator_type alloc; + detail::allocate_stable_state< + State, allocator_type>* ptr; + + ~deleter() + { + if(ptr) + { + A a(alloc); + detail::allocator_traits<A>::deallocate(a, ptr, 1); + } + } + }; + + A a(base.get_allocator()); + deleter d{base.get_allocator(), nullptr}; + d.ptr = detail::allocator_traits<A>::allocate(a, 1); + detail::allocator_traits<A>::construct(a, d.ptr, + d.alloc, std::forward<Args>(args)...); + d.ptr->next_ = base.list_; + base.list_ = d.ptr; + return boost::exchange(d.ptr, nullptr)->value; +} + +} // beast +} // boost + +#endif |