Clementine
prefer_only.hpp
1 //
2 // execution/prefer_only.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 ASIO_EXECUTION_PREFER_ONLY_HPP
12 #define ASIO_EXECUTION_PREFER_ONLY_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include "asio/detail/type_traits.hpp"
20 #include "asio/is_applicable_property.hpp"
21 #include "asio/prefer.hpp"
22 #include "asio/query.hpp"
23 #include "asio/traits/static_query.hpp"
24 
25 #include "asio/detail/push_options.hpp"
26 
27 namespace asio {
28 
29 #if defined(GENERATING_DOCUMENTATION)
30 
31 namespace execution {
32 
35 template <typename Property>
36 struct prefer_only
37 {
39  template <typename T>
40  static constexpr bool is_applicable_property_v =
41  is_applicable_property<T, Property>::value;
42 
44  static constexpr bool is_requirable = false;
45 
48 
51  static constexpr bool is_preferable = automatically_determined;
52 
54  typedef typename Property::polymorphic_query_result_type
55  polymorphic_query_result_type;
56 };
57 
58 } // namespace execution
59 
60 #else // defined(GENERATING_DOCUMENTATION)
61 
62 namespace execution {
63 namespace detail {
64 
65 template <typename InnerProperty, typename = void>
67 {
68  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
69 };
70 
71 template <typename InnerProperty>
72 struct prefer_only_is_preferable<InnerProperty,
73  typename enable_if<
74  InnerProperty::is_preferable
75  >::type>
76 {
77  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
78 };
79 
80 template <typename InnerProperty, typename = void>
82 {
83 };
84 
85 template <typename InnerProperty>
87  typename void_type<
88  typename InnerProperty::polymorphic_query_result_type
89  >::type>
90 {
91  typedef typename InnerProperty::polymorphic_query_result_type
92  polymorphic_query_result_type;
93 };
94 
95 template <typename InnerProperty, typename = void>
97 {
98  InnerProperty property;
99 
100  prefer_only_property(const InnerProperty& p)
101  : property(p)
102  {
103  }
104 };
105 
106 #if defined(ASIO_HAS_DECLTYPE) \
107  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)
108 
109 template <typename InnerProperty>
110 struct prefer_only_property<InnerProperty,
111  typename void_type<
112  decltype(asio::declval<const InnerProperty>().value())
113  >::type>
114 {
115  InnerProperty property;
116 
117  prefer_only_property(const InnerProperty& p)
118  : property(p)
119  {
120  }
121 
122  ASIO_CONSTEXPR auto value() const
123  ASIO_NOEXCEPT_IF((
124  noexcept(asio::declval<const InnerProperty>().value())))
125  -> decltype(asio::declval<const InnerProperty>().value())
126  {
127  return property.value();
128  }
129 };
130 
131 #else // defined(ASIO_HAS_DECLTYPE)
132  // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)
133 
135 {
136  void value();
137 };
138 
139 template <typename T>
142 {
143 };
144 
145 template <typename T, T>
147 {
148 };
149 
150 template <typename>
151 char (&prefer_only_value_memfn_helper(...))[2];
152 
153 template <typename T>
154 char prefer_only_value_memfn_helper(
156  void (prefer_only_memfns_base::*)(),
158 
159 template <typename InnerProperty>
160 struct prefer_only_property<InnerProperty,
161  typename enable_if<
162  sizeof(prefer_only_value_memfn_helper<InnerProperty>(0)) != 1
163  && !is_same<typename InnerProperty::polymorphic_query_result_type,
164  void>::value
165  >::type>
166 {
167  InnerProperty property;
168 
169  prefer_only_property(const InnerProperty& p)
170  : property(p)
171  {
172  }
173 
174  ASIO_CONSTEXPR typename InnerProperty::polymorphic_query_result_type
175  value() const
176  {
177  return property.value();
178  }
179 };
180 
181 #endif // defined(ASIO_HAS_DECLTYPE)
182  // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)
183 
184 } // namespace detail
185 
186 template <typename InnerProperty>
187 struct prefer_only :
188  detail::prefer_only_is_preferable<InnerProperty>,
190  detail::prefer_only_property<InnerProperty>
191 {
192  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
193 
194  ASIO_CONSTEXPR prefer_only(const InnerProperty& p)
196  {
197  }
198 
199 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
200  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
201  template <typename T>
202  static ASIO_CONSTEXPR
204  static_query()
205  ASIO_NOEXCEPT_IF((
207  {
209  }
210 
211  template <typename E, typename T = decltype(prefer_only::static_query<E>())>
212  static ASIO_CONSTEXPR const T static_query_v
213  = prefer_only::static_query<E>();
214 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
215  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
216 
217  template <typename Executor, typename Property>
218  friend ASIO_CONSTEXPR
219  typename prefer_result<const Executor&, const InnerProperty&>::type
220  prefer(const Executor& ex, const prefer_only<Property>& p,
221  typename enable_if<
222  is_same<Property, InnerProperty>::value
224  >::type* = 0)
225 #if !defined(ASIO_MSVC) \
226  && !defined(__clang__) // Clang crashes if noexcept is used here.
227  ASIO_NOEXCEPT_IF((
229 #endif // !defined(ASIO_MSVC)
230  // && !defined(__clang__)
231  {
232  return asio::prefer(ex, p.property);
233  }
234 
235  template <typename Executor, typename Property>
236  friend ASIO_CONSTEXPR
237  typename query_result<const Executor&, const InnerProperty&>::type
238  query(const Executor& ex, const prefer_only<Property>& p,
239  typename enable_if<
240  is_same<Property, InnerProperty>::value
242  >::type* = 0)
243 #if !defined(ASIO_MSVC) \
244  && !defined(__clang__) // Clang crashes if noexcept is used here.
245  ASIO_NOEXCEPT_IF((
247 #endif // !defined(ASIO_MSVC)
248  // && !defined(__clang__)
249  {
250  return asio::query(ex, p.property);
251  }
252 };
253 
254 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
255  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
256 template <typename InnerProperty> template <typename E, typename T>
258 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
259  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
260 
261 } // namespace execution
262 
263 template <typename T, typename InnerProperty>
264 struct is_applicable_property<T, execution::prefer_only<InnerProperty> >
265  : is_applicable_property<T, InnerProperty>
266 {
267 };
268 
269 namespace traits {
270 
271 #if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
272  || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
273 
274 template <typename T, typename InnerProperty>
275 struct static_query<T, execution::prefer_only<InnerProperty> > :
276  static_query<T, const InnerProperty&>
277 {
278 };
279 
280 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
281  // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
282 
283 #if !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
284 
285 template <typename T, typename InnerProperty>
286 struct prefer_free_default<T, execution::prefer_only<InnerProperty>,
287  typename enable_if<
288  can_prefer<const T&, const InnerProperty&>::value
289  >::type>
290 {
291  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
292  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
294 
295  typedef typename prefer_result<const T&,
296  const InnerProperty&>::type result_type;
297 };
298 
299 #endif // !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
300 
301 #if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
302 
303 template <typename T, typename InnerProperty>
304 struct query_free<T, execution::prefer_only<InnerProperty>,
305  typename enable_if<
306  can_query<const T&, const InnerProperty&>::value
307  >::type>
308 {
309  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
310  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
312 
313  typedef typename query_result<const T&,
314  const InnerProperty&>::type result_type;
315 };
316 
317 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
318 
319 } // namespace traits
320 
321 #endif // defined(GENERATING_DOCUMENTATION)
322 
323 } // namespace asio
324 
325 #include "asio/detail/pop_options.hpp"
326 
327 #endif // ASIO_EXECUTION_PREFER_ONLY_HPP
Definition: prefer.hpp:574
Definition: prefer_only.hpp:187
Definition: type_traits.hpp:135
Definition: query.hpp:269
Definition: static_query.hpp:42
Definition: query.hpp:284
Definition: chrono.h:284
Definition: prefer_only.hpp:96
Definition: type_traits.hpp:97
Definition: query.hpp:253
Definition: query_free.hpp:38
Definition: any_executor.hpp:256
Definition: prefer.hpp:623
Definition: handler_work.hpp:37
Definition: prefer.hpp:522
Definition: is_applicable_property.hpp:46
Definition: any_io_executor.hpp:28
Definition: prefer_free.hpp:35