00001
00002
00003
00004
00005
00006
00007
00008
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
00028
00029
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 }
00055
00056 namespace asio {
00057 namespace detail {
00058
00059
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
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
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
00092
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
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
00119 handler_ptr(handler_type& handler, pointer_type pointer)
00120 : handler_(handler),
00121 pointer_(pointer)
00122 {
00123 }
00124
00125
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
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
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
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
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
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
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
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
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
00215 ~handler_ptr()
00216 {
00217 reset();
00218 }
00219
00220
00221 pointer_type get() const
00222 {
00223 return pointer_;
00224 }
00225
00226
00227 pointer_type release()
00228 {
00229 pointer_type tmp = pointer_;
00230 pointer_ = 0;
00231 return tmp;
00232 }
00233
00234
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 }
00252 }
00253
00254 #include "asio/detail/pop_options.hpp"
00255
00256 #endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP