1 // 2 // traits/static_require.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef BOOST_ASIO_TRAITS_STATIC_REQUIRE_HPP 12 #define BOOST_ASIO_TRAITS_STATIC_REQUIRE_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 #include <boost/asio/detail/type_traits.hpp> 20 #include <boost/asio/traits/static_query.hpp> 21 22 #if defined(BOOST_ASIO_HAS_DECLTYPE) \ 23 && defined(BOOST_ASIO_HAS_NOEXCEPT) 24 # define BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT 1 25 #endif // defined(BOOST_ASIO_HAS_DECLTYPE) 26 // && defined(BOOST_ASIO_HAS_NOEXCEPT) 27 28 #include <boost/asio/detail/push_options.hpp> 29 30 namespace boost { 31 namespace asio { 32 namespace traits { 33 34 template <typename T, typename Property, typename = void> 35 struct static_require_default; 36 37 template <typename T, typename Property, typename = void> 38 struct static_require; 39 40 } // namespace traits 41 namespace detail { 42 43 struct no_static_require 44 { 45 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false); 46 }; 47 48 template <typename T, typename Property, typename = void> 49 struct static_require_trait : 50 conditional< 51 is_same<T, typename decay<T>::type>::value 52 && is_same<Property, typename decay<Property>::type>::value, 53 no_static_require, 54 traits::static_require< 55 typename decay<T>::type, 56 typename decay<Property>::type> 57 >::type 58 { 59 }; 60 61 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) 62 63 #if defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE) 64 65 template <typename T, typename Property> 66 struct static_require_trait<T, Property, 67 typename enable_if< 68 decay<Property>::type::value() == traits::static_query<T, Property>::value() 69 >::type> 70 { 71 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 72 }; 73 74 #else // defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE) 75 76 false_type static_require_test(...); 77 78 template <typename T, typename Property> 79 true_type static_require_test(T*, Property*, 80 typename enable_if< 81 Property::value() == traits::static_query<T, Property>::value() 82 >::type* = 0); 83 84 template <typename T, typename Property> 85 struct has_static_require 86 { 87 BOOST_ASIO_STATIC_CONSTEXPR(bool, value = 88 decltype((static_require_test)( 89 static_cast<T*>(0), static_cast<Property*>(0)))::value); 90 }; 91 92 template <typename T, typename Property> 93 struct static_require_trait<T, Property, 94 typename enable_if< 95 has_static_require<typename decay<T>::type, 96 typename decay<Property>::type>::value 97 >::type> 98 { 99 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 100 }; 101 102 #endif // defined(BOOST_ASIO_HAS_WORKING_EXPRESSION_SFINAE) 103 104 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) 105 106 } // namespace detail 107 namespace traits { 108 109 template <typename T, typename Property, typename> 110 struct static_require_default : detail::static_require_trait<T, Property> 111 { 112 }; 113 114 template <typename T, typename Property, typename> 115 struct static_require : static_require_default<T, Property> 116 { 117 }; 118 119 } // namespace traits 120 } // namespace asio 121 } // namespace boost 122 123 #include <boost/asio/detail/pop_options.hpp> 124 125 #endif // BOOST_ASIO_TRAITS_STATIC_REQUIRE_HPP 126