allocator.hpp 7.8 KB

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