File indexing completed on 2025-01-18 09:29:10
0001
0002
0003
0004
0005
0006
0007
0008
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
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
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 inline constexpr unspecified prefer = unspecified;
0078
0079
0080
0081
0082
0083
0084
0085 template <typename T, typename... Properties>
0086 struct can_prefer :
0087 integral_constant<bool, automatically_determined>
0088 {
0089 };
0090
0091
0092
0093
0094
0095
0096
0097 template <typename T, typename... Properties>
0098 struct is_nothrow_prefer :
0099 integral_constant<bool, automatically_determined>
0100 {
0101 };
0102
0103
0104
0105
0106
0107
0108
0109 template <typename T, typename... Properties>
0110 struct prefer_result
0111 {
0112
0113 typedef automatically_determined type;
0114 };
0115
0116 }
0117 }
0118
0119 #else
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
0422
0423 typedef T type;
0424 #endif
0425
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 }
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 }
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
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
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 }
0575 }
0576
0577 #endif
0578
0579 #include <boost/asio/detail/pop_options.hpp>
0580
0581 #endif