1//
2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
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)
6//
7// Official repository: https://github.com/boostorg/beast
8//
9
10#ifndef BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
11#define BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
12
13#include <boost/core/exchange.hpp>
14
15namespace boost {
16namespace beast {
17
18namespace detail {
19
20template<class State, class Allocator>
21struct allocate_stable_state final
22 : stable_base
23 , boost::empty_value<Allocator>
24{
25 State value;
26
27 template<class... Args>
28 explicit
29 allocate_stable_state(
30 Allocator const& alloc,
31 Args&&... args)
32 : boost::empty_value<Allocator>(
33 boost::empty_init_t{}, alloc)
34 , value{std::forward<Args>(args)...}
35 {
36 }
37
38 void destroy() override
39 {
40 using A = typename allocator_traits<
41 Allocator>::template rebind_alloc<
42 allocate_stable_state>;
43
44 A a(this->get());
45 auto* p = this;
46 p->~allocate_stable_state();
47 a.deallocate(p, 1);
48 }
49};
50
51} // detail
52
53
54template<
55 class Handler,
56 class Executor1,
57 class Allocator>
58bool
59asio_handler_is_continuation(
60 async_base<Handler, Executor1, Allocator>* p)
61{
62 using boost::asio::asio_handler_is_continuation;
63 return asio_handler_is_continuation(
64 p->get_legacy_handler_pointer());
65}
66
67template<
68 class State,
69 class Handler,
70 class Executor1,
71 class Allocator,
72 class... Args>
73State&
74allocate_stable(
75 stable_async_base<
76 Handler, Executor1, Allocator>& base,
77 Args&&... args)
78{
79 using allocator_type = typename stable_async_base<
80 Handler, Executor1, Allocator>::allocator_type;
81 using state = detail::allocate_stable_state<
82 State, allocator_type>;
83 using A = typename detail::allocator_traits<
84 allocator_type>::template rebind_alloc<state>;
85
86 struct deleter
87 {
88 allocator_type alloc;
89 state* ptr;
90
91 ~deleter()
92 {
93 if(ptr)
94 {
95 A a(alloc);
96 a.deallocate(ptr, 1);
97 }
98 }
99 };
100
101 A a(base.get_allocator());
102 deleter d{base.get_allocator(), a.allocate(1)};
103 ::new(static_cast<void*>(d.ptr))
104 state(d.alloc, std::forward<Args>(args)...);
105 d.ptr->next_ = base.list_;
106 base.list_ = d.ptr;
107 return boost::exchange(d.ptr, nullptr)->value;
108}
109
110} // beast
111} // boost
112
113#endif
114

source code of boost/libs/beast/include/boost/beast/core/impl/async_base.hpp