]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/prefer.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / prefer.hpp
CommitLineData
20effc67
TL
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 BOOST_ASIO_PREFER_HPP
12#define BOOST_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 <boost/asio/detail/config.hpp>
19#include <boost/asio/detail/type_traits.hpp>
20#include <boost/asio/is_applicable_property.hpp>
21#include <boost/asio/traits/prefer_free.hpp>
22#include <boost/asio/traits/prefer_member.hpp>
23#include <boost/asio/traits/require_free.hpp>
24#include <boost/asio/traits/require_member.hpp>
25#include <boost/asio/traits/static_require.hpp>
26
27#include <boost/asio/detail/push_options.hpp>
28
29#if defined(GENERATING_DOCUMENTATION)
30
31namespace boost {
32namespace asio {
33
34/// A customisation point that attempts to apply a property to an object.
35/**
36 * The name <tt>prefer</tt> denotes a customisation point object. The
37 * expression <tt>boost::asio::prefer(E, P0, Pn...)</tt> for some subexpressions
38 * <tt>E</tt> and <tt>P0</tt>, and where <tt>Pn...</tt> represents <tt>N</tt>
39 * subexpressions (where <tt>N</tt> is 0 or more, and with types <tt>T =
40 * decay_t<decltype(E)></tt> and <tt>Prop0 = decay_t<decltype(P0)></tt>) is
41 * expression-equivalent to:
42 *
43 * @li If <tt>is_applicable_property_v<T, Prop0> && Prop0::is_preferable</tt> is
44 * not a well-formed constant expression with value <tt>true</tt>,
45 * <tt>boost::asio::prefer(E, P0, Pn...)</tt> is ill-formed.
46 *
47 * @li Otherwise, <tt>E</tt> if <tt>N == 0</tt> and the expression
48 * <tt>Prop0::template static_query_v<T> == Prop0::value()</tt> is a
49 * well-formed constant expression with value <tt>true</tt>.
50 *
51 * @li Otherwise, <tt>(E).require(P0)</tt> if <tt>N == 0</tt> and the expression
52 * <tt>(E).require(P0)</tt> is a valid expression.
53 *
54 * @li Otherwise, <tt>require(E, P0)</tt> if <tt>N == 0</tt> and the expression
55 * <tt>require(E, P0)</tt> is a valid expression with overload resolution
56 * performed in a context that does not include the declaration of the
57 * <tt>require</tt> customization point object.
58 *
59 * @li Otherwise, <tt>(E).prefer(P0)</tt> if <tt>N == 0</tt> and the expression
60 * <tt>(E).prefer(P0)</tt> is a valid expression.
61 *
62 * @li Otherwise, <tt>prefer(E, P0)</tt> if <tt>N == 0</tt> and the expression
63 * <tt>prefer(E, P0)</tt> is a valid expression with overload resolution
64 * performed in a context that does not include the declaration of the
65 * <tt>prefer</tt> customization point object.
66 *
67 * @li Otherwise, <tt>E</tt> if <tt>N == 0</tt>.
68 *
69 * @li Otherwise,
70 * <tt>boost::asio::prefer(boost::asio::prefer(E, P0), Pn...)</tt>
71 * if <tt>N > 0</tt> and the expression
72 * <tt>boost::asio::prefer(boost::asio::prefer(E, P0), Pn...)</tt>
73 * is a valid expression.
74 *
75 * @li Otherwise, <tt>boost::asio::prefer(E, P0, Pn...)</tt> is ill-formed.
76 */
77inline constexpr unspecified prefer = unspecified;
78
79/// A type trait that determines whether a @c prefer expression is well-formed.
80/**
81 * Class template @c can_prefer is a trait that is derived from
82 * @c true_type if the expression <tt>boost::asio::prefer(std::declval<T>(),
83 * std::declval<Properties>()...)</tt> is well formed; otherwise @c false_type.
84 */
85template <typename T, typename... Properties>
86struct can_prefer :
87 integral_constant<bool, automatically_determined>
88{
89};
90
91/// A type trait that determines whether a @c prefer expression will not throw.
92/**
93 * Class template @c is_nothrow_prefer is a trait that is derived from
94 * @c true_type if the expression <tt>boost::asio::prefer(std::declval<T>(),
95 * std::declval<Properties>()...)</tt> is @c noexcept; otherwise @c false_type.
96 */
97template <typename T, typename... Properties>
98struct is_nothrow_prefer :
99 integral_constant<bool, automatically_determined>
100{
101};
102
103/// A type trait that determines the result type of a @c prefer expression.
104/**
105 * Class template @c prefer_result is a trait that determines the result
106 * type of the expression <tt>boost::asio::prefer(std::declval<T>(),
107 * std::declval<Properties>()...)</tt>.
108 */
109template <typename T, typename... Properties>
110struct prefer_result
111{
112 /// The result of the @c prefer expression.
113 typedef automatically_determined type;
114};
115
116} // namespace asio
117} // namespace boost
118
119#else // defined(GENERATING_DOCUMENTATION)
120
121namespace asio_prefer_fn {
122
123using boost::asio::decay;
124using boost::asio::declval;
125using boost::asio::enable_if;
126using boost::asio::is_applicable_property;
127using boost::asio::traits::prefer_free;
128using boost::asio::traits::prefer_member;
129using boost::asio::traits::require_free;
130using boost::asio::traits::require_member;
131using boost::asio::traits::static_require;
132
133void prefer();
134void require();
135
136enum overload_type
137{
138 identity,
139 call_require_member,
140 call_require_free,
141 call_prefer_member,
142 call_prefer_free,
143 two_props,
144 n_props,
145 ill_formed
146};
147
148template <typename T, typename Properties, typename = void>
149struct call_traits
150{
151 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
152 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
153 typedef void result_type;
154};
155
156template <typename T, typename Property>
157struct call_traits<T, void(Property),
158 typename enable_if<
159 (
160 is_applicable_property<
161 typename decay<T>::type,
162 typename decay<Property>::type
163 >::value
164 &&
165 decay<Property>::type::is_preferable
166 &&
167 static_require<T, Property>::is_valid
168 )
169 >::type>
170{
171 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);
172 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
173
174#if defined(BOOST_ASIO_HAS_MOVE)
175 typedef BOOST_ASIO_MOVE_ARG(T) result_type;
176#else // defined(BOOST_ASIO_HAS_MOVE)
177 typedef BOOST_ASIO_MOVE_ARG(typename decay<T>::type) result_type;
178#endif // defined(BOOST_ASIO_HAS_MOVE)
179};
180
181template <typename T, typename Property>
182struct call_traits<T, void(Property),
183 typename enable_if<
184 (
185 is_applicable_property<
186 typename decay<T>::type,
187 typename decay<Property>::type
188 >::value
189 &&
190 decay<Property>::type::is_preferable
191 &&
192 !static_require<T, Property>::is_valid
193 &&
194 require_member<T, Property>::is_valid
195 )
196 >::type> :
197 require_member<T, Property>
198{
199 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_member);
200};
201
202template <typename T, typename Property>
203struct call_traits<T, void(Property),
204 typename enable_if<
205 (
206 is_applicable_property<
207 typename decay<T>::type,
208 typename decay<Property>::type
209 >::value
210 &&
211 decay<Property>::type::is_preferable
212 &&
213 !static_require<T, Property>::is_valid
214 &&
215 !require_member<T, Property>::is_valid
216 &&
217 require_free<T, Property>::is_valid
218 )
219 >::type> :
220 require_free<T, Property>
221{
222 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_free);
223};
224
225template <typename T, typename Property>
226struct call_traits<T, void(Property),
227 typename enable_if<
228 (
229 is_applicable_property<
230 typename decay<T>::type,
231 typename decay<Property>::type
232 >::value
233 &&
234 decay<Property>::type::is_preferable
235 &&
236 !static_require<T, Property>::is_valid
237 &&
238 !require_member<T, Property>::is_valid
239 &&
240 !require_free<T, Property>::is_valid
241 &&
242 prefer_member<T, Property>::is_valid
243 )
244 >::type> :
245 prefer_member<T, Property>
246{
247 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_member);
248};
249
250template <typename T, typename Property>
251struct call_traits<T, void(Property),
252 typename enable_if<
253 (
254 is_applicable_property<
255 typename decay<T>::type,
256 typename decay<Property>::type
257 >::value
258 &&
259 decay<Property>::type::is_preferable
260 &&
261 !static_require<T, Property>::is_valid
262 &&
263 !require_member<T, Property>::is_valid
264 &&
265 !require_free<T, Property>::is_valid
266 &&
267 !prefer_member<T, Property>::is_valid
268 &&
269 prefer_free<T, Property>::is_valid
270 )
271 >::type> :
272 prefer_free<T, Property>
273{
274 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_free);
275};
276
277template <typename T, typename Property>
278struct call_traits<T, void(Property),
279 typename enable_if<
280 (
281 is_applicable_property<
282 typename decay<T>::type,
283 typename decay<Property>::type
284 >::value
285 &&
286 decay<Property>::type::is_preferable
287 &&
288 !static_require<T, Property>::is_valid
289 &&
290 !require_member<T, Property>::is_valid
291 &&
292 !require_free<T, Property>::is_valid
293 &&
294 !prefer_member<T, Property>::is_valid
295 &&
296 !prefer_free<T, Property>::is_valid
297 )
298 >::type>
299{
300 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);
301 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
302
303#if defined(BOOST_ASIO_HAS_MOVE)
304 typedef BOOST_ASIO_MOVE_ARG(T) result_type;
305#else // defined(BOOST_ASIO_HAS_MOVE)
306 typedef BOOST_ASIO_MOVE_ARG(typename decay<T>::type) result_type;
307#endif // defined(BOOST_ASIO_HAS_MOVE)
308};
309
310template <typename T, typename P0, typename P1>
311struct call_traits<T, void(P0, P1),
312 typename enable_if<
313 call_traits<T, void(P0)>::overload != ill_formed
314 &&
315 call_traits<
316 typename call_traits<T, void(P0)>::result_type,
317 void(P1)
318 >::overload != ill_formed
319 >::type>
320{
321 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props);
322
323 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
324 (
325 call_traits<T, void(P0)>::is_noexcept
326 &&
327 call_traits<
328 typename call_traits<T, void(P0)>::result_type,
329 void(P1)
330 >::is_noexcept
331 ));
332
333 typedef typename decay<
334 typename call_traits<
335 typename call_traits<T, void(P0)>::result_type,
336 void(P1)
337 >::result_type
338 >::type result_type;
339};
340
341template <typename T, typename P0, typename P1, typename BOOST_ASIO_ELLIPSIS PN>
342struct call_traits<T, void(P0, P1, PN BOOST_ASIO_ELLIPSIS),
343 typename enable_if<
344 call_traits<T, void(P0)>::overload != ill_formed
345 &&
346 call_traits<
347 typename call_traits<T, void(P0)>::result_type,
348 void(P1, PN BOOST_ASIO_ELLIPSIS)
349 >::overload != ill_formed
350 >::type>
351{
352 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props);
353
354 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
355 (
356 call_traits<T, void(P0)>::is_noexcept
357 &&
358 call_traits<
359 typename call_traits<T, void(P0)>::result_type,
360 void(P1, PN BOOST_ASIO_ELLIPSIS)
361 >::is_noexcept
362 ));
363
364 typedef typename decay<
365 typename call_traits<
366 typename call_traits<T, void(P0)>::result_type,
367 void(P1, PN BOOST_ASIO_ELLIPSIS)
368 >::result_type
369 >::type result_type;
370};
371
372struct impl
373{
374 template <typename T, typename Property>
375 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
376 call_traits<T, void(Property)>::overload == identity,
377 typename call_traits<T, void(Property)>::result_type
378 >::type
379 operator()(
380 BOOST_ASIO_MOVE_ARG(T) t,
381 BOOST_ASIO_MOVE_ARG(Property)) const
382 BOOST_ASIO_NOEXCEPT_IF((
383 call_traits<T, void(Property)>::is_noexcept))
384 {
385 return BOOST_ASIO_MOVE_CAST(T)(t);
386 }
387
388 template <typename T, typename Property>
389 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
390 call_traits<T, void(Property)>::overload == call_require_member,
391 typename call_traits<T, void(Property)>::result_type
392 >::type
393 operator()(
394 BOOST_ASIO_MOVE_ARG(T) t,
395 BOOST_ASIO_MOVE_ARG(Property) p) const
396 BOOST_ASIO_NOEXCEPT_IF((
397 call_traits<T, void(Property)>::is_noexcept))
398 {
399 return BOOST_ASIO_MOVE_CAST(T)(t).require(
400 BOOST_ASIO_MOVE_CAST(Property)(p));
401 }
402
403 template <typename T, typename Property>
404 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
405 call_traits<T, void(Property)>::overload == call_require_free,
406 typename call_traits<T, void(Property)>::result_type
407 >::type
408 operator()(
409 BOOST_ASIO_MOVE_ARG(T) t,
410 BOOST_ASIO_MOVE_ARG(Property) p) const
411 BOOST_ASIO_NOEXCEPT_IF((
412 call_traits<T, void(Property)>::is_noexcept))
413 {
414 return require(
415 BOOST_ASIO_MOVE_CAST(T)(t),
416 BOOST_ASIO_MOVE_CAST(Property)(p));
417 }
418
419 template <typename T, typename Property>
420 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
421 call_traits<T, void(Property)>::overload == call_prefer_member,
422 typename call_traits<T, void(Property)>::result_type
423 >::type
424 operator()(
425 BOOST_ASIO_MOVE_ARG(T) t,
426 BOOST_ASIO_MOVE_ARG(Property) p) const
427 BOOST_ASIO_NOEXCEPT_IF((
428 call_traits<T, void(Property)>::is_noexcept))
429 {
430 return BOOST_ASIO_MOVE_CAST(T)(t).prefer(
431 BOOST_ASIO_MOVE_CAST(Property)(p));
432 }
433
434 template <typename T, typename Property>
435 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
436 call_traits<T, void(Property)>::overload == call_prefer_free,
437 typename call_traits<T, void(Property)>::result_type
438 >::type
439 operator()(
440 BOOST_ASIO_MOVE_ARG(T) t,
441 BOOST_ASIO_MOVE_ARG(Property) p) const
442 BOOST_ASIO_NOEXCEPT_IF((
443 call_traits<T, void(Property)>::is_noexcept))
444 {
445 return prefer(
446 BOOST_ASIO_MOVE_CAST(T)(t),
447 BOOST_ASIO_MOVE_CAST(Property)(p));
448 }
449
450 template <typename T, typename P0, typename P1>
451 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
452 call_traits<T, void(P0, P1)>::overload == two_props,
453 typename call_traits<T, void(P0, P1)>::result_type
454 >::type
455 operator()(
456 BOOST_ASIO_MOVE_ARG(T) t,
457 BOOST_ASIO_MOVE_ARG(P0) p0,
458 BOOST_ASIO_MOVE_ARG(P1) p1) const
459 BOOST_ASIO_NOEXCEPT_IF((
460 call_traits<T, void(P0, P1)>::is_noexcept))
461 {
462 return (*this)(
463 (*this)(
464 BOOST_ASIO_MOVE_CAST(T)(t),
465 BOOST_ASIO_MOVE_CAST(P0)(p0)),
466 BOOST_ASIO_MOVE_CAST(P1)(p1));
467 }
468
469 template <typename T, typename P0, typename P1,
470 typename BOOST_ASIO_ELLIPSIS PN>
471 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
472 call_traits<T, void(P0, P1, PN BOOST_ASIO_ELLIPSIS)>::overload == n_props,
473 typename call_traits<T, void(P0, P1, PN BOOST_ASIO_ELLIPSIS)>::result_type
474 >::type
475 operator()(
476 BOOST_ASIO_MOVE_ARG(T) t,
477 BOOST_ASIO_MOVE_ARG(P0) p0,
478 BOOST_ASIO_MOVE_ARG(P1) p1,
479 BOOST_ASIO_MOVE_ARG(PN) BOOST_ASIO_ELLIPSIS pn) const
480 BOOST_ASIO_NOEXCEPT_IF((
481 call_traits<T, void(P0, P1, PN BOOST_ASIO_ELLIPSIS)>::is_noexcept))
482 {
483 return (*this)(
484 (*this)(
485 BOOST_ASIO_MOVE_CAST(T)(t),
486 BOOST_ASIO_MOVE_CAST(P0)(p0)),
487 BOOST_ASIO_MOVE_CAST(P1)(p1),
488 BOOST_ASIO_MOVE_CAST(PN)(pn) BOOST_ASIO_ELLIPSIS);
489 }
490};
491
492template <typename T = impl>
493struct static_instance
494{
495 static const T instance;
496};
497
498template <typename T>
499const T static_instance<T>::instance = {};
500
501} // namespace asio_prefer_fn
502namespace boost {
503namespace asio {
504namespace {
505
506static BOOST_ASIO_CONSTEXPR const asio_prefer_fn::impl&
507 prefer = asio_prefer_fn::static_instance<>::instance;
508
509} // namespace
510
511#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
512
513template <typename T, typename... Properties>
514struct can_prefer :
515 integral_constant<bool,
516 asio_prefer_fn::call_traits<T, void(Properties...)>::overload
517 != asio_prefer_fn::ill_formed>
518{
519};
520
521#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
522
523template <typename T, typename P0 = void,
524 typename P1 = void, typename P2 = void>
525struct can_prefer :
526 integral_constant<bool,
527 asio_prefer_fn::call_traits<T, void(P0, P1, P2)>::overload
528 != asio_prefer_fn::ill_formed>
529{
530};
531
532template <typename T, typename P0, typename P1>
533struct can_prefer<T, P0, P1> :
534 integral_constant<bool,
535 asio_prefer_fn::call_traits<T, void(P0, P1)>::overload
536 != asio_prefer_fn::ill_formed>
537{
538};
539
540template <typename T, typename P0>
541struct can_prefer<T, P0> :
542 integral_constant<bool,
543 asio_prefer_fn::call_traits<T, void(P0)>::overload
544 != asio_prefer_fn::ill_formed>
545{
546};
547
548template <typename T>
549struct can_prefer<T> :
550 false_type
551{
552};
553
554#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
555
556#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
557
558template <typename T, typename BOOST_ASIO_ELLIPSIS Properties>
559constexpr bool can_prefer_v
560 = can_prefer<T, Properties BOOST_ASIO_ELLIPSIS>::value;
561
562#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
563
564#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
565
566template <typename T, typename... Properties>
567struct is_nothrow_prefer :
568 integral_constant<bool,
569 asio_prefer_fn::call_traits<T, void(Properties...)>::is_noexcept>
570{
571};
572
573#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
574
575template <typename T, typename P0 = void,
576 typename P1 = void, typename P2 = void>
577struct is_nothrow_prefer :
578 integral_constant<bool,
579 asio_prefer_fn::call_traits<T, void(P0, P1, P2)>::is_noexcept>
580{
581};
582
583template <typename T, typename P0, typename P1>
584struct is_nothrow_prefer<T, P0, P1> :
585 integral_constant<bool,
586 asio_prefer_fn::call_traits<T, void(P0, P1)>::is_noexcept>
587{
588};
589
590template <typename T, typename P0>
591struct is_nothrow_prefer<T, P0> :
592 integral_constant<bool,
593 asio_prefer_fn::call_traits<T, void(P0)>::is_noexcept>
594{
595};
596
597template <typename T>
598struct is_nothrow_prefer<T> :
599 false_type
600{
601};
602
603#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
604
605#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
606
607template <typename T, typename BOOST_ASIO_ELLIPSIS Properties>
608constexpr bool is_nothrow_prefer_v
609 = is_nothrow_prefer<T, Properties BOOST_ASIO_ELLIPSIS>::value;
610
611#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
612
613#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
614
615template <typename T, typename... Properties>
616struct prefer_result
617{
618 typedef typename asio_prefer_fn::call_traits<
619 T, void(Properties...)>::result_type type;
620};
621
622#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
623
624template <typename T, typename P0 = void,
625 typename P1 = void, typename P2 = void>
626struct prefer_result
627{
628 typedef typename asio_prefer_fn::call_traits<
629 T, void(P0, P1, P2)>::result_type type;
630};
631
632template <typename T, typename P0, typename P1>
633struct prefer_result<T, P0, P1>
634{
635 typedef typename asio_prefer_fn::call_traits<
636 T, void(P0, P1)>::result_type type;
637};
638
639template <typename T, typename P0>
640struct prefer_result<T, P0>
641{
642 typedef typename asio_prefer_fn::call_traits<
643 T, void(P0)>::result_type type;
644};
645
646template <typename T>
647struct prefer_result<T>
648{
649};
650
651#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
652
653} // namespace asio
654} // namespace boost
655
656#endif // defined(GENERATING_DOCUMENTATION)
657
658#include <boost/asio/detail/pop_options.hpp>
659
660#endif // BOOST_ASIO_PREFER_HPP