]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/core/impl/handler_ptr.ipp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / core / impl / handler_ptr.ipp
1 //
2 // Copyright (c) 2016-2017 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_IMPL_HANDLER_PTR_HPP
11 #define BOOST_BEAST_IMPL_HANDLER_PTR_HPP
12
13 #include <boost/asio/associated_allocator.hpp>
14 #include <boost/assert.hpp>
15 #include <memory>
16
17 namespace boost {
18 namespace beast {
19
20 template<class T, class Handler>
21 template<class DeducedHandler, class... Args>
22 inline
23 handler_ptr<T, Handler>::P::
24 P(DeducedHandler&& h, Args&&... args)
25 : n(1)
26 , handler(std::forward<DeducedHandler>(h))
27 {
28 typename std::allocator_traits<
29 boost::asio::associated_allocator_t<Handler>>::
30 template rebind_alloc<T> alloc{
31 boost::asio::get_associated_allocator(handler)};
32 t = std::allocator_traits<decltype(alloc)>::allocate(alloc, 1);
33 try
34 {
35 t = new(t) T{handler,
36 std::forward<Args>(args)...};
37 }
38 catch(...)
39 {
40 std::allocator_traits<
41 decltype(alloc)>::deallocate(alloc, t, 1);
42 throw;
43 }
44 }
45
46 template<class T, class Handler>
47 handler_ptr<T, Handler>::
48 ~handler_ptr()
49 {
50 if(! p_)
51 return;
52 if(--p_->n)
53 return;
54 if(p_->t)
55 {
56 p_->t->~T();
57 typename std::allocator_traits<
58 boost::asio::associated_allocator_t<Handler>>::
59 template rebind_alloc<T> alloc{
60 boost::asio::get_associated_allocator(
61 p_->handler)};
62 std::allocator_traits<
63 decltype(alloc)>::deallocate(alloc, p_->t, 1);
64 }
65 delete p_;
66 }
67
68 template<class T, class Handler>
69 handler_ptr<T, Handler>::
70 handler_ptr(handler_ptr&& other)
71 : p_(other.p_)
72 {
73 other.p_ = nullptr;
74 }
75
76 template<class T, class Handler>
77 handler_ptr<T, Handler>::
78 handler_ptr(handler_ptr const& other)
79 : p_(other.p_)
80 {
81 if(p_)
82 ++p_->n;
83 }
84
85 template<class T, class Handler>
86 template<class... Args>
87 handler_ptr<T, Handler>::
88 handler_ptr(Handler&& handler, Args&&... args)
89 : p_(new P{std::move(handler),
90 std::forward<Args>(args)...})
91 {
92 BOOST_STATIC_ASSERT(! std::is_array<T>::value);
93 }
94
95 template<class T, class Handler>
96 template<class... Args>
97 handler_ptr<T, Handler>::
98 handler_ptr(Handler const& handler, Args&&... args)
99 : p_(new P{handler, std::forward<Args>(args)...})
100 {
101 BOOST_STATIC_ASSERT(! std::is_array<T>::value);
102 }
103
104 template<class T, class Handler>
105 auto
106 handler_ptr<T, Handler>::
107 release_handler() ->
108 handler_type
109 {
110 BOOST_ASSERT(p_);
111 BOOST_ASSERT(p_->t);
112 p_->t->~T();
113 typename std::allocator_traits<
114 boost::asio::associated_allocator_t<Handler>>::
115 template rebind_alloc<T> alloc{
116 boost::asio::get_associated_allocator(
117 p_->handler)};
118 std::allocator_traits<
119 decltype(alloc)>::deallocate(alloc, p_->t, 1);
120 p_->t = nullptr;
121 return std::move(p_->handler);
122 }
123
124 template<class T, class Handler>
125 template<class... Args>
126 void
127 handler_ptr<T, Handler>::
128 invoke(Args&&... args)
129 {
130 BOOST_ASSERT(p_);
131 BOOST_ASSERT(p_->t);
132 p_->t->~T();
133 typename std::allocator_traits<
134 boost::asio::associated_allocator_t<Handler>>::
135 template rebind_alloc<T> alloc{
136 boost::asio::get_associated_allocator(
137 p_->handler)};
138 std::allocator_traits<
139 decltype(alloc)>::deallocate(alloc, p_->t, 1);
140 p_->t = nullptr;
141 p_->handler(std::forward<Args>(args)...);
142 }
143
144 } // beast
145 } // boost
146
147 #endif