| // |
| // handler_alloc_helpers.hpp |
| // ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| // |
| // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff 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 BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP |
| #define BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
| # pragma once |
| #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
| |
| #include <boost/asio/detail/push_options.hpp> |
| |
| #include <boost/asio/detail/push_options.hpp> |
| #include <boost/detail/workaround.hpp> |
| #include <boost/asio/detail/pop_options.hpp> |
| |
| #include <boost/asio/handler_alloc_hook.hpp> |
| #include <boost/asio/detail/noncopyable.hpp> |
| |
| // Calls to asio_handler_allocate and asio_handler_deallocate must be made from |
| // a namespace that does not contain any overloads of these functions. The |
| // boost_asio_handler_alloc_helpers namespace is defined here for that purpose. |
| namespace boost_asio_handler_alloc_helpers { |
| |
| template <typename Handler> |
| inline void* allocate(std::size_t s, Handler* h) |
| { |
| #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
| return ::operator new(s); |
| #else |
| using namespace boost::asio; |
| return asio_handler_allocate(s, h); |
| #endif |
| } |
| |
| template <typename Handler> |
| inline void deallocate(void* p, std::size_t s, Handler* h) |
| { |
| #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
| ::operator delete(p); |
| #else |
| using namespace boost::asio; |
| asio_handler_deallocate(p, s, h); |
| #endif |
| } |
| |
| } // namespace boost_asio_handler_alloc_helpers |
| |
| namespace boost { |
| namespace asio { |
| namespace detail { |
| |
| // Traits for handler allocation. |
| template <typename Handler, typename Object> |
| struct handler_alloc_traits |
| { |
| typedef Handler handler_type; |
| typedef Object value_type; |
| typedef Object* pointer_type; |
| BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object)); |
| }; |
| |
| template <typename Alloc_Traits> |
| class handler_ptr; |
| |
| // Helper class to provide RAII on uninitialised handler memory. |
| template <typename Alloc_Traits> |
| class raw_handler_ptr |
| : private noncopyable |
| { |
| public: |
| typedef typename Alloc_Traits::handler_type handler_type; |
| typedef typename Alloc_Traits::value_type value_type; |
| typedef typename Alloc_Traits::pointer_type pointer_type; |
| BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); |
| |
| // Constructor allocates the memory. |
| raw_handler_ptr(handler_type& handler) |
| : handler_(handler), |
| pointer_(static_cast<pointer_type>( |
| boost_asio_handler_alloc_helpers::allocate(value_size, &handler_))) |
| { |
| } |
| |
| // Destructor automatically deallocates memory, unless it has been stolen by |
| // a handler_ptr object. |
| ~raw_handler_ptr() |
| { |
| if (pointer_) |
| boost_asio_handler_alloc_helpers::deallocate( |
| pointer_, value_size, &handler_); |
| } |
| |
| private: |
| friend class handler_ptr<Alloc_Traits>; |
| handler_type& handler_; |
| pointer_type pointer_; |
| }; |
| |
| // Helper class to provide RAII on uninitialised handler memory. |
| template <typename Alloc_Traits> |
| class handler_ptr |
| : private noncopyable |
| { |
| public: |
| typedef typename Alloc_Traits::handler_type handler_type; |
| typedef typename Alloc_Traits::value_type value_type; |
| typedef typename Alloc_Traits::pointer_type pointer_type; |
| BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size); |
| typedef raw_handler_ptr<Alloc_Traits> raw_ptr_type; |
| |
| // Take ownership of existing memory. |
| handler_ptr(handler_type& handler, pointer_type pointer) |
| : handler_(handler), |
| pointer_(pointer) |
| { |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| handler_ptr(raw_ptr_type& raw_ptr) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type(a1)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1, typename Arg2> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type(a1, a2)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1, typename Arg2, typename Arg3> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, |
| typename Arg5> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, |
| Arg5& a5) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, |
| typename Arg5, typename Arg6> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, |
| Arg5& a5, Arg6& a6) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, |
| typename Arg5, typename Arg6, typename Arg7> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, |
| Arg5& a5, Arg6& a6, Arg7& a7) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Construct object in raw memory and take ownership if construction succeeds. |
| template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, |
| typename Arg5, typename Arg6, typename Arg7, typename Arg8> |
| handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4, |
| Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8) |
| : handler_(raw_ptr.handler_), |
| pointer_(new (raw_ptr.pointer_) value_type( |
| a1, a2, a3, a4, a5, a6, a7, a8)) |
| { |
| raw_ptr.pointer_ = 0; |
| } |
| |
| // Destructor automatically deallocates memory, unless it has been released. |
| ~handler_ptr() |
| { |
| reset(); |
| } |
| |
| // Get the memory. |
| pointer_type get() const |
| { |
| return pointer_; |
| } |
| |
| // Release ownership of the memory. |
| pointer_type release() |
| { |
| pointer_type tmp = pointer_; |
| pointer_ = 0; |
| return tmp; |
| } |
| |
| // Explicitly destroy and deallocate the memory. |
| void reset() |
| { |
| if (pointer_) |
| { |
| pointer_->value_type::~value_type(); |
| boost_asio_handler_alloc_helpers::deallocate( |
| pointer_, value_size, &handler_); |
| pointer_ = 0; |
| } |
| } |
| |
| private: |
| handler_type& handler_; |
| pointer_type pointer_; |
| }; |
| |
| } // namespace detail |
| } // namespace asio |
| } // namespace boost |
| |
| #include <boost/asio/detail/pop_options.hpp> |
| |
| #endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP |