prefer.hpp 21 KB

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