handler_alloc_helpers.hpp
Go to the documentation of this file.
00001 //
00002 // handler_alloc_helpers.hpp
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~
00004 //
00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00006 //
00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 
00011 #ifndef ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
00012 #define ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
00013 
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017 
00018 #include "asio/detail/push_options.hpp"
00019 
00020 #include "asio/detail/push_options.hpp"
00021 #include <boost/detail/workaround.hpp>
00022 #include "asio/detail/pop_options.hpp"
00023 
00024 #include "asio/handler_alloc_hook.hpp"
00025 #include "asio/detail/noncopyable.hpp"
00026 
00027 // Calls to asio_handler_allocate and asio_handler_deallocate must be made from
00028 // a namespace that does not contain any overloads of these functions. The
00029 // asio_handler_alloc_helpers namespace is defined here for that purpose.
00030 namespace asio_handler_alloc_helpers {
00031 
00032 template <typename Handler>
00033 inline void* allocate(std::size_t s, Handler* h)
00034 {
00035 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
00036   return ::operator new(s);
00037 #else
00038   using namespace asio;
00039   return asio_handler_allocate(s, h);
00040 #endif
00041 }
00042 
00043 template <typename Handler>
00044 inline void deallocate(void* p, std::size_t s, Handler* h)
00045 {
00046 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
00047   ::operator delete(p);
00048 #else
00049   using namespace asio;
00050   asio_handler_deallocate(p, s, h);
00051 #endif
00052 }
00053 
00054 } // namespace asio_handler_alloc_helpers
00055 
00056 namespace asio {
00057 namespace detail {
00058 
00059 // Traits for handler allocation.
00060 template <typename Handler, typename Object>
00061 struct handler_alloc_traits
00062 {
00063   typedef Handler handler_type;
00064   typedef Object value_type;
00065   typedef Object* pointer_type;
00066   BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object));
00067 };
00068 
00069 template <typename Alloc_Traits>
00070 class handler_ptr;
00071 
00072 // Helper class to provide RAII on uninitialised handler memory.
00073 template <typename Alloc_Traits>
00074 class raw_handler_ptr
00075   : private noncopyable
00076 {
00077 public:
00078   typedef typename Alloc_Traits::handler_type handler_type;
00079   typedef typename Alloc_Traits::value_type value_type;
00080   typedef typename Alloc_Traits::pointer_type pointer_type;
00081   BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
00082 
00083   // Constructor allocates the memory.
00084   raw_handler_ptr(handler_type& handler)
00085     : handler_(handler),
00086       pointer_(static_cast<pointer_type>(
00087             asio_handler_alloc_helpers::allocate(value_size, &handler_)))
00088   {
00089   }
00090 
00091   // Destructor automatically deallocates memory, unless it has been stolen by
00092   // a handler_ptr object.
00093   ~raw_handler_ptr()
00094   {
00095     if (pointer_)
00096       asio_handler_alloc_helpers::deallocate(
00097           pointer_, value_size, &handler_);
00098   }
00099 
00100 private:
00101   friend class handler_ptr<Alloc_Traits>;
00102   handler_type& handler_;
00103   pointer_type pointer_;
00104 };
00105 
00106 // Helper class to provide RAII on uninitialised handler memory.
00107 template <typename Alloc_Traits>
00108 class handler_ptr
00109   : private noncopyable
00110 {
00111 public:
00112   typedef typename Alloc_Traits::handler_type handler_type;
00113   typedef typename Alloc_Traits::value_type value_type;
00114   typedef typename Alloc_Traits::pointer_type pointer_type;
00115   BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
00116   typedef raw_handler_ptr<Alloc_Traits> raw_ptr_type;
00117 
00118   // Take ownership of existing memory.
00119   handler_ptr(handler_type& handler, pointer_type pointer)
00120     : handler_(handler),
00121       pointer_(pointer)
00122   {
00123   }
00124 
00125   // Construct object in raw memory and take ownership if construction succeeds.
00126   handler_ptr(raw_ptr_type& raw_ptr)
00127     : handler_(raw_ptr.handler_),
00128       pointer_(new (raw_ptr.pointer_) value_type)
00129   {
00130     raw_ptr.pointer_ = 0;
00131   }
00132 
00133   // Construct object in raw memory and take ownership if construction succeeds.
00134   template <typename Arg1>
00135   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1)
00136     : handler_(raw_ptr.handler_),
00137       pointer_(new (raw_ptr.pointer_) value_type(a1))
00138   {
00139     raw_ptr.pointer_ = 0;
00140   }
00141 
00142   // Construct object in raw memory and take ownership if construction succeeds.
00143   template <typename Arg1, typename Arg2>
00144   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2)
00145     : handler_(raw_ptr.handler_),
00146       pointer_(new (raw_ptr.pointer_) value_type(a1, a2))
00147   {
00148     raw_ptr.pointer_ = 0;
00149   }
00150 
00151   // Construct object in raw memory and take ownership if construction succeeds.
00152   template <typename Arg1, typename Arg2, typename Arg3>
00153   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3)
00154     : handler_(raw_ptr.handler_),
00155       pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3))
00156   {
00157     raw_ptr.pointer_ = 0;
00158   }
00159 
00160   // Construct object in raw memory and take ownership if construction succeeds.
00161   template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
00162   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4)
00163     : handler_(raw_ptr.handler_),
00164       pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4))
00165   {
00166     raw_ptr.pointer_ = 0;
00167   }
00168 
00169   // Construct object in raw memory and take ownership if construction succeeds.
00170   template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
00171       typename Arg5>
00172   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
00173       Arg5& a5)
00174     : handler_(raw_ptr.handler_),
00175       pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5))
00176   {
00177     raw_ptr.pointer_ = 0;
00178   }
00179 
00180   // Construct object in raw memory and take ownership if construction succeeds.
00181   template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
00182       typename Arg5, typename Arg6>
00183   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
00184       Arg5& a5, Arg6& a6)
00185     : handler_(raw_ptr.handler_),
00186       pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6))
00187   {
00188     raw_ptr.pointer_ = 0;
00189   }
00190 
00191   // Construct object in raw memory and take ownership if construction succeeds.
00192   template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
00193       typename Arg5, typename Arg6, typename Arg7>
00194   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
00195       Arg5& a5, Arg6& a6, Arg7& a7)
00196     : handler_(raw_ptr.handler_),
00197       pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7))
00198   {
00199     raw_ptr.pointer_ = 0;
00200   }
00201 
00202   // Construct object in raw memory and take ownership if construction succeeds.
00203   template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
00204       typename Arg5, typename Arg6, typename Arg7, typename Arg8>
00205   handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
00206       Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8)
00207     : handler_(raw_ptr.handler_),
00208       pointer_(new (raw_ptr.pointer_) value_type(
00209             a1, a2, a3, a4, a5, a6, a7, a8))
00210   {
00211     raw_ptr.pointer_ = 0;
00212   }
00213 
00214   // Destructor automatically deallocates memory, unless it has been released.
00215   ~handler_ptr()
00216   {
00217     reset();
00218   }
00219 
00220   // Get the memory.
00221   pointer_type get() const
00222   {
00223     return pointer_;
00224   }
00225 
00226   // Release ownership of the memory.
00227   pointer_type release()
00228   {
00229     pointer_type tmp = pointer_;
00230     pointer_ = 0;
00231     return tmp;
00232   }
00233 
00234   // Explicitly destroy and deallocate the memory.
00235   void reset()
00236   {
00237     if (pointer_)
00238     {
00239       pointer_->value_type::~value_type();
00240       asio_handler_alloc_helpers::deallocate(
00241           pointer_, value_size, &handler_);
00242       pointer_ = 0;
00243     }
00244   }
00245 
00246 private:
00247   handler_type& handler_;
00248   pointer_type pointer_;
00249 };
00250 
00251 } // namespace detail
00252 } // namespace asio
00253 
00254 #include "asio/detail/pop_options.hpp"
00255 
00256 #endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39