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