Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:10

0001 //
0002 // prefer.hpp
0003 // ~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_PREFER_HPP
0012 #define BOOST_ASIO_PREFER_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/type_traits.hpp>
0020 #include <boost/asio/is_applicable_property.hpp>
0021 #include <boost/asio/traits/prefer_free.hpp>
0022 #include <boost/asio/traits/prefer_member.hpp>
0023 #include <boost/asio/traits/require_free.hpp>
0024 #include <boost/asio/traits/require_member.hpp>
0025 #include <boost/asio/traits/static_require.hpp>
0026 
0027 #include <boost/asio/detail/push_options.hpp>
0028 
0029 #if defined(GENERATING_DOCUMENTATION)
0030 
0031 namespace boost {
0032 namespace asio {
0033 
0034 /// A customisation point that attempts to apply a property to an object.
0035 /**
0036  * The name <tt>prefer</tt> denotes a customisation point object. The
0037  * expression <tt>boost::asio::prefer(E, P0, Pn...)</tt> for some subexpressions
0038  * <tt>E</tt> and <tt>P0</tt>, and where <tt>Pn...</tt> represents <tt>N</tt>
0039  * subexpressions (where <tt>N</tt> is 0 or more, and with types <tt>T =
0040  * decay_t<decltype(E)></tt> and <tt>Prop0 = decay_t<decltype(P0)></tt>) is
0041  * expression-equivalent to:
0042  *
0043  * @li If <tt>is_applicable_property_v<T, Prop0> && Prop0::is_preferable</tt> is
0044  *   not a well-formed constant expression with value <tt>true</tt>,
0045  *   <tt>boost::asio::prefer(E, P0, Pn...)</tt> is ill-formed.
0046  *
0047  * @li Otherwise, <tt>E</tt> if <tt>N == 0</tt> and the expression
0048  *   <tt>Prop0::template static_query_v<T> == Prop0::value()</tt> is a
0049  *   well-formed constant expression with value <tt>true</tt>.
0050  *
0051  * @li Otherwise, <tt>(E).require(P0)</tt> if <tt>N == 0</tt> and the expression
0052  *   <tt>(E).require(P0)</tt> is a valid expression.
0053  *
0054  * @li Otherwise, <tt>require(E, P0)</tt> if <tt>N == 0</tt> and the expression
0055  *   <tt>require(E, P0)</tt> is a valid expression with overload resolution
0056  *   performed in a context that does not include the declaration of the
0057  *   <tt>require</tt> customization point object.
0058  *
0059  * @li Otherwise, <tt>(E).prefer(P0)</tt> if <tt>N == 0</tt> and the expression
0060  *   <tt>(E).prefer(P0)</tt> is a valid expression.
0061  *
0062  * @li Otherwise, <tt>prefer(E, P0)</tt> if <tt>N == 0</tt> and the expression
0063  *   <tt>prefer(E, P0)</tt> is a valid expression with overload resolution
0064  *   performed in a context that does not include the declaration of the
0065  *   <tt>prefer</tt> customization point object.
0066  *
0067  * @li Otherwise, <tt>E</tt> if <tt>N == 0</tt>.
0068  *
0069  * @li Otherwise,
0070  *   <tt>boost::asio::prefer(boost::asio::prefer(E, P0), Pn...)</tt>
0071  *   if <tt>N > 0</tt> and the expression
0072  *   <tt>boost::asio::prefer(boost::asio::prefer(E, P0), Pn...)</tt>
0073  *   is a valid expression.
0074  *
0075  * @li Otherwise, <tt>boost::asio::prefer(E, P0, Pn...)</tt> is ill-formed.
0076  */
0077 inline constexpr unspecified prefer = unspecified;
0078 
0079 /// A type trait that determines whether a @c prefer expression is well-formed.
0080 /**
0081  * Class template @c can_prefer is a trait that is derived from
0082  * @c true_type if the expression <tt>boost::asio::prefer(std::declval<T>(),
0083  * std::declval<Properties>()...)</tt> is well formed; otherwise @c false_type.
0084  */
0085 template <typename T, typename... Properties>
0086 struct can_prefer :
0087   integral_constant<bool, automatically_determined>
0088 {
0089 };
0090 
0091 /// A type trait that determines whether a @c prefer expression will not throw.
0092 /**
0093  * Class template @c is_nothrow_prefer is a trait that is derived from
0094  * @c true_type if the expression <tt>boost::asio::prefer(std::declval<T>(),
0095  * std::declval<Properties>()...)</tt> is @c noexcept; otherwise @c false_type.
0096  */
0097 template <typename T, typename... Properties>
0098 struct is_nothrow_prefer :
0099   integral_constant<bool, automatically_determined>
0100 {
0101 };
0102 
0103 /// A type trait that determines the result type of a @c prefer expression.
0104 /**
0105  * Class template @c prefer_result is a trait that determines the result
0106  * type of the expression <tt>boost::asio::prefer(std::declval<T>(),
0107  * std::declval<Properties>()...)</tt>.
0108  */
0109 template <typename T, typename... Properties>
0110 struct prefer_result
0111 {
0112   /// The result of the @c prefer expression.
0113   typedef automatically_determined type;
0114 };
0115 
0116 } // namespace asio
0117 } // namespace boost
0118 
0119 #else // defined(GENERATING_DOCUMENTATION)
0120 
0121 namespace boost_asio_prefer_fn {
0122 
0123 using boost::asio::conditional_t;
0124 using boost::asio::decay_t;
0125 using boost::asio::declval;
0126 using boost::asio::enable_if_t;
0127 using boost::asio::is_applicable_property;
0128 using boost::asio::traits::prefer_free;
0129 using boost::asio::traits::prefer_member;
0130 using boost::asio::traits::require_free;
0131 using boost::asio::traits::require_member;
0132 using boost::asio::traits::static_require;
0133 
0134 void prefer();
0135 void require();
0136 
0137 enum overload_type
0138 {
0139   identity,
0140   call_require_member,
0141   call_require_free,
0142   call_prefer_member,
0143   call_prefer_free,
0144   two_props,
0145   n_props,
0146   ill_formed
0147 };
0148 
0149 template <typename Impl, typename T, typename Properties,
0150     typename = void, typename = void, typename = void, typename = void,
0151     typename = void, typename = void, typename = void>
0152 struct call_traits
0153 {
0154   static constexpr overload_type overload = ill_formed;
0155   static constexpr bool is_noexcept = false;
0156   typedef void result_type;
0157 };
0158 
0159 template <typename Impl, typename T, typename Property>
0160 struct call_traits<Impl, T, void(Property),
0161   enable_if_t<
0162     is_applicable_property<
0163       decay_t<T>,
0164       decay_t<Property>
0165     >::value
0166   >,
0167   enable_if_t<
0168     decay_t<Property>::is_preferable
0169   >,
0170   enable_if_t<
0171     static_require<T, Property>::is_valid
0172   >>
0173 {
0174   static constexpr overload_type overload = identity;
0175   static constexpr bool is_noexcept = true;
0176 
0177   typedef T&& result_type;
0178 };
0179 
0180 template <typename Impl, typename T, typename Property>
0181 struct call_traits<Impl, T, void(Property),
0182   enable_if_t<
0183     is_applicable_property<
0184       decay_t<T>,
0185       decay_t<Property>
0186     >::value
0187   >,
0188   enable_if_t<
0189     decay_t<Property>::is_preferable
0190   >,
0191   enable_if_t<
0192     !static_require<T, Property>::is_valid
0193   >,
0194   enable_if_t<
0195     require_member<typename Impl::template proxy<T>::type, Property>::is_valid
0196   >> :
0197   require_member<typename Impl::template proxy<T>::type, Property>
0198 {
0199   static constexpr overload_type overload = call_require_member;
0200 };
0201 
0202 template <typename Impl, typename T, typename Property>
0203 struct call_traits<Impl, T, void(Property),
0204   enable_if_t<
0205     is_applicable_property<
0206       decay_t<T>,
0207       decay_t<Property>
0208     >::value
0209   >,
0210   enable_if_t<
0211     decay_t<Property>::is_preferable
0212   >,
0213   enable_if_t<
0214     !static_require<T, Property>::is_valid
0215   >,
0216   enable_if_t<
0217     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid
0218   >,
0219   enable_if_t<
0220     require_free<T, Property>::is_valid
0221   >> :
0222   require_free<T, Property>
0223 {
0224   static constexpr overload_type overload = call_require_free;
0225 };
0226 
0227 template <typename Impl, typename T, typename Property>
0228 struct call_traits<Impl, T, void(Property),
0229   enable_if_t<
0230     is_applicable_property<
0231       decay_t<T>,
0232       decay_t<Property>
0233     >::value
0234   >,
0235   enable_if_t<
0236     decay_t<Property>::is_preferable
0237   >,
0238   enable_if_t<
0239     !static_require<T, Property>::is_valid
0240   >,
0241   enable_if_t<
0242     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid
0243   >,
0244   enable_if_t<
0245     !require_free<T, Property>::is_valid
0246   >,
0247   enable_if_t<
0248     prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid
0249   >> :
0250   prefer_member<typename Impl::template proxy<T>::type, Property>
0251 {
0252   static constexpr overload_type overload = call_prefer_member;
0253 };
0254 
0255 template <typename Impl, typename T, typename Property>
0256 struct call_traits<Impl, T, void(Property),
0257   enable_if_t<
0258     is_applicable_property<
0259       decay_t<T>,
0260       decay_t<Property>
0261     >::value
0262   >,
0263   enable_if_t<
0264     decay_t<Property>::is_preferable
0265   >,
0266   enable_if_t<
0267     !static_require<T, Property>::is_valid
0268   >,
0269   enable_if_t<
0270     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid
0271   >,
0272   enable_if_t<
0273     !require_free<T, Property>::is_valid
0274   >,
0275   enable_if_t<
0276     !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid
0277   >,
0278   enable_if_t<
0279     prefer_free<T, Property>::is_valid
0280   >> :
0281   prefer_free<T, Property>
0282 {
0283   static constexpr overload_type overload = call_prefer_free;
0284 };
0285 
0286 template <typename Impl, typename T, typename Property>
0287 struct call_traits<Impl, T, void(Property),
0288   enable_if_t<
0289     is_applicable_property<
0290       decay_t<T>,
0291       decay_t<Property>
0292     >::value
0293   >,
0294   enable_if_t<
0295     decay_t<Property>::is_preferable
0296   >,
0297   enable_if_t<
0298     !static_require<T, Property>::is_valid
0299   >,
0300   enable_if_t<
0301     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid
0302   >,
0303   enable_if_t<
0304     !require_free<T, Property>::is_valid
0305   >,
0306   enable_if_t<
0307     !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid
0308   >,
0309   enable_if_t<
0310     !prefer_free<T, Property>::is_valid
0311   >>
0312 {
0313   static constexpr overload_type overload = identity;
0314   static constexpr bool is_noexcept = true;
0315 
0316   typedef T&& result_type;
0317 };
0318 
0319 template <typename Impl, typename T, typename P0, typename P1>
0320 struct call_traits<Impl, T, void(P0, P1),
0321   enable_if_t<
0322     call_traits<Impl, T, void(P0)>::overload != ill_formed
0323   >,
0324   enable_if_t<
0325     call_traits<
0326       Impl,
0327       typename call_traits<Impl, T, void(P0)>::result_type,
0328       void(P1)
0329     >::overload != ill_formed
0330   >>
0331 {
0332   static constexpr overload_type overload = two_props;
0333 
0334   static constexpr bool is_noexcept =
0335     (
0336       call_traits<Impl, T, void(P0)>::is_noexcept
0337       &&
0338       call_traits<
0339         Impl,
0340         typename call_traits<Impl, T, void(P0)>::result_type,
0341         void(P1)
0342       >::is_noexcept
0343     );
0344 
0345   typedef decay_t<
0346     typename call_traits<
0347       Impl,
0348       typename call_traits<Impl, T, void(P0)>::result_type,
0349       void(P1)
0350     >::result_type
0351   > result_type;
0352 };
0353 
0354 template <typename Impl, typename T, typename P0,
0355     typename P1, typename... PN>
0356 struct call_traits<Impl, T, void(P0, P1, PN...),
0357   enable_if_t<
0358     call_traits<Impl, T, void(P0)>::overload != ill_formed
0359   >,
0360   enable_if_t<
0361     call_traits<
0362       Impl,
0363       typename call_traits<Impl, T, void(P0)>::result_type,
0364       void(P1, PN...)
0365     >::overload != ill_formed
0366   >>
0367 {
0368   static constexpr overload_type overload = n_props;
0369 
0370   static constexpr bool is_noexcept =
0371     (
0372       call_traits<Impl, T, void(P0)>::is_noexcept
0373       &&
0374       call_traits<
0375         Impl,
0376         typename call_traits<Impl, T, void(P0)>::result_type,
0377         void(P1, PN...)
0378       >::is_noexcept
0379     );
0380 
0381   typedef decay_t<
0382     typename call_traits<
0383       Impl,
0384       typename call_traits<Impl, T, void(P0)>::result_type,
0385       void(P1, PN...)
0386     >::result_type
0387   > result_type;
0388 };
0389 
0390 struct impl
0391 {
0392   template <typename T>
0393   struct proxy
0394   {
0395 #if defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) \
0396   && defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
0397     struct type
0398     {
0399       template <typename P>
0400       auto require(P&& p)
0401         noexcept(
0402           noexcept(
0403             declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))
0404           )
0405         )
0406         -> decltype(
0407           declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))
0408         );
0409 
0410       template <typename P>
0411       auto prefer(P&& p)
0412         noexcept(
0413           noexcept(
0414             declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p))
0415           )
0416         )
0417         -> decltype(
0418           declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p))
0419         );
0420     };
0421 #else // defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
0422       //   && defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
0423     typedef T type;
0424 #endif // defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
0425        //   && defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
0426   };
0427 
0428   template <typename T, typename Property>
0429   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0430     call_traits<impl, T, void(Property)>::overload == identity,
0431     typename call_traits<impl, T, void(Property)>::result_type
0432   >
0433   operator()(T&& t, Property&&) const
0434     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0435   {
0436     return static_cast<T&&>(t);
0437   }
0438 
0439   template <typename T, typename Property>
0440   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0441     call_traits<impl, T, void(Property)>::overload == call_require_member,
0442     typename call_traits<impl, T, void(Property)>::result_type
0443   >
0444   operator()(T&& t, Property&& p) const
0445     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0446   {
0447     return static_cast<T&&>(t).require(static_cast<Property&&>(p));
0448   }
0449 
0450   template <typename T, typename Property>
0451   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0452     call_traits<impl, T, void(Property)>::overload == call_require_free,
0453     typename call_traits<impl, T, void(Property)>::result_type
0454   >
0455   operator()(T&& t, Property&& p) const
0456     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0457   {
0458     return require(static_cast<T&&>(t), static_cast<Property&&>(p));
0459   }
0460 
0461   template <typename T, typename Property>
0462   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0463     call_traits<impl, T, void(Property)>::overload == call_prefer_member,
0464     typename call_traits<impl, T, void(Property)>::result_type
0465   >
0466   operator()(T&& t, Property&& p) const
0467     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0468   {
0469     return static_cast<T&&>(t).prefer(static_cast<Property&&>(p));
0470   }
0471 
0472   template <typename T, typename Property>
0473   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0474     call_traits<impl, T, void(Property)>::overload == call_prefer_free,
0475     typename call_traits<impl, T, void(Property)>::result_type
0476   >
0477   operator()(T&& t, Property&& p) const
0478     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0479   {
0480     return prefer(static_cast<T&&>(t), static_cast<Property&&>(p));
0481   }
0482 
0483   template <typename T, typename P0, typename P1>
0484   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0485     call_traits<impl, T, void(P0, P1)>::overload == two_props,
0486     typename call_traits<impl, T, void(P0, P1)>::result_type
0487   >
0488   operator()(T&& t, P0&& p0, P1&& p1) const
0489     noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept)
0490   {
0491     return (*this)(
0492         (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),
0493         static_cast<P1&&>(p1));
0494   }
0495 
0496   template <typename T, typename P0, typename P1,
0497     typename... PN>
0498   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0499     call_traits<impl, T, void(P0, P1, PN...)>::overload == n_props,
0500     typename call_traits<impl, T, void(P0, P1, PN...)>::result_type
0501   >
0502   operator()(T&& t, P0&& p0, P1&& p1, PN&&... pn) const
0503     noexcept(call_traits<impl, T, void(P0, P1, PN...)>::is_noexcept)
0504   {
0505     return (*this)(
0506         (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),
0507         static_cast<P1&&>(p1), static_cast<PN&&>(pn)...);
0508   }
0509 };
0510 
0511 template <typename T = impl>
0512 struct static_instance
0513 {
0514   static const T instance;
0515 };
0516 
0517 template <typename T>
0518 const T static_instance<T>::instance = {};
0519 
0520 } // namespace boost_asio_prefer_fn
0521 namespace boost {
0522 namespace asio {
0523 namespace {
0524 
0525 static constexpr const boost_asio_prefer_fn::impl&
0526   prefer = boost_asio_prefer_fn::static_instance<>::instance;
0527 
0528 } // namespace
0529 
0530 typedef boost_asio_prefer_fn::impl prefer_t;
0531 
0532 template <typename T, typename... Properties>
0533 struct can_prefer :
0534   integral_constant<bool,
0535     boost_asio_prefer_fn::call_traits<
0536       prefer_t, T, void(Properties...)>::overload
0537         != boost_asio_prefer_fn::ill_formed>
0538 {
0539 };
0540 
0541 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0542 
0543 template <typename T, typename... Properties>
0544 constexpr bool can_prefer_v
0545   = can_prefer<T, Properties...>::value;
0546 
0547 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0548 
0549 template <typename T, typename... Properties>
0550 struct is_nothrow_prefer :
0551   integral_constant<bool,
0552     boost_asio_prefer_fn::call_traits<
0553       prefer_t, T, void(Properties...)>::is_noexcept>
0554 {
0555 };
0556 
0557 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0558 
0559 template <typename T, typename... Properties>
0560 constexpr bool is_nothrow_prefer_v = is_nothrow_prefer<T, Properties...>::value;
0561 
0562 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0563 
0564 template <typename T, typename... Properties>
0565 struct prefer_result
0566 {
0567   typedef typename boost_asio_prefer_fn::call_traits<
0568       prefer_t, T, void(Properties...)>::result_type type;
0569 };
0570 
0571 template <typename T, typename... Properties>
0572 using prefer_result_t = typename prefer_result<T, Properties...>::type;
0573 
0574 } // namespace asio
0575 } // namespace boost
0576 
0577 #endif // defined(GENERATING_DOCUMENTATION)
0578 
0579 #include <boost/asio/detail/pop_options.hpp>
0580 
0581 #endif // BOOST_ASIO_PREFER_HPP