• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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