File indexing completed on 2025-01-18 09:29:11
0001
0002
0003
0004
0005
0006
0007
0008
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
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
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 inline constexpr unspecified require_concept = unspecified;
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 template <typename T, typename Property>
0071 struct can_require_concept :
0072 integral_constant<bool, automatically_determined>
0073 {
0074 };
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 template <typename T, typename Property>
0085 struct is_nothrow_require_concept :
0086 integral_constant<bool, automatically_determined>
0087 {
0088 };
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 template <typename T, typename Property>
0099 struct require_concept_result
0100 {
0101
0102 typedef automatically_determined type;
0103 };
0104
0105 }
0106 }
0107
0108 #else
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
0238 typedef T type;
0239 #endif
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 }
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 }
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
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
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 }
0341 }
0342
0343 #endif
0344
0345 #include <boost/asio/detail/pop_options.hpp>
0346
0347 #endif