$search
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