Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // require.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_REQUIRE_HPP
0012 #define BOOST_ASIO_REQUIRE_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/require_member.hpp>
0022 #include <boost/asio/traits/require_free.hpp>
0023 #include <boost/asio/traits/static_require.hpp>
0024 
0025 #include <boost/asio/detail/push_options.hpp>
0026 
0027 #if defined(GENERATING_DOCUMENTATION)
0028 
0029 namespace boost {
0030 namespace asio {
0031 
0032 /// A customisation point that applies a concept-preserving property to an
0033 /// object.
0034 /**
0035  * The name <tt>require</tt> denotes a customisation point object. The
0036  * expression <tt>boost::asio::require(E, P0, Pn...)</tt> for some
0037  * subexpressions <tt>E</tt> and <tt>P0</tt>, and where <tt>Pn...</tt>
0038  * represents <tt>N</tt> subexpressions (where <tt>N</tt> is 0 or more, and with
0039  * types <tt>T = decay_t<decltype(E)></tt> and <tt>Prop0 =
0040  * decay_t<decltype(P0)></tt>) is expression-equivalent to:
0041  *
0042  * @li If <tt>is_applicable_property_v<T, Prop0> && Prop0::is_requirable</tt> is
0043  *   not a well-formed constant expression with value <tt>true</tt>,
0044  *   <tt>boost::asio::require(E, P0, Pn...)</tt> is ill-formed.
0045  *
0046  * @li Otherwise, <tt>E</tt> if <tt>N == 0</tt> and the expression
0047  *   <tt>Prop0::template static_query_v<T> == Prop0::value()</tt> is a
0048  *   well-formed constant expression with value <tt>true</tt>.
0049  *
0050  * @li Otherwise, <tt>(E).require(P0)</tt> if <tt>N == 0</tt> and the expression
0051  *   <tt>(E).require(P0)</tt> is a valid expression.
0052  *
0053  * @li Otherwise, <tt>require(E, P0)</tt> if <tt>N == 0</tt> and the expression
0054  *   <tt>require(E, P0)</tt> is a valid expression with overload resolution
0055  *   performed in a context that does not include the declaration of the
0056  *   <tt>require</tt> customization point object.
0057  *
0058  * @li Otherwise,
0059  *   <tt>boost::asio::require(boost::asio::require(E, P0), Pn...)</tt>
0060  *   if <tt>N > 0</tt> and the expression
0061  *   <tt>boost::asio::require(boost::asio::require(E, P0), Pn...)</tt>
0062  *   is a valid expression.
0063  *
0064  * @li Otherwise, <tt>boost::asio::require(E, P0, Pn...)</tt> is ill-formed.
0065  */
0066 inline constexpr unspecified require = unspecified;
0067 
0068 /// A type trait that determines whether a @c require expression is well-formed.
0069 /**
0070  * Class template @c can_require is a trait that is derived from
0071  * @c true_type if the expression <tt>boost::asio::require(std::declval<T>(),
0072  * std::declval<Properties>()...)</tt> is well formed; otherwise @c false_type.
0073  */
0074 template <typename T, typename... Properties>
0075 struct can_require :
0076   integral_constant<bool, automatically_determined>
0077 {
0078 };
0079 
0080 /// A type trait that determines whether a @c require expression will not throw.
0081 /**
0082  * Class template @c is_nothrow_require is a trait that is derived from
0083  * @c true_type if the expression <tt>boost::asio::require(std::declval<T>(),
0084  * std::declval<Properties>()...)</tt> is @c noexcept; otherwise @c false_type.
0085  */
0086 template <typename T, typename... Properties>
0087 struct is_nothrow_require :
0088   integral_constant<bool, automatically_determined>
0089 {
0090 };
0091 
0092 /// A type trait that determines the result type of a @c require expression.
0093 /**
0094  * Class template @c require_result is a trait that determines the result
0095  * type of the expression <tt>boost::asio::require(std::declval<T>(),
0096  * std::declval<Properties>()...)</tt>.
0097  */
0098 template <typename T, typename... Properties>
0099 struct require_result
0100 {
0101   /// The result of the @c require expression.
0102   typedef automatically_determined type;
0103 };
0104 
0105 } // namespace asio
0106 } // namespace boost
0107 
0108 #else // defined(GENERATING_DOCUMENTATION)
0109 
0110 namespace boost_asio_require_fn {
0111 
0112 using boost::asio::conditional_t;
0113 using boost::asio::decay_t;
0114 using boost::asio::declval;
0115 using boost::asio::enable_if_t;
0116 using boost::asio::is_applicable_property;
0117 using boost::asio::traits::require_free;
0118 using boost::asio::traits::require_member;
0119 using boost::asio::traits::static_require;
0120 
0121 void require();
0122 
0123 enum overload_type
0124 {
0125   identity,
0126   call_member,
0127   call_free,
0128   two_props,
0129   n_props,
0130   ill_formed
0131 };
0132 
0133 template <typename Impl, typename T, typename Properties, typename = void,
0134     typename = void, typename = void, typename = void, typename = void>
0135 struct call_traits
0136 {
0137   static constexpr overload_type overload = ill_formed;
0138   static constexpr bool is_noexcept = false;
0139   typedef void result_type;
0140 };
0141 
0142 template <typename Impl, typename T, typename Property>
0143 struct call_traits<Impl, T, void(Property),
0144   enable_if_t<
0145     is_applicable_property<
0146       decay_t<T>,
0147       decay_t<Property>
0148     >::value
0149   >,
0150   enable_if_t<
0151     decay_t<Property>::is_requirable
0152   >,
0153   enable_if_t<
0154     static_require<T, Property>::is_valid
0155   >>
0156 {
0157   static constexpr overload_type overload = identity;
0158   static constexpr bool is_noexcept = true;
0159 
0160   typedef T&& result_type;
0161 };
0162 
0163 template <typename Impl, typename T, typename Property>
0164 struct call_traits<Impl, T, void(Property),
0165   enable_if_t<
0166     is_applicable_property<
0167       decay_t<T>,
0168       decay_t<Property>
0169     >::value
0170   >,
0171   enable_if_t<
0172     decay_t<Property>::is_requirable
0173   >,
0174   enable_if_t<
0175     !static_require<T, Property>::is_valid
0176   >,
0177   enable_if_t<
0178     require_member<typename Impl::template proxy<T>::type, Property>::is_valid
0179   >> :
0180   require_member<typename Impl::template proxy<T>::type, Property>
0181 {
0182   static constexpr overload_type overload = call_member;
0183 };
0184 
0185 template <typename Impl, typename T, typename Property>
0186 struct call_traits<Impl, T, void(Property),
0187   enable_if_t<
0188     is_applicable_property<
0189       decay_t<T>,
0190       decay_t<Property>
0191     >::value
0192   >,
0193   enable_if_t<
0194     decay_t<Property>::is_requirable
0195   >,
0196   enable_if_t<
0197     !static_require<T, Property>::is_valid
0198   >,
0199   enable_if_t<
0200     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid
0201   >,
0202   enable_if_t<
0203     require_free<T, Property>::is_valid
0204   >> :
0205   require_free<T, Property>
0206 {
0207   static constexpr overload_type overload = call_free;
0208 };
0209 
0210 template <typename Impl, typename T, typename P0, typename P1>
0211 struct call_traits<Impl, T, void(P0, P1),
0212   enable_if_t<
0213     call_traits<Impl, T, void(P0)>::overload != ill_formed
0214   >,
0215   enable_if_t<
0216     call_traits<
0217       Impl,
0218       typename call_traits<Impl, T, void(P0)>::result_type,
0219       void(P1)
0220     >::overload != ill_formed
0221   >>
0222 {
0223   static constexpr overload_type overload = two_props;
0224 
0225   static constexpr bool is_noexcept =
0226     (
0227       call_traits<Impl, T, void(P0)>::is_noexcept
0228       &&
0229       call_traits<
0230         Impl,
0231         typename call_traits<Impl, T, void(P0)>::result_type,
0232         void(P1)
0233       >::is_noexcept
0234     );
0235 
0236   typedef decay_t<
0237     typename call_traits<
0238       Impl,
0239       typename call_traits<Impl, T, void(P0)>::result_type,
0240       void(P1)
0241     >::result_type
0242   > result_type;
0243 };
0244 
0245 template <typename Impl, typename T, typename P0,
0246     typename P1, typename... PN>
0247 struct call_traits<Impl, T, void(P0, P1, PN...),
0248   enable_if_t<
0249     call_traits<Impl, T, void(P0)>::overload != ill_formed
0250   >,
0251   enable_if_t<
0252     call_traits<
0253       Impl,
0254       typename call_traits<Impl, T, void(P0)>::result_type,
0255       void(P1, PN...)
0256     >::overload != ill_formed
0257   >>
0258 {
0259   static constexpr overload_type overload = n_props;
0260 
0261   static constexpr bool is_noexcept =
0262     (
0263       call_traits<Impl, T, void(P0)>::is_noexcept
0264       &&
0265       call_traits<
0266         Impl,
0267         typename call_traits<Impl, T, void(P0)>::result_type,
0268         void(P1, PN...)
0269       >::is_noexcept
0270     );
0271 
0272   typedef decay_t<
0273     typename call_traits<
0274       Impl,
0275       typename call_traits<Impl, T, void(P0)>::result_type,
0276       void(P1, PN...)
0277     >::result_type
0278   > result_type;
0279 };
0280 
0281 struct impl
0282 {
0283   template <typename T>
0284   struct proxy
0285   {
0286 #if defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
0287     struct type
0288     {
0289       template <typename P>
0290       auto require(P&& p)
0291         noexcept(
0292           noexcept(
0293             declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))
0294           )
0295         )
0296         -> decltype(
0297           declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))
0298         );
0299     };
0300 #else // defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
0301     typedef T type;
0302 #endif // defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
0303   };
0304 
0305   template <typename T, typename Property>
0306   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0307     call_traits<impl, T, void(Property)>::overload == identity,
0308     typename call_traits<impl, T, void(Property)>::result_type
0309   >
0310   operator()(T&& t, Property&&) const
0311     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0312   {
0313     return static_cast<T&&>(t);
0314   }
0315 
0316   template <typename T, typename Property>
0317   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0318     call_traits<impl, T, void(Property)>::overload == call_member,
0319     typename call_traits<impl, T, void(Property)>::result_type
0320   >
0321   operator()(T&& t, Property&& p) const
0322     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0323   {
0324     return static_cast<T&&>(t).require(static_cast<Property&&>(p));
0325   }
0326 
0327   template <typename T, typename Property>
0328   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0329     call_traits<impl, T, void(Property)>::overload == call_free,
0330     typename call_traits<impl, T, void(Property)>::result_type
0331   >
0332   operator()(T&& t, Property&& p) const
0333     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0334   {
0335     return require(static_cast<T&&>(t), static_cast<Property&&>(p));
0336   }
0337 
0338   template <typename T, typename P0, typename P1>
0339   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0340     call_traits<impl, T, void(P0, P1)>::overload == two_props,
0341     typename call_traits<impl, T, void(P0, P1)>::result_type
0342   >
0343   operator()(T&& t, P0&& p0, P1&& p1) const
0344     noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept)
0345   {
0346     return (*this)(
0347         (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),
0348         static_cast<P1&&>(p1));
0349   }
0350 
0351   template <typename T, typename P0, typename P1,
0352     typename... PN>
0353   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0354     call_traits<impl, T, void(P0, P1, PN...)>::overload == n_props,
0355     typename call_traits<impl, T, void(P0, P1, PN...)>::result_type
0356   >
0357   operator()(T&& t, P0&& p0, P1&& p1, PN&&... pn) const
0358     noexcept(call_traits<impl, T, void(P0, P1, PN...)>::is_noexcept)
0359   {
0360     return (*this)(
0361         (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),
0362         static_cast<P1&&>(p1), static_cast<PN&&>(pn)...);
0363   }
0364 };
0365 
0366 template <typename T = impl>
0367 struct static_instance
0368 {
0369   static const T instance;
0370 };
0371 
0372 template <typename T>
0373 const T static_instance<T>::instance = {};
0374 
0375 } // namespace boost_asio_require_fn
0376 namespace boost {
0377 namespace asio {
0378 namespace {
0379 
0380 static constexpr const boost_asio_require_fn::impl&
0381   require = boost_asio_require_fn::static_instance<>::instance;
0382 
0383 } // namespace
0384 
0385 typedef boost_asio_require_fn::impl require_t;
0386 
0387 template <typename T, typename... Properties>
0388 struct can_require :
0389   integral_constant<bool,
0390     boost_asio_require_fn::call_traits<
0391       require_t, T, void(Properties...)>::overload
0392         != boost_asio_require_fn::ill_formed>
0393 {
0394 };
0395 
0396 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0397 
0398 template <typename T, typename... Properties>
0399 constexpr bool can_require_v
0400   = can_require<T, Properties...>::value;
0401 
0402 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0403 
0404 template <typename T, typename... Properties>
0405 struct is_nothrow_require :
0406   integral_constant<bool,
0407     boost_asio_require_fn::call_traits<
0408       require_t, T, void(Properties...)>::is_noexcept>
0409 {
0410 };
0411 
0412 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0413 
0414 template <typename T, typename... Properties>
0415 constexpr bool is_nothrow_require_v
0416   = is_nothrow_require<T, Properties...>::value;
0417 
0418 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0419 
0420 template <typename T, typename... Properties>
0421 struct require_result
0422 {
0423   typedef typename boost_asio_require_fn::call_traits<
0424       require_t, T, void(Properties...)>::result_type type;
0425 };
0426 
0427 template <typename T, typename... Properties>
0428 using require_result_t = typename require_result<T, Properties...>::type;
0429 
0430 } // namespace asio
0431 } // namespace boost
0432 
0433 #endif // defined(GENERATING_DOCUMENTATION)
0434 
0435 #include <boost/asio/detail/pop_options.hpp>
0436 
0437 #endif // BOOST_ASIO_REQUIRE_HPP