2 // Copyright (c) 2016-2017 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_HANDLER_PTR_HPP
11 #define BOOST_BEAST_HANDLER_PTR_HPP
13 #include <boost/beast/core/detail/allocator.hpp>
14 #include <boost/beast/core/detail/config.hpp>
15 #include <boost/beast/core/detail/type_traits.hpp>
16 #include <type_traits>
22 /** A smart pointer container with associated completion handler.
24 This is a smart pointer that retains unique ownership of an
25 object through a pointer. Memory is managed using the allocator
26 associated with a completion handler stored in the object. The
27 managed object is destroyed and its memory deallocated when one
28 of the following occurs:
30 @li The function @ref invoke is called.
32 @li The function @ref release_handler is called.
34 @li The container is destroyed.
36 Objects of this type are used in the implementation of composed
37 operations with states that are expensive or impossible to move.
38 This container manages that non-trivial state on behalf of the
42 @e Distinct @e objects: Safe.@n
43 @e Shared @e objects: Unsafe.
45 @tparam T The type of the owned object. Must be noexcept destructible.
47 @tparam Handler The type of the completion handler.
49 template<class T, class Handler>
52 using handler_storage_t = typename detail::aligned_union<1, Handler>::type;
60 static_assert(std::is_nothrow_destructible<T>::value,
61 "T must be nothrow destructible");
63 /// The type of element stored
64 using element_type = T;
66 /// The type of handler stored
67 using handler_type = Handler;
69 /// Default constructor (deleted).
70 handler_ptr() = delete;
72 /// Copy assignment (deleted).
73 handler_ptr& operator=(handler_ptr const&) = delete;
75 /// Move assignment (deleted).
76 handler_ptr& operator=(handler_ptr &&) = delete;
80 If `*this` owns an object the object is destroyed and
81 the memory deallocated using the allocator associated
88 When this call returns, the moved-from container
89 will have no owned object.
91 handler_ptr(handler_ptr&& other);
93 /// Copy constructor (deleted).
94 handler_ptr(handler_ptr const& other) = delete;
98 This creates a new container with an owned object of
99 type `T`. The allocator associated with the handler will
100 be used to allocate memory for the owned object. The
101 constructor for the owned object will be called with the
102 following equivalent signature:
105 T::T(Handler const&, Args&&...)
108 @par Exception Safety
111 @param handler The handler to associate with the owned
112 object. The argument will be moved if it is an xvalue.
114 @param args Optional arguments forwarded to
115 the owned object's constructor.
117 template<class DeducedHandler, class... Args>
118 explicit handler_ptr(DeducedHandler&& handler, Args&&... args);
120 /// Returns a const reference to the handler
124 return *reinterpret_cast<Handler const*>(&h_);
127 /// Returns a reference to the handler
131 return *reinterpret_cast<Handler*>(&h_);
134 /** Returns a pointer to the owned object.
142 /// Return a reference to the owned object.
149 /// Return a pointer to the owned object.
156 /** Release ownership of the handler
158 Requires: `*this` owns an object
160 Before this function returns, the owned object is
161 destroyed, satisfying the deallocation-before-invocation
164 @return The released handler.
169 /** Invoke the handler in the owned object.
171 This function invokes the handler in the owned object
172 with a forwarded argument list. Before the invocation,
173 the owned object is destroyed, satisfying the
174 deallocation-before-invocation Asio guarantee.
176 @note Care must be taken when the arguments are themselves
177 stored in the owned object. Such arguments must first be
178 moved to the stack or elsewhere, and then passed, or else
179 undefined behavior will result.
181 template<class... Args>
183 invoke(Args&&... args);
189 #include <boost/beast/core/impl/handler_ptr.ipp>