handler_alloc_helpers.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //
  2. // handler_alloc_helpers.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
  11. #define BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/push_options.hpp>
  16. #include <boost/asio/detail/push_options.hpp>
  17. #include <boost/detail/workaround.hpp>
  18. #include <boost/asio/detail/pop_options.hpp>
  19. #include <boost/asio/handler_alloc_hook.hpp>
  20. #include <boost/asio/detail/noncopyable.hpp>
  21. // Calls to asio_handler_allocate and asio_handler_deallocate must be made from
  22. // a namespace that does not contain any overloads of these functions. The
  23. // boost_asio_handler_alloc_helpers namespace is defined here for that purpose.
  24. namespace boost_asio_handler_alloc_helpers {
  25. template <typename Handler>
  26. inline void* allocate(std::size_t s, Handler* h)
  27. {
  28. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  29. return ::operator new(s);
  30. #else
  31. using namespace boost::asio;
  32. return asio_handler_allocate(s, h);
  33. #endif
  34. }
  35. template <typename Handler>
  36. inline void deallocate(void* p, std::size_t s, Handler* h)
  37. {
  38. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  39. ::operator delete(p);
  40. #else
  41. using namespace boost::asio;
  42. asio_handler_deallocate(p, s, h);
  43. #endif
  44. }
  45. } // namespace boost_asio_handler_alloc_helpers
  46. namespace boost {
  47. namespace asio {
  48. namespace detail {
  49. // Traits for handler allocation.
  50. template <typename Handler, typename Object>
  51. struct handler_alloc_traits
  52. {
  53. typedef Handler handler_type;
  54. typedef Object value_type;
  55. typedef Object* pointer_type;
  56. BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object));
  57. };
  58. template <typename Alloc_Traits>
  59. class handler_ptr;
  60. // Helper class to provide RAII on uninitialised handler memory.
  61. template <typename Alloc_Traits>
  62. class raw_handler_ptr
  63. : private noncopyable
  64. {
  65. public:
  66. typedef typename Alloc_Traits::handler_type handler_type;
  67. typedef typename Alloc_Traits::value_type value_type;
  68. typedef typename Alloc_Traits::pointer_type pointer_type;
  69. BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
  70. // Constructor allocates the memory.
  71. raw_handler_ptr(handler_type& handler)
  72. : handler_(handler),
  73. pointer_(static_cast<pointer_type>(
  74. boost_asio_handler_alloc_helpers::allocate(value_size, &handler_)))
  75. {
  76. }
  77. // Destructor automatically deallocates memory, unless it has been stolen by
  78. // a handler_ptr object.
  79. ~raw_handler_ptr()
  80. {
  81. if (pointer_)
  82. boost_asio_handler_alloc_helpers::deallocate(
  83. pointer_, value_size, &handler_);
  84. }
  85. private:
  86. friend class handler_ptr<Alloc_Traits>;
  87. handler_type& handler_;
  88. pointer_type pointer_;
  89. };
  90. // Helper class to provide RAII on uninitialised handler memory.
  91. template <typename Alloc_Traits>
  92. class handler_ptr
  93. : private noncopyable
  94. {
  95. public:
  96. typedef typename Alloc_Traits::handler_type handler_type;
  97. typedef typename Alloc_Traits::value_type value_type;
  98. typedef typename Alloc_Traits::pointer_type pointer_type;
  99. BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
  100. typedef raw_handler_ptr<Alloc_Traits> raw_ptr_type;
  101. // Take ownership of existing memory.
  102. handler_ptr(handler_type& handler, pointer_type pointer)
  103. : handler_(handler),
  104. pointer_(pointer)
  105. {
  106. }
  107. // Construct object in raw memory and take ownership if construction succeeds.
  108. handler_ptr(raw_ptr_type& raw_ptr)
  109. : handler_(raw_ptr.handler_),
  110. pointer_(new (raw_ptr.pointer_) value_type)
  111. {
  112. raw_ptr.pointer_ = 0;
  113. }
  114. // Construct object in raw memory and take ownership if construction succeeds.
  115. template <typename Arg1>
  116. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1)
  117. : handler_(raw_ptr.handler_),
  118. pointer_(new (raw_ptr.pointer_) value_type(a1))
  119. {
  120. raw_ptr.pointer_ = 0;
  121. }
  122. // Construct object in raw memory and take ownership if construction succeeds.
  123. template <typename Arg1, typename Arg2>
  124. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2)
  125. : handler_(raw_ptr.handler_),
  126. pointer_(new (raw_ptr.pointer_) value_type(a1, a2))
  127. {
  128. raw_ptr.pointer_ = 0;
  129. }
  130. // Construct object in raw memory and take ownership if construction succeeds.
  131. template <typename Arg1, typename Arg2, typename Arg3>
  132. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3)
  133. : handler_(raw_ptr.handler_),
  134. pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3))
  135. {
  136. raw_ptr.pointer_ = 0;
  137. }
  138. // Construct object in raw memory and take ownership if construction succeeds.
  139. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
  140. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4)
  141. : handler_(raw_ptr.handler_),
  142. pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4))
  143. {
  144. raw_ptr.pointer_ = 0;
  145. }
  146. // Construct object in raw memory and take ownership if construction succeeds.
  147. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  148. typename Arg5>
  149. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
  150. Arg5& a5)
  151. : handler_(raw_ptr.handler_),
  152. pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5))
  153. {
  154. raw_ptr.pointer_ = 0;
  155. }
  156. // Construct object in raw memory and take ownership if construction succeeds.
  157. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  158. typename Arg5, typename Arg6>
  159. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
  160. Arg5& a5, Arg6& a6)
  161. : handler_(raw_ptr.handler_),
  162. pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6))
  163. {
  164. raw_ptr.pointer_ = 0;
  165. }
  166. // Construct object in raw memory and take ownership if construction succeeds.
  167. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  168. typename Arg5, typename Arg6, typename Arg7>
  169. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
  170. Arg5& a5, Arg6& a6, Arg7& a7)
  171. : handler_(raw_ptr.handler_),
  172. pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7))
  173. {
  174. raw_ptr.pointer_ = 0;
  175. }
  176. // Construct object in raw memory and take ownership if construction succeeds.
  177. template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
  178. typename Arg5, typename Arg6, typename Arg7, typename Arg8>
  179. handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
  180. Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8)
  181. : handler_(raw_ptr.handler_),
  182. pointer_(new (raw_ptr.pointer_) value_type(
  183. a1, a2, a3, a4, a5, a6, a7, a8))
  184. {
  185. raw_ptr.pointer_ = 0;
  186. }
  187. // Destructor automatically deallocates memory, unless it has been released.
  188. ~handler_ptr()
  189. {
  190. reset();
  191. }
  192. // Get the memory.
  193. pointer_type get() const
  194. {
  195. return pointer_;
  196. }
  197. // Release ownership of the memory.
  198. pointer_type release()
  199. {
  200. pointer_type tmp = pointer_;
  201. pointer_ = 0;
  202. return tmp;
  203. }
  204. // Explicitly destroy and deallocate the memory.
  205. void reset()
  206. {
  207. if (pointer_)
  208. {
  209. pointer_->value_type::~value_type();
  210. boost_asio_handler_alloc_helpers::deallocate(
  211. pointer_, value_size, &handler_);
  212. pointer_ = 0;
  213. }
  214. }
  215. private:
  216. handler_type& handler_;
  217. pointer_type pointer_;
  218. };
  219. } // namespace detail
  220. } // namespace asio
  221. } // namespace boost
  222. #include <boost/asio/detail/pop_options.hpp>
  223. #endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP