Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
5.8KB

  1. //
  2. // detail/handler_alloc_helpers.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 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 ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
  11. #define 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 "asio/detail/config.hpp"
  16. #include "asio/detail/memory.hpp"
  17. #include "asio/detail/noncopyable.hpp"
  18. #include "asio/detail/recycling_allocator.hpp"
  19. #include "asio/associated_allocator.hpp"
  20. #include "asio/handler_alloc_hook.hpp"
  21. #include "asio/detail/push_options.hpp"
  22. // Calls to asio_handler_allocate and asio_handler_deallocate must be made from
  23. // a namespace that does not contain any overloads of these functions. The
  24. // asio_handler_alloc_helpers namespace is defined here for that purpose.
  25. namespace asio_handler_alloc_helpers {
  26. template <typename Handler>
  27. inline void* allocate(std::size_t s, Handler& h)
  28. {
  29. #if !defined(ASIO_HAS_HANDLER_HOOKS)
  30. return ::operator new(s);
  31. #else
  32. using asio::asio_handler_allocate;
  33. return asio_handler_allocate(s, asio::detail::addressof(h));
  34. #endif
  35. }
  36. template <typename Handler>
  37. inline void deallocate(void* p, std::size_t s, Handler& h)
  38. {
  39. #if !defined(ASIO_HAS_HANDLER_HOOKS)
  40. ::operator delete(p);
  41. #else
  42. using asio::asio_handler_deallocate;
  43. asio_handler_deallocate(p, s, asio::detail::addressof(h));
  44. #endif
  45. }
  46. } // namespace asio_handler_alloc_helpers
  47. namespace asio {
  48. namespace detail {
  49. template <typename Handler, typename T>
  50. class hook_allocator
  51. {
  52. public:
  53. typedef T value_type;
  54. template <typename U>
  55. struct rebind
  56. {
  57. typedef hook_allocator<Handler, U> other;
  58. };
  59. explicit hook_allocator(Handler& h)
  60. : handler_(h)
  61. {
  62. }
  63. template <typename U>
  64. hook_allocator(const hook_allocator<Handler, U>& a)
  65. : handler_(a.handler_)
  66. {
  67. }
  68. T* allocate(std::size_t n)
  69. {
  70. return static_cast<T*>(
  71. asio_handler_alloc_helpers::allocate(sizeof(T) * n, handler_));
  72. }
  73. void deallocate(T* p, std::size_t n)
  74. {
  75. asio_handler_alloc_helpers::deallocate(p, sizeof(T) * n, handler_);
  76. }
  77. //private:
  78. Handler& handler_;
  79. };
  80. template <typename Handler>
  81. class hook_allocator<Handler, void>
  82. {
  83. public:
  84. typedef void value_type;
  85. template <typename U>
  86. struct rebind
  87. {
  88. typedef hook_allocator<Handler, U> other;
  89. };
  90. explicit hook_allocator(Handler& h)
  91. : handler_(h)
  92. {
  93. }
  94. template <typename U>
  95. hook_allocator(const hook_allocator<Handler, U>& a)
  96. : handler_(a.handler_)
  97. {
  98. }
  99. //private:
  100. Handler& handler_;
  101. };
  102. template <typename Handler, typename Allocator>
  103. struct get_hook_allocator
  104. {
  105. typedef Allocator type;
  106. static type get(Handler&, const Allocator& a)
  107. {
  108. return a;
  109. }
  110. };
  111. template <typename Handler, typename T>
  112. struct get_hook_allocator<Handler, std::allocator<T> >
  113. {
  114. typedef hook_allocator<Handler, T> type;
  115. static type get(Handler& handler, const std::allocator<T>&)
  116. {
  117. return type(handler);
  118. }
  119. };
  120. } // namespace detail
  121. } // namespace asio
  122. #define ASIO_DEFINE_HANDLER_PTR(op) \
  123. struct ptr \
  124. { \
  125. Handler* h; \
  126. op* v; \
  127. op* p; \
  128. ~ptr() \
  129. { \
  130. reset(); \
  131. } \
  132. static op* allocate(Handler& handler) \
  133. { \
  134. typedef typename ::asio::associated_allocator< \
  135. Handler>::type associated_allocator_type; \
  136. typedef typename ::asio::detail::get_hook_allocator< \
  137. Handler, associated_allocator_type>::type hook_allocator_type; \
  138. ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \
  139. ::asio::detail::get_hook_allocator< \
  140. Handler, associated_allocator_type>::get( \
  141. handler, ::asio::get_associated_allocator(handler))); \
  142. return a.allocate(1); \
  143. } \
  144. void reset() \
  145. { \
  146. if (p) \
  147. { \
  148. p->~op(); \
  149. p = 0; \
  150. } \
  151. if (v) \
  152. { \
  153. typedef typename ::asio::associated_allocator< \
  154. Handler>::type associated_allocator_type; \
  155. typedef typename ::asio::detail::get_hook_allocator< \
  156. Handler, associated_allocator_type>::type hook_allocator_type; \
  157. ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \
  158. ::asio::detail::get_hook_allocator< \
  159. Handler, associated_allocator_type>::get( \
  160. *h, ::asio::get_associated_allocator(*h))); \
  161. a.deallocate(static_cast<op*>(v), 1); \
  162. v = 0; \
  163. } \
  164. } \
  165. } \
  166. /**/
  167. #define ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
  168. struct ptr \
  169. { \
  170. const Alloc* a; \
  171. void* v; \
  172. op* p; \
  173. ~ptr() \
  174. { \
  175. reset(); \
  176. } \
  177. static op* allocate(const Alloc& a) \
  178. { \
  179. typedef typename ::asio::detail::get_recycling_allocator< \
  180. Alloc, purpose>::type recycling_allocator_type; \
  181. ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
  182. ::asio::detail::get_recycling_allocator< \
  183. Alloc, purpose>::get(a)); \
  184. return a1.allocate(1); \
  185. } \
  186. void reset() \
  187. { \
  188. if (p) \
  189. { \
  190. p->~op(); \
  191. p = 0; \
  192. } \
  193. if (v) \
  194. { \
  195. typedef typename ::asio::detail::get_recycling_allocator< \
  196. Alloc, purpose>::type recycling_allocator_type; \
  197. ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
  198. ::asio::detail::get_recycling_allocator< \
  199. Alloc, purpose>::get(*a)); \
  200. a1.deallocate(static_cast<op*>(v), 1); \
  201. v = 0; \
  202. } \
  203. } \
  204. } \
  205. /**/
  206. #define ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
  207. ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( \
  208. ::asio::detail::thread_info_base::default_tag, op ) \
  209. /**/
  210. #include "asio/detail/pop_options.hpp"
  211. #endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP