allocator.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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 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/execution/scheduler.hpp>
  19. #include <boost/asio/execution/sender.hpp>
  20. #include <boost/asio/is_applicable_property.hpp>
  21. #include <boost/asio/traits/query_static_constexpr_member.hpp>
  22. #include <boost/asio/traits/static_query.hpp>
  23. #include <boost/asio/detail/push_options.hpp>
  24. namespace boost {
  25. namespace asio {
  26. #if defined(GENERATING_DOCUMENTATION)
  27. namespace execution {
  28. /// A property to describe which allocator an executor will use to allocate the
  29. /// memory required to store a submitted function object.
  30. template <typename ProtoAllocator>
  31. struct allocator_t
  32. {
  33. /// The allocator_t property applies to executors, senders, and schedulers.
  34. template <typename T>
  35. static constexpr bool is_applicable_property_v =
  36. is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
  37. /// The allocator_t property can be required.
  38. static constexpr bool is_requirable = true;
  39. /// The allocator_t property can be preferred.
  40. static constexpr bool is_preferable = true;
  41. /// Default constructor.
  42. constexpr allocator_t();
  43. /// Obtain the allocator stored in the allocator_t property object.
  44. /**
  45. * Present only if @c ProtoAllocator is non-void.
  46. */
  47. constexpr ProtoAllocator value() const;
  48. /// Create an allocator_t object with a different allocator.
  49. /**
  50. * Present only if @c ProtoAllocator is void.
  51. */
  52. template <typename OtherAllocator>
  53. allocator_t<OtherAllocator operator()(const OtherAllocator& a);
  54. };
  55. /// A special value used for accessing the allocator_t property.
  56. constexpr allocator_t<void> allocator;
  57. } // namespace execution
  58. #else // defined(GENERATING_DOCUMENTATION)
  59. namespace execution {
  60. template <typename ProtoAllocator>
  61. struct allocator_t
  62. {
  63. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  64. # if defined(BOOST_ASIO_NO_DEPRECATED)
  65. template <typename T>
  66. BOOST_ASIO_STATIC_CONSTEXPR(bool,
  67. is_applicable_property_v = (
  68. is_executor<T>::value));
  69. # else // defined(BOOST_ASIO_NO_DEPRECATED)
  70. template <typename T>
  71. BOOST_ASIO_STATIC_CONSTEXPR(bool,
  72. is_applicable_property_v = (
  73. is_executor<T>::value
  74. || conditional<
  75. is_executor<T>::value,
  76. false_type,
  77. is_sender<T>
  78. >::type::value
  79. || conditional<
  80. is_executor<T>::value,
  81. false_type,
  82. is_scheduler<T>
  83. >::type::value
  84. ));
  85. # endif // defined(BOOST_ASIO_NO_DEPRECATED)
  86. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  87. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
  88. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
  89. template <typename T>
  90. struct static_proxy
  91. {
  92. #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  93. struct type
  94. {
  95. template <typename P>
  96. static constexpr auto query(BOOST_ASIO_MOVE_ARG(P) p)
  97. noexcept(
  98. noexcept(
  99. conditional<true, T, P>::type::query(BOOST_ASIO_MOVE_CAST(P)(p))
  100. )
  101. )
  102. -> decltype(
  103. conditional<true, T, P>::type::query(BOOST_ASIO_MOVE_CAST(P)(p))
  104. )
  105. {
  106. return T::query(BOOST_ASIO_MOVE_CAST(P)(p));
  107. }
  108. };
  109. #else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  110. typedef T type;
  111. #endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  112. };
  113. template <typename T>
  114. struct query_static_constexpr_member :
  115. traits::query_static_constexpr_member<
  116. typename static_proxy<T>::type, allocator_t> {};
  117. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  118. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  119. template <typename T>
  120. static BOOST_ASIO_CONSTEXPR
  121. typename query_static_constexpr_member<T>::result_type
  122. static_query()
  123. BOOST_ASIO_NOEXCEPT_IF((
  124. query_static_constexpr_member<T>::is_noexcept))
  125. {
  126. return query_static_constexpr_member<T>::value();
  127. }
  128. template <typename E, typename T = decltype(allocator_t::static_query<E>())>
  129. static BOOST_ASIO_CONSTEXPR const T static_query_v
  130. = allocator_t::static_query<E>();
  131. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  132. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  133. BOOST_ASIO_CONSTEXPR ProtoAllocator value() const
  134. {
  135. return a_;
  136. }
  137. private:
  138. friend struct allocator_t<void>;
  139. explicit BOOST_ASIO_CONSTEXPR allocator_t(const ProtoAllocator& a)
  140. : a_(a)
  141. {
  142. }
  143. ProtoAllocator a_;
  144. };
  145. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  146. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  147. template <typename ProtoAllocator> template <typename E, typename T>
  148. const T allocator_t<ProtoAllocator>::static_query_v;
  149. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  150. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  151. template <>
  152. struct allocator_t<void>
  153. {
  154. #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  155. # if defined(BOOST_ASIO_NO_DEPRECATED)
  156. template <typename T>
  157. BOOST_ASIO_STATIC_CONSTEXPR(bool,
  158. is_applicable_property_v = (
  159. is_executor<T>::value));
  160. # else // defined(BOOST_ASIO_NO_DEPRECATED)
  161. template <typename T>
  162. BOOST_ASIO_STATIC_CONSTEXPR(bool,
  163. is_applicable_property_v = (
  164. is_executor<T>::value
  165. || conditional<
  166. is_executor<T>::value,
  167. false_type,
  168. is_sender<T>
  169. >::type::value
  170. || conditional<
  171. is_executor<T>::value,
  172. false_type,
  173. is_scheduler<T>
  174. >::type::value
  175. ));
  176. # endif // defined(BOOST_ASIO_NO_DEPRECATED)
  177. #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  178. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
  179. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
  180. BOOST_ASIO_CONSTEXPR allocator_t()
  181. {
  182. }
  183. template <typename T>
  184. struct static_proxy
  185. {
  186. #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  187. struct type
  188. {
  189. template <typename P>
  190. static constexpr auto query(BOOST_ASIO_MOVE_ARG(P) p)
  191. noexcept(
  192. noexcept(
  193. conditional<true, T, P>::type::query(BOOST_ASIO_MOVE_CAST(P)(p))
  194. )
  195. )
  196. -> decltype(
  197. conditional<true, T, P>::type::query(BOOST_ASIO_MOVE_CAST(P)(p))
  198. )
  199. {
  200. return T::query(BOOST_ASIO_MOVE_CAST(P)(p));
  201. }
  202. };
  203. #else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  204. typedef T type;
  205. #endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
  206. };
  207. template <typename T>
  208. struct query_static_constexpr_member :
  209. traits::query_static_constexpr_member<
  210. typename static_proxy<T>::type, allocator_t> {};
  211. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  212. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  213. template <typename T>
  214. static BOOST_ASIO_CONSTEXPR
  215. typename query_static_constexpr_member<T>::result_type
  216. static_query()
  217. BOOST_ASIO_NOEXCEPT_IF((
  218. query_static_constexpr_member<T>::is_noexcept))
  219. {
  220. return query_static_constexpr_member<T>::value();
  221. }
  222. template <typename E, typename T = decltype(allocator_t::static_query<E>())>
  223. static BOOST_ASIO_CONSTEXPR const T static_query_v
  224. = allocator_t::static_query<E>();
  225. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  226. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  227. template <typename OtherProtoAllocator>
  228. BOOST_ASIO_CONSTEXPR allocator_t<OtherProtoAllocator> operator()(
  229. const OtherProtoAllocator& a) const
  230. {
  231. return allocator_t<OtherProtoAllocator>(a);
  232. }
  233. };
  234. #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  235. && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  236. template <typename E, typename T>
  237. const T allocator_t<void>::static_query_v;
  238. #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  239. // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  240. #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
  241. constexpr allocator_t<void> allocator;
  242. #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
  243. template <typename T>
  244. struct allocator_instance
  245. {
  246. static allocator_t<T> instance;
  247. };
  248. template <typename T>
  249. allocator_t<T> allocator_instance<T>::instance;
  250. namespace {
  251. static const allocator_t<void>& allocator = allocator_instance<void>::instance;
  252. } // namespace
  253. #endif
  254. } // namespace execution
  255. #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  256. template <typename T, typename ProtoAllocator>
  257. struct is_applicable_property<T, execution::allocator_t<ProtoAllocator> >
  258. : integral_constant<bool,
  259. execution::is_executor<T>::value
  260. #if !defined(BOOST_ASIO_NO_DEPRECATED)
  261. || conditional<
  262. execution::is_executor<T>::value,
  263. false_type,
  264. execution::is_sender<T>
  265. >::type::value
  266. || conditional<
  267. execution::is_executor<T>::value,
  268. false_type,
  269. execution::is_scheduler<T>
  270. >::type::value
  271. #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
  272. >
  273. {
  274. };
  275. #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
  276. namespace traits {
  277. #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
  278. || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  279. template <typename T, typename ProtoAllocator>
  280. struct static_query<T, execution::allocator_t<ProtoAllocator>,
  281. typename enable_if<
  282. execution::allocator_t<ProtoAllocator>::template
  283. query_static_constexpr_member<T>::is_valid
  284. >::type>
  285. {
  286. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  287. BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
  288. typedef typename execution::allocator_t<ProtoAllocator>::template
  289. query_static_constexpr_member<T>::result_type result_type;
  290. static BOOST_ASIO_CONSTEXPR result_type value()
  291. {
  292. return execution::allocator_t<ProtoAllocator>::template
  293. query_static_constexpr_member<T>::value();
  294. }
  295. };
  296. #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
  297. // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
  298. } // namespace traits
  299. #endif // defined(GENERATING_DOCUMENTATION)
  300. } // namespace asio
  301. } // namespace boost
  302. #include <boost/asio/detail/pop_options.hpp>
  303. #endif // BOOST_ASIO_EXECUTION_ALLOCATOR_HPP