Clementine
prefer.hpp
1 //
2 // prefer.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_PREFER_HPP
12 #define ASIO_PREFER_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/prefer_free.hpp"
22 #include "asio/traits/prefer_member.hpp"
23 #include "asio/traits/require_free.hpp"
24 #include "asio/traits/require_member.hpp"
25 #include "asio/traits/static_require.hpp"
26 
27 #include "asio/detail/push_options.hpp"
28 
29 #if defined(GENERATING_DOCUMENTATION)
30 
31 namespace asio {
32 
34 
76 inline constexpr unspecified prefer = unspecified;
77 
79 
84 template <typename T, typename... Properties>
85 struct can_prefer :
86  integral_constant<bool, automatically_determined>
87 {
88 };
89 
91 
96 template <typename T, typename... Properties>
97 struct is_nothrow_prefer :
98  integral_constant<bool, automatically_determined>
99 {
100 };
101 
103 
108 template <typename T, typename... Properties>
109 struct prefer_result
110 {
112  typedef automatically_determined type;
113 };
114 
115 } // namespace asio
116 
117 #else // defined(GENERATING_DOCUMENTATION)
118 
119 namespace asio_prefer_fn {
120 
121 using asio::decay;
122 using asio::declval;
123 using asio::enable_if;
130 
131 void prefer();
132 void require();
133 
134 enum overload_type
135 {
136  identity,
137  call_require_member,
138  call_require_free,
139  call_prefer_member,
140  call_prefer_free,
141  two_props,
142  n_props,
143  ill_formed
144 };
145 
146 template <typename T, typename Properties, typename = void>
148 {
149  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
150  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
151  typedef void result_type;
152 };
153 
154 template <typename T, typename Property>
155 struct call_traits<T, void(Property),
156  typename enable_if<
157  (
159  typename decay<T>::type,
160  typename decay<Property>::type
161  >::value
162  &&
163  decay<Property>::type::is_preferable
164  &&
165  static_require<T, Property>::is_valid
166  )
167  >::type>
168 {
169  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);
170  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
171 
172 #if defined(ASIO_HAS_MOVE)
173  typedef ASIO_MOVE_ARG(T) result_type;
174 #else // defined(ASIO_HAS_MOVE)
175  typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;
176 #endif // defined(ASIO_HAS_MOVE)
177 };
178 
179 template <typename T, typename Property>
180 struct call_traits<T, void(Property),
181  typename enable_if<
182  (
184  typename decay<T>::type,
185  typename decay<Property>::type
186  >::value
187  &&
188  decay<Property>::type::is_preferable
189  &&
190  !static_require<T, Property>::is_valid
191  &&
192  require_member<T, Property>::is_valid
193  )
194  >::type> :
195  require_member<T, Property>
196 {
197  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_member);
198 };
199 
200 template <typename T, typename Property>
201 struct call_traits<T, void(Property),
202  typename enable_if<
203  (
205  typename decay<T>::type,
206  typename decay<Property>::type
207  >::value
208  &&
209  decay<Property>::type::is_preferable
210  &&
211  !static_require<T, Property>::is_valid
212  &&
213  !require_member<T, Property>::is_valid
214  &&
215  require_free<T, Property>::is_valid
216  )
217  >::type> :
218  require_free<T, Property>
219 {
220  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_free);
221 };
222 
223 template <typename T, typename Property>
224 struct call_traits<T, void(Property),
225  typename enable_if<
226  (
228  typename decay<T>::type,
229  typename decay<Property>::type
230  >::value
231  &&
232  decay<Property>::type::is_preferable
233  &&
234  !static_require<T, Property>::is_valid
235  &&
236  !require_member<T, Property>::is_valid
237  &&
238  !require_free<T, Property>::is_valid
239  &&
240  prefer_member<T, Property>::is_valid
241  )
242  >::type> :
243  prefer_member<T, Property>
244 {
245  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_member);
246 };
247 
248 template <typename T, typename Property>
249 struct call_traits<T, void(Property),
250  typename enable_if<
251  (
253  typename decay<T>::type,
254  typename decay<Property>::type
255  >::value
256  &&
257  decay<Property>::type::is_preferable
258  &&
259  !static_require<T, Property>::is_valid
260  &&
261  !require_member<T, Property>::is_valid
262  &&
263  !require_free<T, Property>::is_valid
264  &&
265  !prefer_member<T, Property>::is_valid
266  &&
267  prefer_free<T, Property>::is_valid
268  )
269  >::type> :
270  prefer_free<T, Property>
271 {
272  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_free);
273 };
274 
275 template <typename T, typename Property>
276 struct call_traits<T, void(Property),
277  typename enable_if<
278  (
280  typename decay<T>::type,
281  typename decay<Property>::type
282  >::value
283  &&
284  decay<Property>::type::is_preferable
285  &&
286  !static_require<T, Property>::is_valid
287  &&
288  !require_member<T, Property>::is_valid
289  &&
290  !require_free<T, Property>::is_valid
291  &&
292  !prefer_member<T, Property>::is_valid
293  &&
294  !prefer_free<T, Property>::is_valid
295  )
296  >::type>
297 {
298  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);
299  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
300 
301 #if defined(ASIO_HAS_MOVE)
302  typedef ASIO_MOVE_ARG(T) result_type;
303 #else // defined(ASIO_HAS_MOVE)
304  typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;
305 #endif // defined(ASIO_HAS_MOVE)
306 };
307 
308 template <typename T, typename P0, typename P1>
309 struct call_traits<T, void(P0, P1),
310  typename enable_if<
311  call_traits<T, void(P0)>::overload != ill_formed
312  &&
313  call_traits<
314  typename call_traits<T, void(P0)>::result_type,
315  void(P1)
316  >::overload != ill_formed
317  >::type>
318 {
319  ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props);
320 
321  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
322  (
323  call_traits<T, void(P0)>::is_noexcept
324  &&
325  call_traits<
326  typename call_traits<T, void(P0)>::result_type,
327  void(P1)
328  >::is_noexcept
329  ));
330 
331  typedef typename decay<
332  typename call_traits<
333  typename call_traits<T, void(P0)>::result_type,
334  void(P1)
335  >::result_type
336  >::type result_type;
337 };
338 
339 template <typename T, typename P0, typename P1, typename ASIO_ELLIPSIS PN>
340 struct call_traits<T, void(P0, P1, PN ASIO_ELLIPSIS),
341  typename enable_if<
342  call_traits<T, void(P0)>::overload != ill_formed
343  &&
344  call_traits<
345  typename call_traits<T, void(P0)>::result_type,
346  void(P1, PN ASIO_ELLIPSIS)
347  >::overload != ill_formed
348  >::type>
349 {
350  ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props);
351 
352  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
353  (
354  call_traits<T, void(P0)>::is_noexcept
355  &&
356  call_traits<
357  typename call_traits<T, void(P0)>::result_type,
358  void(P1, PN ASIO_ELLIPSIS)
359  >::is_noexcept
360  ));
361 
362  typedef typename decay<
363  typename call_traits<
364  typename call_traits<T, void(P0)>::result_type,
365  void(P1, PN ASIO_ELLIPSIS)
366  >::result_type
367  >::type result_type;
368 };
369 
370 struct impl
371 {
372  template <typename T, typename Property>
373  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
375  typename call_traits<T, void(Property)>::result_type
376  >::type
377  operator()(
378  ASIO_MOVE_ARG(T) t,
379  ASIO_MOVE_ARG(Property)) const
380  ASIO_NOEXCEPT_IF((
381  call_traits<T, void(Property)>::is_noexcept))
382  {
383  return ASIO_MOVE_CAST(T)(t);
384  }
385 
386  template <typename T, typename Property>
387  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
388  call_traits<T, void(Property)>::overload == call_require_member,
389  typename call_traits<T, void(Property)>::result_type
390  >::type
391  operator()(
392  ASIO_MOVE_ARG(T) t,
393  ASIO_MOVE_ARG(Property) p) const
394  ASIO_NOEXCEPT_IF((
395  call_traits<T, void(Property)>::is_noexcept))
396  {
397  return ASIO_MOVE_CAST(T)(t).require(
398  ASIO_MOVE_CAST(Property)(p));
399  }
400 
401  template <typename T, typename Property>
402  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
403  call_traits<T, void(Property)>::overload == call_require_free,
404  typename call_traits<T, void(Property)>::result_type
405  >::type
406  operator()(
407  ASIO_MOVE_ARG(T) t,
408  ASIO_MOVE_ARG(Property) p) const
409  ASIO_NOEXCEPT_IF((
410  call_traits<T, void(Property)>::is_noexcept))
411  {
412  return require(
413  ASIO_MOVE_CAST(T)(t),
414  ASIO_MOVE_CAST(Property)(p));
415  }
416 
417  template <typename T, typename Property>
418  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
419  call_traits<T, void(Property)>::overload == call_prefer_member,
420  typename call_traits<T, void(Property)>::result_type
421  >::type
422  operator()(
423  ASIO_MOVE_ARG(T) t,
424  ASIO_MOVE_ARG(Property) p) const
425  ASIO_NOEXCEPT_IF((
426  call_traits<T, void(Property)>::is_noexcept))
427  {
428  return ASIO_MOVE_CAST(T)(t).prefer(
429  ASIO_MOVE_CAST(Property)(p));
430  }
431 
432  template <typename T, typename Property>
433  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
434  call_traits<T, void(Property)>::overload == call_prefer_free,
435  typename call_traits<T, void(Property)>::result_type
436  >::type
437  operator()(
438  ASIO_MOVE_ARG(T) t,
439  ASIO_MOVE_ARG(Property) p) const
440  ASIO_NOEXCEPT_IF((
441  call_traits<T, void(Property)>::is_noexcept))
442  {
443  return prefer(
444  ASIO_MOVE_CAST(T)(t),
445  ASIO_MOVE_CAST(Property)(p));
446  }
447 
448  template <typename T, typename P0, typename P1>
449  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
451  typename call_traits<T, void(P0, P1)>::result_type
452  >::type
453  operator()(
454  ASIO_MOVE_ARG(T) t,
455  ASIO_MOVE_ARG(P0) p0,
456  ASIO_MOVE_ARG(P1) p1) const
457  ASIO_NOEXCEPT_IF((
458  call_traits<T, void(P0, P1)>::is_noexcept))
459  {
460  return (*this)(
461  (*this)(
462  ASIO_MOVE_CAST(T)(t),
463  ASIO_MOVE_CAST(P0)(p0)),
464  ASIO_MOVE_CAST(P1)(p1));
465  }
466 
467  template <typename T, typename P0, typename P1,
468  typename ASIO_ELLIPSIS PN>
469  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<
471  typename call_traits<T, void(P0, P1, PN ASIO_ELLIPSIS)>::result_type
472  >::type
473  operator()(
474  ASIO_MOVE_ARG(T) t,
475  ASIO_MOVE_ARG(P0) p0,
476  ASIO_MOVE_ARG(P1) p1,
477  ASIO_MOVE_ARG(PN) ASIO_ELLIPSIS pn) const
478  ASIO_NOEXCEPT_IF((
479  call_traits<T, void(P0, P1, PN ASIO_ELLIPSIS)>::is_noexcept))
480  {
481  return (*this)(
482  (*this)(
483  ASIO_MOVE_CAST(T)(t),
484  ASIO_MOVE_CAST(P0)(p0)),
485  ASIO_MOVE_CAST(P1)(p1),
486  ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS);
487  }
488 };
489 
490 template <typename T = impl>
492 {
493  static const T instance;
494 };
495 
496 template <typename T>
497 const T static_instance<T>::instance = {};
498 
499 } // namespace asio_prefer_fn
500 namespace asio {
501 namespace {
502 
503 static ASIO_CONSTEXPR const asio_prefer_fn::impl&
505 
506 } // namespace
507 
508 #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
509 
510 template <typename T, typename... Properties>
511 struct can_prefer :
512  integral_constant<bool,
513  asio_prefer_fn::call_traits<T, void(Properties...)>::overload
514  != asio_prefer_fn::ill_formed>
515 {
516 };
517 
518 #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
519 
520 template <typename T, typename P0 = void,
521  typename P1 = void, typename P2 = void>
522 struct can_prefer :
523  integral_constant<bool,
524  asio_prefer_fn::call_traits<T, void(P0, P1, P2)>::overload
525  != asio_prefer_fn::ill_formed>
526 {
527 };
528 
529 template <typename T, typename P0, typename P1>
530 struct can_prefer<T, P0, P1> :
531  integral_constant<bool,
532  asio_prefer_fn::call_traits<T, void(P0, P1)>::overload
533  != asio_prefer_fn::ill_formed>
534 {
535 };
536 
537 template <typename T, typename P0>
538 struct can_prefer<T, P0> :
539  integral_constant<bool,
540  asio_prefer_fn::call_traits<T, void(P0)>::overload
541  != asio_prefer_fn::ill_formed>
542 {
543 };
544 
545 template <typename T>
546 struct can_prefer<T> :
547  false_type
548 {
549 };
550 
551 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
552 
553 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
554 
555 template <typename T, typename ASIO_ELLIPSIS Properties>
556 constexpr bool can_prefer_v
558 
559 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
560 
561 #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
562 
563 template <typename T, typename... Properties>
564 struct is_nothrow_prefer :
565  integral_constant<bool,
566  asio_prefer_fn::call_traits<T, void(Properties...)>::is_noexcept>
567 {
568 };
569 
570 #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
571 
572 template <typename T, typename P0 = void,
573  typename P1 = void, typename P2 = void>
575  integral_constant<bool,
576  asio_prefer_fn::call_traits<T, void(P0, P1, P2)>::is_noexcept>
577 {
578 };
579 
580 template <typename T, typename P0, typename P1>
581 struct is_nothrow_prefer<T, P0, P1> :
582  integral_constant<bool,
583  asio_prefer_fn::call_traits<T, void(P0, P1)>::is_noexcept>
584 {
585 };
586 
587 template <typename T, typename P0>
588 struct is_nothrow_prefer<T, P0> :
589  integral_constant<bool,
590  asio_prefer_fn::call_traits<T, void(P0)>::is_noexcept>
591 {
592 };
593 
594 template <typename T>
595 struct is_nothrow_prefer<T> :
596  false_type
597 {
598 };
599 
600 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
601 
602 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
603 
604 template <typename T, typename ASIO_ELLIPSIS Properties>
605 constexpr bool is_nothrow_prefer_v
607 
608 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
609 
610 #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
611 
612 template <typename T, typename... Properties>
613 struct prefer_result
614 {
615  typedef typename asio_prefer_fn::call_traits<
616  T, void(Properties...)>::result_type type;
617 };
618 
619 #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
620 
621 template <typename T, typename P0 = void,
622  typename P1 = void, typename P2 = void>
624 {
625  typedef typename asio_prefer_fn::call_traits<
626  T, void(P0, P1, P2)>::result_type type;
627 };
628 
629 template <typename T, typename P0, typename P1>
630 struct prefer_result<T, P0, P1>
631 {
632  typedef typename asio_prefer_fn::call_traits<
633  T, void(P0, P1)>::result_type type;
634 };
635 
636 template <typename T, typename P0>
637 struct prefer_result<T, P0>
638 {
639  typedef typename asio_prefer_fn::call_traits<
640  T, void(P0)>::result_type type;
641 };
642 
643 template <typename T>
644 struct prefer_result<T>
645 {
646 };
647 
648 #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
649 
650 } // namespace asio
651 
652 #endif // defined(GENERATING_DOCUMENTATION)
653 
654 #include "asio/detail/pop_options.hpp"
655 
656 #endif // ASIO_PREFER_HPP
Definition: prefer.hpp:370
Definition: static_require.hpp:37
Definition: prefer.hpp:491
Definition: prefer.hpp:574
Definition: prefer_member.hpp:38
Definition: type_traits.hpp:97
Definition: require_member.hpp:38
Definition: prefer.hpp:119
Definition: prefer.hpp:623
Definition: prefer.hpp:147
Definition: prefer.hpp:522
Definition: is_applicable_property.hpp:46
Definition: require_free.hpp:38
Definition: prefer_free.hpp:38
Definition: any_io_executor.hpp:28