// // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BEAST_IMPL_HANDLER_PTR_HPP #define BEAST_IMPL_HANDLER_PTR_HPP #include #include #include #include namespace beast { template template inline handler_ptr::P:: P(DeducedHandler&& h, Args&&... args) : n(1) , handler(std::forward(h)) { t = reinterpret_cast( beast_asio_helpers:: allocate(sizeof(T), handler)); try { t = new(t) T{handler, std::forward(args)...}; } catch(...) { beast_asio_helpers:: deallocate(t, sizeof(T), handler); throw; } } template handler_ptr:: ~handler_ptr() { if(! p_) return; if(--p_->n) return; if(p_->t) { p_->t->~T(); beast_asio_helpers:: deallocate(p_->t, sizeof(T), p_->handler); } delete p_; } template handler_ptr:: handler_ptr(handler_ptr&& other) : p_(other.p_) { other.p_ = nullptr; } template handler_ptr:: handler_ptr(handler_ptr const& other) : p_(other.p_) { if(p_) ++p_->n; } template template handler_ptr:: handler_ptr(Handler&& handler, Args&&... args) : p_(new P{std::move(handler), std::forward(args)...}) { static_assert(! std::is_array::value, "T must not be an array type"); } template template handler_ptr:: handler_ptr(Handler const& handler, Args&&... args) : p_(new P{handler, std::forward(args)...}) { static_assert(! std::is_array::value, "T must not be an array type"); } template auto handler_ptr:: release_handler() -> handler_type { BOOST_ASSERT(p_); BOOST_ASSERT(p_->t); p_->t->~T(); beast_asio_helpers:: deallocate(p_->t, sizeof(T), p_->handler); p_->t = nullptr; return std::move(p_->handler); } template template void handler_ptr:: invoke(Args&&... args) { BOOST_ASSERT(p_); BOOST_ASSERT(p_->t); p_->t->~T(); beast_asio_helpers:: deallocate(p_->t, sizeof(T), p_->handler); p_->t = nullptr; p_->handler(std::forward(args)...); } } // beast #endif