mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Simplify handler_ptr:
Replace aligned_union in handler_ptr with the built-in one to reduce the number of template instantiations and remove the reinterpret_casts that were required. Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
committed by
Vinnie Falco
parent
587929edf6
commit
34037d538e
@ -2,6 +2,7 @@ Version 196:
|
||||
|
||||
* Tidy up calls to placement new
|
||||
* Remove unused type_traits
|
||||
* Simplify handler_ptr
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include <boost/beast/core/detail/allocator.hpp>
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@ -50,10 +49,11 @@ namespace beast {
|
||||
template<class T, class Handler>
|
||||
class handler_ptr
|
||||
{
|
||||
using handler_storage_t = typename detail::aligned_union<1, Handler>::type;
|
||||
|
||||
T* t_ = nullptr;
|
||||
handler_storage_t h_;
|
||||
union
|
||||
{
|
||||
Handler h_;
|
||||
};
|
||||
|
||||
void clear();
|
||||
|
||||
@ -113,20 +113,21 @@ public:
|
||||
the owned object's constructor.
|
||||
*/
|
||||
template<class DeducedHandler, class... Args>
|
||||
explicit handler_ptr(DeducedHandler&& handler, Args&&... args);
|
||||
explicit
|
||||
handler_ptr(DeducedHandler&& handler, Args&&... args);
|
||||
|
||||
/// Return a reference to the handler
|
||||
handler_type const&
|
||||
handler() const
|
||||
{
|
||||
return *reinterpret_cast<Handler const*>(&h_);
|
||||
return h_;
|
||||
}
|
||||
|
||||
/// Return a reference to the handler
|
||||
handler_type&
|
||||
handler()
|
||||
{
|
||||
return *reinterpret_cast<Handler*>(&h_);
|
||||
return h_;
|
||||
}
|
||||
|
||||
/// Return `true` if `*this` owns an object
|
||||
@ -167,7 +168,7 @@ public:
|
||||
return t_;
|
||||
}
|
||||
|
||||
/** Return ownership of the handler
|
||||
/** Returns ownership of the handler
|
||||
|
||||
Before this function returns, the owned object is
|
||||
destroyed, satisfying the deallocation-before-invocation
|
||||
|
@ -41,7 +41,7 @@ handler_ptr<T, Handler>::
|
||||
if(t_)
|
||||
{
|
||||
clear();
|
||||
handler().~Handler();
|
||||
h_.~Handler();
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,8 +52,9 @@ handler_ptr(handler_ptr&& other)
|
||||
{
|
||||
if(other.t_)
|
||||
{
|
||||
new(&h_) Handler(std::move(other.handler()));
|
||||
other.handler().~Handler();
|
||||
::new(static_cast<void*>(std::addressof(h_)))
|
||||
Handler(std::move(other.h_));
|
||||
other.h_.~Handler();
|
||||
other.t_ = nullptr;
|
||||
}
|
||||
}
|
||||
@ -64,25 +65,27 @@ handler_ptr<T, Handler>::
|
||||
handler_ptr(DeducedHandler&& h, Args&&... args)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(! std::is_array<T>::value);
|
||||
typename beast::detail::allocator_traits<
|
||||
using A = typename beast::detail::allocator_traits<
|
||||
net::associated_allocator_t<
|
||||
Handler>>::template rebind_alloc<T> alloc{
|
||||
net::get_associated_allocator(h)};
|
||||
using A = decltype(alloc);
|
||||
Handler>>::template rebind_alloc<T>;
|
||||
A alloc{net::get_associated_allocator(h)};
|
||||
using traits =
|
||||
typename beast::detail::allocator_traits<A>;
|
||||
bool destroy = false;
|
||||
auto deleter = [&alloc, &destroy](T* p)
|
||||
{
|
||||
if(destroy)
|
||||
beast::detail::allocator_traits<A>::destroy(alloc, p);
|
||||
beast::detail::allocator_traits<A>::deallocate(alloc, p, 1);
|
||||
traits::destroy(alloc, p);
|
||||
traits::deallocate(alloc, p, 1);
|
||||
};
|
||||
std::unique_ptr<T, decltype(deleter)> t{
|
||||
beast::detail::allocator_traits<A>::allocate(alloc, 1), deleter};
|
||||
beast::detail::allocator_traits<A>::construct(alloc, t.get(),
|
||||
traits::allocate(alloc, 1), deleter};
|
||||
traits::construct(alloc, t.get(),
|
||||
static_cast<DeducedHandler const&>(h),
|
||||
std::forward<Args>(args)...);
|
||||
destroy = true;
|
||||
new(&h_) Handler(std::forward<DeducedHandler>(h));
|
||||
::new(static_cast<void*>(std::addressof(h_)))
|
||||
Handler(std::forward<DeducedHandler>(h));
|
||||
t_ = t.release();
|
||||
}
|
||||
|
||||
@ -100,8 +103,8 @@ release_handler() ->
|
||||
};
|
||||
std::unique_ptr<
|
||||
Handler, decltype(deleter)> destroyer{
|
||||
&handler(), deleter};
|
||||
return std::move(handler());
|
||||
std::addressof(h_), deleter};
|
||||
return std::move(h_);
|
||||
}
|
||||
|
||||
template<class T, class Handler>
|
||||
@ -119,8 +122,8 @@ invoke(Args&&... args)
|
||||
};
|
||||
std::unique_ptr<
|
||||
Handler, decltype(deleter)> destroyer{
|
||||
&handler(), deleter};
|
||||
handler()(std::forward<Args>(args)...);
|
||||
std::addressof(h_), deleter};
|
||||
h_(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
Reference in New Issue
Block a user