Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:43:56

0001 //
0002 // execution/prefer_only.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 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_EXECUTION_PREFER_ONLY_HPP
0012 #define BOOST_ASIO_EXECUTION_PREFER_ONLY_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/prefer.hpp>
0022 #include <boost/asio/query.hpp>
0023 #include <boost/asio/traits/static_query.hpp>
0024 
0025 #include <boost/asio/detail/push_options.hpp>
0026 
0027 namespace boost {
0028 namespace asio {
0029 
0030 #if defined(GENERATING_DOCUMENTATION)
0031 
0032 namespace execution {
0033 
0034 /// A property adapter that is used with the polymorphic executor wrapper
0035 /// to mark properties as preferable, but not requirable.
0036 template <typename Property>
0037 struct prefer_only
0038 {
0039   /// The prefer_only adapter applies to the same types as the nested property.
0040   template <typename T>
0041   static constexpr bool is_applicable_property_v =
0042     is_applicable_property<T, Property>::value;
0043 
0044   /// The context_t property cannot be required.
0045   static constexpr bool is_requirable = false;
0046 
0047   /// The context_t property can be preferred, it the underlying property can
0048   /// be preferred.
0049   /**
0050    * @c true if @c Property::is_preferable is @c true, otherwise @c false.
0051    */
0052   static constexpr bool is_preferable = automatically_determined;
0053 
0054   /// The type returned by queries against an @c any_executor.
0055   typedef typename Property::polymorphic_query_result_type
0056     polymorphic_query_result_type;
0057 };
0058 
0059 } // namespace execution
0060 
0061 #else // defined(GENERATING_DOCUMENTATION)
0062 
0063 namespace execution {
0064 namespace detail {
0065 
0066 template <typename InnerProperty, typename = void>
0067 struct prefer_only_is_preferable
0068 {
0069   static constexpr bool is_preferable = false;
0070 };
0071 
0072 template <typename InnerProperty>
0073 struct prefer_only_is_preferable<InnerProperty,
0074     enable_if_t<
0075       InnerProperty::is_preferable
0076     >
0077   >
0078 {
0079   static constexpr bool is_preferable = true;
0080 };
0081 
0082 template <typename InnerProperty, typename = void>
0083 struct prefer_only_polymorphic_query_result_type
0084 {
0085 };
0086 
0087 template <typename InnerProperty>
0088 struct prefer_only_polymorphic_query_result_type<InnerProperty,
0089     void_t<
0090       typename InnerProperty::polymorphic_query_result_type
0091     >
0092   >
0093 {
0094   typedef typename InnerProperty::polymorphic_query_result_type
0095     polymorphic_query_result_type;
0096 };
0097 
0098 template <typename InnerProperty, typename = void>
0099 struct prefer_only_property
0100 {
0101   InnerProperty property;
0102 
0103   prefer_only_property(const InnerProperty& p)
0104     : property(p)
0105   {
0106   }
0107 };
0108 
0109 #if defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE)
0110 
0111 template <typename InnerProperty>
0112 struct prefer_only_property<InnerProperty,
0113     void_t<
0114       decltype(boost::asio::declval<const InnerProperty>().value())
0115     >
0116   >
0117 {
0118   InnerProperty property;
0119 
0120   prefer_only_property(const InnerProperty& p)
0121     : property(p)
0122   {
0123   }
0124 
0125   constexpr auto value() const
0126     noexcept(noexcept(boost::asio::declval<const InnerProperty>().value()))
0127     -> decltype(boost::asio::declval<const InnerProperty>().value())
0128   {
0129     return property.value();
0130   }
0131 };
0132 
0133 #else // defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE)
0134 
0135 struct prefer_only_memfns_base
0136 {
0137   void value();
0138 };
0139 
0140 template <typename T>
0141 struct prefer_only_memfns_derived
0142   : T, prefer_only_memfns_base
0143 {
0144 };
0145 
0146 template <typename T, T>
0147 struct prefer_only_memfns_check
0148 {
0149 };
0150 
0151 template <typename>
0152 char (&prefer_only_value_memfn_helper(...))[2];
0153 
0154 template <typename T>
0155 char prefer_only_value_memfn_helper(
0156     prefer_only_memfns_check<
0157       void (prefer_only_memfns_base::*)(),
0158       &prefer_only_memfns_derived<T>::value>*);
0159 
0160 template <typename InnerProperty>
0161 struct prefer_only_property<InnerProperty,
0162     enable_if_t<
0163       sizeof(prefer_only_value_memfn_helper<InnerProperty>(0)) != 1
0164         && !is_same<typename InnerProperty::polymorphic_query_result_type,
0165           void>::value
0166     >
0167   >
0168 {
0169   InnerProperty property;
0170 
0171   prefer_only_property(const InnerProperty& p)
0172     : property(p)
0173   {
0174   }
0175 
0176   constexpr typename InnerProperty::polymorphic_query_result_type
0177   value() const
0178   {
0179     return property.value();
0180   }
0181 };
0182 
0183 #endif // defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE)
0184 
0185 } // namespace detail
0186 
0187 template <typename InnerProperty>
0188 struct prefer_only :
0189   detail::prefer_only_is_preferable<InnerProperty>,
0190   detail::prefer_only_polymorphic_query_result_type<InnerProperty>,
0191   detail::prefer_only_property<InnerProperty>
0192 {
0193   static constexpr bool is_requirable = false;
0194 
0195   constexpr prefer_only(const InnerProperty& p)
0196     : detail::prefer_only_property<InnerProperty>(p)
0197   {
0198   }
0199 
0200 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0201   && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0202   template <typename T>
0203   static constexpr
0204   typename traits::static_query<T, InnerProperty>::result_type
0205   static_query()
0206     noexcept(traits::static_query<T, InnerProperty>::is_noexcept)
0207   {
0208     return traits::static_query<T, InnerProperty>::value();
0209   }
0210 
0211   template <typename E, typename T = decltype(prefer_only::static_query<E>())>
0212   static constexpr const T static_query_v
0213     = prefer_only::static_query<E>();
0214 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
0215        //   && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0216 
0217   template <typename Executor, typename Property>
0218   friend constexpr
0219   prefer_result_t<const Executor&, const InnerProperty&>
0220   prefer(const Executor& ex, const prefer_only<Property>& p,
0221       enable_if_t<
0222         is_same<Property, InnerProperty>::value
0223       >* = 0,
0224       enable_if_t<
0225         can_prefer<const Executor&, const InnerProperty&>::value
0226       >* = 0)
0227 #if !defined(BOOST_ASIO_MSVC) \
0228   && !defined(__clang__) // Clang crashes if noexcept is used here.
0229     noexcept(is_nothrow_prefer<const Executor&, const InnerProperty&>::value)
0230 #endif // !defined(BOOST_ASIO_MSVC)
0231        //   && !defined(__clang__)
0232   {
0233     return boost::asio::prefer(ex, p.property);
0234   }
0235 
0236   template <typename Executor, typename Property>
0237   friend constexpr
0238   query_result_t<const Executor&, const InnerProperty&>
0239   query(const Executor& ex, const prefer_only<Property>& p,
0240       enable_if_t<
0241         is_same<Property, InnerProperty>::value
0242       >* = 0,
0243       enable_if_t<
0244         can_query<const Executor&, const InnerProperty&>::value
0245       >* = 0)
0246 #if !defined(BOOST_ASIO_MSVC) \
0247   && !defined(__clang__) // Clang crashes if noexcept is used here.
0248     noexcept(is_nothrow_query<const Executor&, const InnerProperty&>::value)
0249 #endif // !defined(BOOST_ASIO_MSVC)
0250        //   && !defined(__clang__)
0251   {
0252     return boost::asio::query(ex, p.property);
0253   }
0254 };
0255 
0256 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0257   && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0258 template <typename InnerProperty> template <typename E, typename T>
0259 const T prefer_only<InnerProperty>::static_query_v;
0260 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
0261        //   && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0262 
0263 } // namespace execution
0264 
0265 template <typename T, typename InnerProperty>
0266 struct is_applicable_property<T, execution::prefer_only<InnerProperty>>
0267   : is_applicable_property<T, InnerProperty>
0268 {
0269 };
0270 
0271 namespace traits {
0272 
0273 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
0274   || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0275 
0276 template <typename T, typename InnerProperty>
0277 struct static_query<T, execution::prefer_only<InnerProperty>> :
0278   static_query<T, const InnerProperty&>
0279 {
0280 };
0281 
0282 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
0283        //   || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
0284 
0285 #if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
0286 
0287 template <typename T, typename InnerProperty>
0288 struct prefer_free_default<T, execution::prefer_only<InnerProperty>,
0289     enable_if_t<
0290       can_prefer<const T&, const InnerProperty&>::value
0291     >
0292   >
0293 {
0294   static constexpr bool is_valid = true;
0295   static constexpr bool is_noexcept =
0296     is_nothrow_prefer<const T&, const InnerProperty&>::value;
0297 
0298   typedef prefer_result_t<const T&, const InnerProperty&> result_type;
0299 };
0300 
0301 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
0302 
0303 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
0304 
0305 template <typename T, typename InnerProperty>
0306 struct query_free<T, execution::prefer_only<InnerProperty>,
0307     enable_if_t<
0308       can_query<const T&, const InnerProperty&>::value
0309     >
0310   >
0311 {
0312   static constexpr bool is_valid = true;
0313   static constexpr bool is_noexcept =
0314     is_nothrow_query<const T&, const InnerProperty&>::value;
0315 
0316   typedef query_result_t<const T&, const InnerProperty&> result_type;
0317 };
0318 
0319 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
0320 
0321 } // namespace traits
0322 
0323 #endif // defined(GENERATING_DOCUMENTATION)
0324 
0325 } // namespace asio
0326 } // namespace boost
0327 
0328 #include <boost/asio/detail/pop_options.hpp>
0329 
0330 #endif // BOOST_ASIO_EXECUTION_PREFER_ONLY_HPP