]>
Commit | Line | Data |
---|---|---|
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 | ||
31 | namespace boost { | |
32 | namespace 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 | */ | |
77 | inline 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 | */ | |
85 | template <typename T, typename... Properties> | |
86 | struct 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 | */ | |
97 | template <typename T, typename... Properties> | |
98 | struct 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 | */ | |
109 | template <typename T, typename... Properties> | |
110 | struct 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 | ||
121 | namespace asio_prefer_fn { | |
122 | ||
123 | using boost::asio::decay; | |
124 | using boost::asio::declval; | |
125 | using boost::asio::enable_if; | |
126 | using boost::asio::is_applicable_property; | |
127 | using boost::asio::traits::prefer_free; | |
128 | using boost::asio::traits::prefer_member; | |
129 | using boost::asio::traits::require_free; | |
130 | using boost::asio::traits::require_member; | |
131 | using boost::asio::traits::static_require; | |
132 | ||
133 | void prefer(); | |
134 | void require(); | |
135 | ||
136 | enum 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 | ||
148 | template <typename T, typename Properties, typename = void> | |
149 | struct 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 | ||
156 | template <typename T, typename Property> | |
157 | struct 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 | ||
181 | template <typename T, typename Property> | |
182 | struct 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 | ||
202 | template <typename T, typename Property> | |
203 | struct 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 | ||
225 | template <typename T, typename Property> | |
226 | struct 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 | ||
250 | template <typename T, typename Property> | |
251 | struct 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 | ||
277 | template <typename T, typename Property> | |
278 | struct 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 | ||
310 | template <typename T, typename P0, typename P1> | |
311 | struct 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 | ||
341 | template <typename T, typename P0, typename P1, typename BOOST_ASIO_ELLIPSIS PN> | |
342 | struct 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 | ||
372 | struct 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 | ||
492 | template <typename T = impl> | |
493 | struct static_instance | |
494 | { | |
495 | static const T instance; | |
496 | }; | |
497 | ||
498 | template <typename T> | |
499 | const T static_instance<T>::instance = {}; | |
500 | ||
501 | } // namespace asio_prefer_fn | |
502 | namespace boost { | |
503 | namespace asio { | |
504 | namespace { | |
505 | ||
506 | static 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 | ||
513 | template <typename T, typename... Properties> | |
514 | struct 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 | ||
523 | template <typename T, typename P0 = void, | |
524 | typename P1 = void, typename P2 = void> | |
525 | struct 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 | ||
532 | template <typename T, typename P0, typename P1> | |
533 | struct 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 | ||
540 | template <typename T, typename P0> | |
541 | struct 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 | ||
548 | template <typename T> | |
549 | struct 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 | ||
558 | template <typename T, typename BOOST_ASIO_ELLIPSIS Properties> | |
559 | constexpr 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 | ||
566 | template <typename T, typename... Properties> | |
567 | struct 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 | ||
575 | template <typename T, typename P0 = void, | |
576 | typename P1 = void, typename P2 = void> | |
577 | struct is_nothrow_prefer : | |
578 | integral_constant<bool, | |
579 | asio_prefer_fn::call_traits<T, void(P0, P1, P2)>::is_noexcept> | |
580 | { | |
581 | }; | |
582 | ||
583 | template <typename T, typename P0, typename P1> | |
584 | struct 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 | ||
590 | template <typename T, typename P0> | |
591 | struct is_nothrow_prefer<T, P0> : | |
592 | integral_constant<bool, | |
593 | asio_prefer_fn::call_traits<T, void(P0)>::is_noexcept> | |
594 | { | |
595 | }; | |
596 | ||
597 | template <typename T> | |
598 | struct 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 | ||
607 | template <typename T, typename BOOST_ASIO_ELLIPSIS Properties> | |
608 | constexpr 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 | ||
615 | template <typename T, typename... Properties> | |
616 | struct 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 | ||
624 | template <typename T, typename P0 = void, | |
625 | typename P1 = void, typename P2 = void> | |
626 | struct prefer_result | |
627 | { | |
628 | typedef typename asio_prefer_fn::call_traits< | |
629 | T, void(P0, P1, P2)>::result_type type; | |
630 | }; | |
631 | ||
632 | template <typename T, typename P0, typename P1> | |
633 | struct prefer_result<T, P0, P1> | |
634 | { | |
635 | typedef typename asio_prefer_fn::call_traits< | |
636 | T, void(P0, P1)>::result_type type; | |
637 | }; | |
638 | ||
639 | template <typename T, typename P0> | |
640 | struct prefer_result<T, P0> | |
641 | { | |
642 | typedef typename asio_prefer_fn::call_traits< | |
643 | T, void(P0)>::result_type type; | |
644 | }; | |
645 | ||
646 | template <typename T> | |
647 | struct 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 |