2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
11 #define BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
13 #include <boost/core/exchange.hpp>
20 template<class State, class Allocator>
21 struct allocate_stable_state final
23 , boost::empty_value<Allocator>
27 template<class... Args>
29 allocate_stable_state(
30 Allocator const& alloc,
32 : boost::empty_value<Allocator>(
33 boost::empty_init_t{}, alloc)
34 , value{std::forward<Args>(args)...}
38 void destroy() override
40 using A = typename allocator_traits<
41 Allocator>::template rebind_alloc<
42 allocate_stable_state>;
46 p->~allocate_stable_state();
58 boost::asio::asio_handler_invoke_is_deprecated
61 async_base<Handler, Executor1, Allocator>* p)
63 using boost::asio::asio_handler_invoke;
64 return asio_handler_invoke(f,
65 p->get_legacy_handler_pointer());
72 boost::asio::asio_handler_allocate_is_deprecated
73 asio_handler_allocate(
75 async_base<Handler, Executor1, Allocator>* p)
77 using boost::asio::asio_handler_allocate;
78 return asio_handler_allocate(size,
79 p->get_legacy_handler_pointer());
86 boost::asio::asio_handler_deallocate_is_deprecated
87 asio_handler_deallocate(
88 void* mem, std::size_t size,
89 async_base<Handler, Executor1, Allocator>* p)
91 using boost::asio::asio_handler_deallocate;
92 return asio_handler_deallocate(mem, size,
93 p->get_legacy_handler_pointer());
101 asio_handler_is_continuation(
102 async_base<Handler, Executor1, Allocator>* p)
104 using boost::asio::asio_handler_is_continuation;
105 return asio_handler_is_continuation(
106 p->get_legacy_handler_pointer());
118 Handler, Executor1, Allocator>& base,
121 using allocator_type = typename stable_async_base<
122 Handler, Executor1, Allocator>::allocator_type;
123 using state = detail::allocate_stable_state<
124 State, allocator_type>;
125 using A = typename detail::allocator_traits<
126 allocator_type>::template rebind_alloc<state>;
130 allocator_type alloc;
138 a.deallocate(ptr, 1);
143 A a(base.get_allocator());
144 deleter d{base.get_allocator(), a.allocate(1)};
145 ::new(static_cast<void*>(d.ptr))
146 state(d.alloc, std::forward<Args>(args)...);
147 d.ptr->next_ = base.list_;
149 return boost::exchange(d.ptr, nullptr)->value;