Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // require_concept.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_CONCEPT_HPP
0012 #define BOOST_ASIO_REQUIRE_CONCEPT_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_concept_member.hpp>
0022 #include <boost/asio/traits/require_concept_free.hpp>
0023 #include <boost/asio/traits/static_require_concept.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-enforcing property to an
0033 /// object.
0034 /**
0035  * The name <tt>require_concept</tt> denotes a customization point object. The
0036  * expression <tt>boost::asio::require_concept(E, P)</tt> for some
0037  * subexpressions <tt>E</tt> and <tt>P</tt> (with types <tt>T =
0038  * decay_t<decltype(E)></tt> and <tt>Prop = decay_t<decltype(P)></tt>) is
0039  * expression-equivalent to:
0040  *
0041  * @li If <tt>is_applicable_property_v<T, Prop> &&
0042  *   Prop::is_requirable_concept</tt> is not a well-formed constant expression
0043  *   with value <tt>true</tt>, <tt>boost::asio::require_concept(E, P)</tt> is
0044  *   ill-formed.
0045  *
0046  * @li Otherwise, <tt>E</tt> if the expression <tt>Prop::template
0047  *   static_query_v<T> == Prop::value()</tt> is a well-formed constant
0048  *   expression with value <tt>true</tt>.
0049  *
0050  * @li Otherwise, <tt>(E).require_concept(P)</tt> if the expression
0051  *   <tt>(E).require_concept(P)</tt> is well-formed.
0052  *
0053  * @li Otherwise, <tt>require_concept(E, P)</tt> if the expression
0054  *   <tt>require_concept(E, P)</tt> is a valid expression with overload
0055  *   resolution performed in a context that does not include the declaration
0056  *   of the <tt>require_concept</tt> customization point object.
0057  *
0058  * @li Otherwise, <tt>boost::asio::require_concept(E, P)</tt> is ill-formed.
0059  */
0060 inline constexpr unspecified require_concept = unspecified;
0061 
0062 /// A type trait that determines whether a @c require_concept expression is
0063 /// well-formed.
0064 /**
0065  * Class template @c can_require_concept is a trait that is derived from
0066  * @c true_type if the expression
0067  * <tt>boost::asio::require_concept(std::declval<T>(),
0068  * std::declval<Property>())</tt> is well formed; otherwise @c false_type.
0069  */
0070 template <typename T, typename Property>
0071 struct can_require_concept :
0072   integral_constant<bool, automatically_determined>
0073 {
0074 };
0075 
0076 /// A type trait that determines whether a @c require_concept expression will
0077 /// not throw.
0078 /**
0079  * Class template @c is_nothrow_require_concept is a trait that is derived from
0080  * @c true_type if the expression
0081  * <tt>boost::asio::require_concept(std::declval<T>(),
0082  * std::declval<Property>())</tt> is @c noexcept; otherwise @c false_type.
0083  */
0084 template <typename T, typename Property>
0085 struct is_nothrow_require_concept :
0086   integral_constant<bool, automatically_determined>
0087 {
0088 };
0089 
0090 /// A type trait that determines the result type of a @c require_concept
0091 /// expression.
0092 /**
0093  * Class template @c require_concept_result is a trait that determines the
0094  * result type of the expression
0095  * <tt>boost::asio::require_concept(std::declval<T>(),
0096  * std::declval<Property>())</tt>.
0097  */
0098 template <typename T, typename Property>
0099 struct require_concept_result
0100 {
0101   /// The result of the @c require_concept 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_concept_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_concept_free;
0118 using boost::asio::traits::require_concept_member;
0119 using boost::asio::traits::static_require_concept;
0120 
0121 void require_concept();
0122 
0123 enum overload_type
0124 {
0125   identity,
0126   call_member,
0127   call_free,
0128   ill_formed
0129 };
0130 
0131 template <typename Impl, typename T, typename Properties, typename = void,
0132     typename = void, typename = void, typename = void, typename = void>
0133 struct call_traits
0134 {
0135   static constexpr overload_type overload = ill_formed;
0136   static constexpr bool is_noexcept = false;
0137   typedef void result_type;
0138 };
0139 
0140 template <typename Impl, typename T, typename Property>
0141 struct call_traits<Impl, T, void(Property),
0142   enable_if_t<
0143     is_applicable_property<
0144       decay_t<T>,
0145       decay_t<Property>
0146     >::value
0147   >,
0148   enable_if_t<
0149     decay_t<Property>::is_requirable_concept
0150   >,
0151   enable_if_t<
0152     static_require_concept<T, Property>::is_valid
0153   >>
0154 {
0155   static constexpr overload_type overload = identity;
0156   static constexpr bool is_noexcept = true;
0157   typedef T&& result_type;
0158 };
0159 
0160 template <typename Impl, typename T, typename Property>
0161 struct call_traits<Impl, T, void(Property),
0162   enable_if_t<
0163     is_applicable_property<
0164       decay_t<T>,
0165       decay_t<Property>
0166     >::value
0167   >,
0168   enable_if_t<
0169     decay_t<Property>::is_requirable_concept
0170   >,
0171   enable_if_t<
0172     !static_require_concept<T, Property>::is_valid
0173   >,
0174   enable_if_t<
0175     require_concept_member<
0176       typename Impl::template proxy<T>::type,
0177       Property
0178     >::is_valid
0179   >> :
0180   require_concept_member<
0181     typename Impl::template proxy<T>::type,
0182     Property
0183   >
0184 {
0185   static constexpr overload_type overload = call_member;
0186 };
0187 
0188 template <typename Impl, typename T, typename Property>
0189 struct call_traits<Impl, T, void(Property),
0190   enable_if_t<
0191     is_applicable_property<
0192       decay_t<T>,
0193       decay_t<Property>
0194     >::value
0195   >,
0196   enable_if_t<
0197     decay_t<Property>::is_requirable_concept
0198   >,
0199   enable_if_t<
0200     !static_require_concept<T, Property>::is_valid
0201   >,
0202   enable_if_t<
0203     !require_concept_member<
0204       typename Impl::template proxy<T>::type,
0205       Property
0206     >::is_valid
0207   >,
0208   enable_if_t<
0209     require_concept_free<T, Property>::is_valid
0210   >> :
0211   require_concept_free<T, Property>
0212 {
0213   static constexpr overload_type overload = call_free;
0214 };
0215 
0216 struct impl
0217 {
0218   template <typename T>
0219   struct proxy
0220   {
0221 #if defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)
0222     struct type
0223     {
0224       template <typename P>
0225       auto require_concept(P&& p)
0226         noexcept(
0227           noexcept(
0228             declval<conditional_t<true, T, P>>().require_concept(
0229               static_cast<P&&>(p))
0230           )
0231         )
0232         -> decltype(
0233           declval<conditional_t<true, T, P>>().require_concept(
0234             static_cast<P&&>(p))
0235         );
0236     };
0237 #else // defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)
0238     typedef T type;
0239 #endif // defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)
0240   };
0241 
0242   template <typename T, typename Property>
0243   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0244     call_traits<impl, T, void(Property)>::overload == identity,
0245     typename call_traits<impl, T, void(Property)>::result_type
0246   >
0247   operator()(T&& t, Property&&) const
0248     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0249   {
0250     return static_cast<T&&>(t);
0251   }
0252 
0253   template <typename T, typename Property>
0254   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0255     call_traits<impl, T, void(Property)>::overload == call_member,
0256     typename call_traits<impl, T, void(Property)>::result_type
0257   >
0258   operator()(T&& t, Property&& p) const
0259     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0260   {
0261     return static_cast<T&&>(t).require_concept(static_cast<Property&&>(p));
0262   }
0263 
0264   template <typename T, typename Property>
0265   BOOST_ASIO_NODISCARD constexpr enable_if_t<
0266     call_traits<impl, T, void(Property)>::overload == call_free,
0267     typename call_traits<impl, T, void(Property)>::result_type
0268   >
0269   operator()(T&& t, Property&& p) const
0270     noexcept(call_traits<impl, T, void(Property)>::is_noexcept)
0271   {
0272     return require_concept(static_cast<T&&>(t), static_cast<Property&&>(p));
0273   }
0274 };
0275 
0276 template <typename T = impl>
0277 struct static_instance
0278 {
0279   static const T instance;
0280 };
0281 
0282 template <typename T>
0283 const T static_instance<T>::instance = {};
0284 
0285 } // namespace boost_asio_require_concept_fn
0286 namespace boost {
0287 namespace asio {
0288 namespace {
0289 
0290 static constexpr const boost_asio_require_concept_fn::impl&
0291   require_concept = boost_asio_require_concept_fn::static_instance<>::instance;
0292 
0293 } // namespace
0294 
0295 typedef boost_asio_require_concept_fn::impl require_concept_t;
0296 
0297 template <typename T, typename Property>
0298 struct can_require_concept :
0299   integral_constant<bool,
0300     boost_asio_require_concept_fn::call_traits<
0301       require_concept_t, T, void(Property)>::overload !=
0302         boost_asio_require_concept_fn::ill_formed>
0303 {
0304 };
0305 
0306 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0307 
0308 template <typename T, typename Property>
0309 constexpr bool can_require_concept_v = can_require_concept<T, Property>::value;
0310 
0311 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0312 
0313 template <typename T, typename Property>
0314 struct is_nothrow_require_concept :
0315   integral_constant<bool,
0316     boost_asio_require_concept_fn::call_traits<
0317       require_concept_t, T, void(Property)>::is_noexcept>
0318 {
0319 };
0320 
0321 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0322 
0323 template <typename T, typename Property>
0324 constexpr bool is_nothrow_require_concept_v
0325   = is_nothrow_require_concept<T, Property>::value;
0326 
0327 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
0328 
0329 template <typename T, typename Property>
0330 struct require_concept_result
0331 {
0332   typedef typename boost_asio_require_concept_fn::call_traits<
0333       require_concept_t, T, void(Property)>::result_type type;
0334 };
0335 
0336 template <typename T, typename Property>
0337 using require_concept_result_t =
0338   typename require_concept_result<T, Property>::type;
0339 
0340 } // namespace asio
0341 } // namespace boost
0342 
0343 #endif // defined(GENERATING_DOCUMENTATION)
0344 
0345 #include <boost/asio/detail/pop_options.hpp>
0346 
0347 #endif // BOOST_ASIO_REQUIRE_CONCEPT_HPP