File indexing completed on 2025-12-15 09:43:56
0001
0002
0003
0004
0005
0006
0007
0008
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
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
0035
0036 template <typename Property>
0037 struct prefer_only
0038 {
0039
0040 template <typename T>
0041 static constexpr bool is_applicable_property_v =
0042 is_applicable_property<T, Property>::value;
0043
0044
0045 static constexpr bool is_requirable = false;
0046
0047
0048
0049
0050
0051
0052 static constexpr bool is_preferable = automatically_determined;
0053
0054
0055 typedef typename Property::polymorphic_query_result_type
0056 polymorphic_query_result_type;
0057 };
0058
0059 }
0060
0061 #else
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
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
0184
0185 }
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
0215
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__)
0229 noexcept(is_nothrow_prefer<const Executor&, const InnerProperty&>::value)
0230 #endif
0231
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__)
0248 noexcept(is_nothrow_query<const Executor&, const InnerProperty&>::value)
0249 #endif
0250
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
0261
0262
0263 }
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
0283
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
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
0320
0321 }
0322
0323 #endif
0324
0325 }
0326 }
0327
0328 #include <boost/asio/detail/pop_options.hpp>
0329
0330 #endif