Clementine
require.hpp
1 //
2 // require.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_REQUIRE_HPP
12 #define ASIO_REQUIRE_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/traits/require_member.hpp"
22 #include "asio/traits/require_free.hpp"
23 #include "asio/traits/static_require.hpp"
24 
25 #include "asio/detail/push_options.hpp"
26 
27 #if defined(GENERATING_DOCUMENTATION)
28 
29 namespace asio {
30 
33 
65 inline constexpr unspecified require = unspecified;
66 
68 
73 template <typename T, typename... Properties>
74 struct can_require :
75  integral_constant<bool, automatically_determined>
76 {
77 };
78 
80 
85 template <typename T, typename... Properties>
86 struct is_nothrow_require :
87  integral_constant<bool, automatically_determined>
88 {
89 };
90 
92 
97 template <typename T, typename... Properties>
98 struct require_result
99 {
101  typedef automatically_determined type;
102 };
103 
104 } // namespace asio
105 
106 #else // defined(GENERATING_DOCUMENTATION)
107 
108 namespace asio_require_fn {
109 
110 using asio::decay;
111 using asio::declval;
112 using asio::enable_if;
117 
118 void require();
119 
120 enum overload_type
121 {
122  identity,
123  call_member,
124  call_free,
125  two_props,
126  n_props,
127  ill_formed
128 };
129 
130 template <typename T, typename Properties, typename = void>
132 {
133  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
134  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
135  typedef void result_type;
136 };
137 
138 template <typename T, typename Property>
139 struct call_traits<T, void(Property),
140  typename enable_if<
141  (
143  typename decay<T>::type,
144  typename decay<Property>::type
145  >::value
146  &&
147  decay<Property>::type::is_requirable
148  &&
149  static_require<T, Property>::is_valid
150  )
151  >::type>
152 {
153  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);
154  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
155 
156 #if defined(ASIO_HAS_MOVE)
157  typedef ASIO_MOVE_ARG(T) result_type;
158 #else // defined(ASIO_HAS_MOVE)
159  typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;
160 #endif // defined(ASIO_HAS_MOVE)
161 };
162 
163 template <typename T, typename Property>
164 struct call_traits<T, void(Property),
165  typename enable_if<
166  (
168  typename decay<T>::type,
169  typename decay<Property>::type
170  >::value
171  &&
172  decay<Property>::type::is_requirable
173  &&
174  !static_require<T, Property>::is_valid
175  &&
176  require_member<T, Property>::is_valid
177  )
178  >::type> :
179  require_member<T, Property>
180 {
181  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
182 };
183 
184 template <typename T, typename Property>
185 struct call_traits<T, void(Property),
186  typename enable_if<
187  (
189  typename decay<T>::type,
190  typename decay<Property>::type
191  >::value
192  &&
193  decay<Property>::type::is_requirable
194  &&
195  !static_require<T, Property>::is_valid
196  &&
197  !require_member<T, Property>::is_valid
198  &&
199  require_free<T, Property>::is_valid
200  )
201  >::type> :
202  require_free<T, Property>
203 {
204  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
205 };
206 
207 template <typename T, typename P0, typename P1>
208 struct call_traits<T, void(P0, P1),
209  typename enable_if<
210  call_traits<T, void(P0)>::overload != ill_formed
211  &&
212  call_traits<
213  typename call_traits<T, void(P0)>::result_type,
214  void(P1)
215  >::overload != ill_formed
216  >::type>
217 {
218  ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props);
219 
220  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
221  (
222  call_traits<T, void(P0)>::is_noexcept
223  &&
224  call_traits<
225  typename call_traits<T, void(P0)>::result_type,
226  void(P1)
227  >::is_noexcept
228  ));
229 
230  typedef typename decay<
231  typename call_traits<
232  typename call_traits<T, void(P0)>::result_type,
233  void(P1)
234  >::result_type
235  >::type result_type;
236 };
237 
238 template <typename T, typename P0, typename P1, typename ASIO_ELLIPSIS PN>
239 struct call_traits<T, void(P0, P1, PN ASIO_ELLIPSIS),
240  typename enable_if<
241  call_traits<T, void(P0)>::overload != ill_formed
242  &&
243  call_traits<
244  typename call_traits<T, void(P0)>::result_type,
245  void(P1, PN ASIO_ELLIPSIS)
246  >::overload != ill_formed
247  >::type>
248 {
249  ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props);
250 
251  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
252  (
253  call_traits<T, void(P0)>::is_noexcept
254  &&
255  call_traits<
256  typename call_traits<T, void(P0)>::result_type,
257  void(P1, PN ASIO_ELLIPSIS)
258  >::is_noexcept
259  ));
260 
261  typedef typename decay<
262  typename call_traits<
263  typename call_traits<T, void(P0)>::result_type,
264  void(P1, PN ASIO_ELLIPSIS)
265  >::result_type
266  >::type result_type;
267 };
268 
269 struct impl
270 {
271  template <typename T, typename Property>
272  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
274  typename call_traits<T, void(Property)>::result_type
275  >::type
276  operator()(
277  ASIO_MOVE_ARG(T) t,
278  ASIO_MOVE_ARG(Property)) const
279  ASIO_NOEXCEPT_IF((
280  call_traits<T, void(Property)>::is_noexcept))
281  {
282  return ASIO_MOVE_CAST(T)(t);
283  }
284 
285  template <typename T, typename Property>
286  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
287  call_traits<T, void(Property)>::overload == call_member,
288  typename call_traits<T, void(Property)>::result_type
289  >::type
290  operator()(
291  ASIO_MOVE_ARG(T) t,
292  ASIO_MOVE_ARG(Property) p) const
293  ASIO_NOEXCEPT_IF((
294  call_traits<T, void(Property)>::is_noexcept))
295  {
296  return ASIO_MOVE_CAST(T)(t).require(
297  ASIO_MOVE_CAST(Property)(p));
298  }
299 
300  template <typename T, typename Property>
301  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
302  call_traits<T, void(Property)>::overload == call_free,
303  typename call_traits<T, void(Property)>::result_type
304  >::type
305  operator()(
306  ASIO_MOVE_ARG(T) t,
307  ASIO_MOVE_ARG(Property) p) const
308  ASIO_NOEXCEPT_IF((
309  call_traits<T, void(Property)>::is_noexcept))
310  {
311  return require(
312  ASIO_MOVE_CAST(T)(t),
313  ASIO_MOVE_CAST(Property)(p));
314  }
315 
316  template <typename T, typename P0, typename P1>
317  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
319  typename call_traits<T, void(P0, P1)>::result_type
320  >::type
321  operator()(
322  ASIO_MOVE_ARG(T) t,
323  ASIO_MOVE_ARG(P0) p0,
324  ASIO_MOVE_ARG(P1) p1) const
325  ASIO_NOEXCEPT_IF((
326  call_traits<T, void(P0, P1)>::is_noexcept))
327  {
328  return (*this)(
329  (*this)(
330  ASIO_MOVE_CAST(T)(t),
331  ASIO_MOVE_CAST(P0)(p0)),
332  ASIO_MOVE_CAST(P1)(p1));
333  }
334 
335  template <typename T, typename P0, typename P1,
336  typename ASIO_ELLIPSIS PN>
337  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
339  typename call_traits<T, void(P0, P1, PN ASIO_ELLIPSIS)>::result_type
340  >::type
341  operator()(
342  ASIO_MOVE_ARG(T) t,
343  ASIO_MOVE_ARG(P0) p0,
344  ASIO_MOVE_ARG(P1) p1,
345  ASIO_MOVE_ARG(PN) ASIO_ELLIPSIS pn) const
346  ASIO_NOEXCEPT_IF((
347  call_traits<T, void(P0, P1, PN ASIO_ELLIPSIS)>::is_noexcept))
348  {
349  return (*this)(
350  (*this)(
351  ASIO_MOVE_CAST(T)(t),
352  ASIO_MOVE_CAST(P0)(p0)),
353  ASIO_MOVE_CAST(P1)(p1),
354  ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS);
355  }
356 };
357 
358 template <typename T = impl>
360 {
361  static const T instance;
362 };
363 
364 template <typename T>
365 const T static_instance<T>::instance = {};
366 
367 } // namespace asio_require_fn
368 namespace asio {
369 namespace {
370 
371 static ASIO_CONSTEXPR const asio_require_fn::impl&
373 
374 } // namespace
375 
376 #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
377 
378 template <typename T, typename... Properties>
379 struct can_require :
380  integral_constant<bool,
381  asio_require_fn::call_traits<T, void(Properties...)>::overload
382  != asio_require_fn::ill_formed>
383 {
384 };
385 
386 #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
387 
388 template <typename T, typename P0 = void,
389  typename P1 = void, typename P2 = void>
390 struct can_require :
391  integral_constant<bool,
392  asio_require_fn::call_traits<T, void(P0, P1, P2)>::overload
393  != asio_require_fn::ill_formed>
394 {
395 };
396 
397 template <typename T, typename P0, typename P1>
398 struct can_require<T, P0, P1> :
399  integral_constant<bool,
400  asio_require_fn::call_traits<T, void(P0, P1)>::overload
401  != asio_require_fn::ill_formed>
402 {
403 };
404 
405 template <typename T, typename P0>
406 struct can_require<T, P0> :
407  integral_constant<bool,
408  asio_require_fn::call_traits<T, void(P0)>::overload
409  != asio_require_fn::ill_formed>
410 {
411 };
412 
413 template <typename T>
414 struct can_require<T> :
415  false_type
416 {
417 };
418 
419 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
420 
421 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
422 
423 template <typename T, typename ASIO_ELLIPSIS Properties>
424 constexpr bool can_require_v
426 
427 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
428 
429 #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
430 
431 template <typename T, typename... Properties>
432 struct is_nothrow_require :
433  integral_constant<bool,
434  asio_require_fn::call_traits<T, void(Properties...)>::is_noexcept>
435 {
436 };
437 
438 #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
439 
440 template <typename T, typename P0 = void,
441  typename P1 = void, typename P2 = void>
443  integral_constant<bool,
444  asio_require_fn::call_traits<T, void(P0, P1, P2)>::is_noexcept>
445 {
446 };
447 
448 template <typename T, typename P0, typename P1>
449 struct is_nothrow_require<T, P0, P1> :
450  integral_constant<bool,
451  asio_require_fn::call_traits<T, void(P0, P1)>::is_noexcept>
452 {
453 };
454 
455 template <typename T, typename P0>
456 struct is_nothrow_require<T, P0> :
457  integral_constant<bool,
458  asio_require_fn::call_traits<T, void(P0)>::is_noexcept>
459 {
460 };
461 
462 template <typename T>
464  false_type
465 {
466 };
467 
468 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
469 
470 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
471 
472 template <typename T, typename ASIO_ELLIPSIS Properties>
473 constexpr bool is_nothrow_require_v
475 
476 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
477 
478 #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
479 
480 template <typename T, typename... Properties>
481 struct require_result
482 {
483  typedef typename asio_require_fn::call_traits<
484  T, void(Properties...)>::result_type type;
485 };
486 
487 #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
488 
489 template <typename T, typename P0 = void,
490  typename P1 = void, typename P2 = void>
492 {
493  typedef typename asio_require_fn::call_traits<
494  T, void(P0, P1, P2)>::result_type type;
495 };
496 
497 template <typename T, typename P0, typename P1>
498 struct require_result<T, P0, P1>
499 {
500  typedef typename asio_require_fn::call_traits<
501  T, void(P0, P1)>::result_type type;
502 };
503 
504 template <typename T, typename P0>
505 struct require_result<T, P0>
506 {
507  typedef typename asio_require_fn::call_traits<
508  T, void(P0)>::result_type type;
509 };
510 
511 template <typename T>
512 struct require_result<T>
513 {
514 };
515 
516 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
517 
518 } // namespace asio
519 
520 #endif // defined(GENERATING_DOCUMENTATION)
521 
522 #include "asio/detail/pop_options.hpp"
523 
524 #endif // ASIO_REQUIRE_HPP
Definition: static_require.hpp:37
Definition: require.hpp:491
Definition: require.hpp:269
Definition: require.hpp:442
Definition: require.hpp:359
Definition: type_traits.hpp:97
Definition: require_member.hpp:38
Definition: require.hpp:131
Definition: require.hpp:390
Definition: require.hpp:108
Definition: is_applicable_property.hpp:46
Definition: require_free.hpp:38
Definition: any_io_executor.hpp:28