allocator.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. //
  2. // execution/allocator.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2024 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_EXECUTION_ALLOCATOR_HPP
  11. #define BOOST_ASIO_EXECUTION_ALLOCATOR_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/config.hpp>
  16. #include <boost/asio/detail/type_traits.hpp>
  17. #include <boost/asio/execution/executor.hpp>
  18. #include <boost/asio/is_applicable_property.hpp>
  19. #include <boost/asio/traits/query_static_constexpr_member.hpp>
  20. #include <boost/asio/traits/static_query.hpp>
  21. #include <boost/asio/detail/push_options.hpp>
  22. namespace boost {
  23. namespace asio {
  24. #if defined(GENERATING_DOCUMENTATION)
  25. namespace execution {
  26. /// A property to describe which allocator an executor will use to allocate the
  27. /// memory required to store a submitted function object.
  28. template <typename ProtoAllocator>
  29. struct allocator_t
  30. {
  31. /// The allocator_t property applies to executors.
  32. template <typename T>
  33. static constexpr bool is_applicable_property_v = is_executor_v<T>;
  34. /// The allocator_t property can be required.
  35. static constexpr bool is_requirable = true;
  36. /// The allocator_t property can be preferred.
  37. static constexpr bool is_preferable = true;
  38. /// Default constructor.
  39. constexpr allocator_t();
  40. /// Obtain the allocator stored in the allocator_t property object.
  41. /**
  42. * Present only if @c ProtoAllocator is non-void.
  43. */
  44. constexpr ProtoAllocator value() const;
  45. /// Create an allocator_t object with a different allocator.
  46. /**
  47. * Present only if @c ProtoAllocator is void.
  48. */
  49. template <typename OtherAllocator>
  50. allocator_t<OtherAllocator operator()(const OtherAllocator& a);
  51. };
  52. /// A special value used for accessing the allocator_t property.
  53. constexpr allocator_t<void> allocator;
  54. } // namespace execution
  55. #else // defined(GENERATING_DOCUMENTATION)
  56. namespace execution {
  57. template <typename ProtoAllocator>
  58. struct allocator_t
  59. {
  60. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  61. template <typename T>
  62. static constexpr bool is_applicable_property_v = is_executor<T>::value;
  63. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  64. static constexpr bool is_requirable = true;
  65. static constexpr bool is_preferable = true;
  66. template <typename T>
  67. struct static_proxy
  68. {
  69. #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  70. struct type
  71. {
  72. template <typename P>
  73. static constexpr auto query(P&& p)
  74. noexcept(
  75. noexcept(
  76. conditional_t<true, T, P>::query(static_cast<P&&>(p))
  77. )
  78. )
  79. -> decltype(
  80. conditional_t<true, T, P>::query(static_cast<P&&>(p))
  81. )
  82. {
  83. return T::query(static_cast<P&&>(p));
  84. }
  85. };
  86. #else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  87. typedef T type;
  88. #endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  89. };
  90. template <typename T>
  91. struct query_static_constexpr_member :
  92. traits::query_static_constexpr_member<
  93. typename static_proxy<T>::type, allocator_t> {};
  94. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  95. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  96. template <typename T>
  97. static constexpr typename query_static_constexpr_member<T>::result_type
  98. static_query()
  99. noexcept(query_static_constexpr_member<T>::is_noexcept)
  100. {
  101. return query_static_constexpr_member<T>::value();
  102. }
  103. template <typename E, typename T = decltype(allocator_t::static_query<E>())>
  104. static constexpr const T static_query_v = allocator_t::static_query<E>();
  105. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  106. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  107. constexpr ProtoAllocator value() const
  108. {
  109. return a_;
  110. }
  111. private:
  112. friend struct allocator_t<void>;
  113. explicit constexpr allocator_t(const ProtoAllocator& a)
  114. : a_(a)
  115. {
  116. }
  117. ProtoAllocator a_;
  118. };
  119. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  120. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  121. template <typename ProtoAllocator> template <typename E, typename T>
  122. const T allocator_t<ProtoAllocator>::static_query_v;
  123. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  124. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  125. template <>
  126. struct allocator_t<void>
  127. {
  128. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  129. template <typename T>
  130. static constexpr bool is_applicable_property_v = is_executor<T>::value;
  131. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  132. static constexpr bool is_requirable = true;
  133. static constexpr bool is_preferable = true;
  134. constexpr allocator_t()
  135. {
  136. }
  137. template <typename T>
  138. struct static_proxy
  139. {
  140. #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  141. struct type
  142. {
  143. template <typename P>
  144. static constexpr auto query(P&& p)
  145. noexcept(
  146. noexcept(
  147. conditional_t<true, T, P>::query(static_cast<P&&>(p))
  148. )
  149. )
  150. -> decltype(
  151. conditional_t<true, T, P>::query(static_cast<P&&>(p))
  152. )
  153. {
  154. return T::query(static_cast<P&&>(p));
  155. }
  156. };
  157. #else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  158. typedef T type;
  159. #endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  160. };
  161. template <typename T>
  162. struct query_static_constexpr_member :
  163. traits::query_static_constexpr_member<
  164. typename static_proxy<T>::type, allocator_t> {};
  165. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  166. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  167. template <typename T>
  168. static constexpr typename query_static_constexpr_member<T>::result_type
  169. static_query()
  170. noexcept(query_static_constexpr_member<T>::is_noexcept)
  171. {
  172. return query_static_constexpr_member<T>::value();
  173. }
  174. template <typename E, typename T = decltype(allocator_t::static_query<E>())>
  175. static constexpr const T static_query_v = allocator_t::static_query<E>();
  176. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  177. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  178. template <typename OtherProtoAllocator>
  179. constexpr allocator_t<OtherProtoAllocator> operator()(
  180. const OtherProtoAllocator& a) const
  181. {
  182. return allocator_t<OtherProtoAllocator>(a);
  183. }
  184. };
  185. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  186. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  187. template <typename E, typename T>
  188. const T allocator_t<void>::static_query_v;
  189. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  190. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  191. BOOST_ASIO_INLINE_VARIABLE constexpr allocator_t<void> allocator;
  192. } // namespace execution
  193. #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  194. template <typename T, typename ProtoAllocator>
  195. struct is_applicable_property<T, execution::allocator_t<ProtoAllocator>>
  196. : integral_constant<bool, execution::is_executor<T>::value>
  197. {
  198. };
  199. #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  200. namespace traits {
  201. #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  202. || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  203. template <typename T, typename ProtoAllocator>
  204. struct static_query<T, execution::allocator_t<ProtoAllocator>,
  205. enable_if_t<
  206. execution::allocator_t<ProtoAllocator>::template
  207. query_static_constexpr_member<T>::is_valid
  208. >>
  209. {
  210. static constexpr bool is_valid = true;
  211. static constexpr bool is_noexcept = true;
  212. typedef typename execution::allocator_t<ProtoAllocator>::template
  213. query_static_constexpr_member<T>::result_type result_type;
  214. static constexpr result_type value()
  215. {
  216. return execution::allocator_t<ProtoAllocator>::template
  217. query_static_constexpr_member<T>::value();
  218. }
  219. };
  220. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  221. // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  222. } // namespace traits
  223. #endif // defined(GENERATING_DOCUMENTATION)
  224. } // namespace asio
  225. } // namespace boost
  226. #include <boost/asio/detail/pop_options.hpp>
  227. #endif // BOOST_ASIO_EXECUTION_ALLOCATOR_HPP