1 // 2 // execution/context_as.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2020 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_EXECUTION_CONTEXT_AS_HPP 12 #define BOOST_ASIO_EXECUTION_CONTEXT_AS_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/execution/context.hpp> 21 #include <boost/asio/execution/executor.hpp> 22 #include <boost/asio/execution/scheduler.hpp> 23 #include <boost/asio/execution/sender.hpp> 24 #include <boost/asio/is_applicable_property.hpp> 25 #include <boost/asio/query.hpp> 26 #include <boost/asio/traits/query_static_constexpr_member.hpp> 27 #include <boost/asio/traits/static_query.hpp> 28 29 #include <boost/asio/detail/push_options.hpp> 30 31 namespace boost { 32 namespace asio { 33 34 #if defined(GENERATING_DOCUMENTATION) 35 36 namespace execution { 37 38 /// A property that is used to obtain the execution context that is associated 39 /// with an executor. 40 template <typename U> 41 struct context_as_t 42 { 43 /// The context_as_t property applies to executors, senders, and schedulers. 44 template <typename T> 45 static constexpr bool is_applicable_property_v = 46 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; 47 48 /// The context_t property cannot be required. 49 static constexpr bool is_requirable = false; 50 51 /// The context_t property cannot be preferred. 52 static constexpr bool is_preferable = false; 53 54 /// The type returned by queries against an @c any_executor. 55 typedef T polymorphic_query_result_type; 56 }; 57 58 /// A special value used for accessing the context_as_t property. 59 template <typename U> 60 constexpr context_as_t context_as; 61 62 } // namespace execution 63 64 #else // defined(GENERATING_DOCUMENTATION) 65 66 namespace execution { 67 68 template <typename T> 69 struct context_as_t 70 { 71 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 72 template <typename U> 73 BOOST_ASIO_STATIC_CONSTEXPR(bool, 74 is_applicable_property_v = is_executor<U>::value 75 || is_sender<U>::value || is_scheduler<U>::value); 76 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 77 78 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); 79 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); 80 81 typedef T polymorphic_query_result_type; 82 83 BOOST_ASIO_CONSTEXPR context_as_t() 84 { 85 } 86 87 BOOST_ASIO_CONSTEXPR context_as_t(context_t) 88 { 89 } 90 91 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 92 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 93 template <typename E> 94 static BOOST_ASIO_CONSTEXPR 95 typename traits::query_static_constexpr_member<E, context_t>::result_type 96 static_query() 97 BOOST_ASIO_NOEXCEPT_IF(( 98 traits::query_static_constexpr_member<E, context_t>::is_noexcept)) 99 { 100 return traits::query_static_constexpr_member<E, context_t>::value(); 101 } 102 103 template <typename E, typename U = decltype(context_as_t::static_query<E>())> 104 static BOOST_ASIO_CONSTEXPR const U static_query_v 105 = context_as_t::static_query<E>(); 106 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 107 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 108 109 template <typename Executor, typename U> 110 friend BOOST_ASIO_CONSTEXPR U query( 111 const Executor& ex, const context_as_t<U>&, 112 typename enable_if< 113 is_same<T, U>::value 114 && can_query<const Executor&, const context_t&>::value 115 >::type* = 0) 116 #if !defined(__clang__) // Clang crashes if noexcept is used here. 117 #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. 118 BOOST_ASIO_NOEXCEPT_IF(( 119 is_nothrow_query<const Executor&, const context_t&>::value)) 120 #else // defined(BOOST_ASIO_MSVC) 121 BOOST_ASIO_NOEXCEPT_IF(( 122 is_nothrow_query<const Executor&, const context_t&>::value)) 123 #endif // defined(BOOST_ASIO_MSVC) 124 #endif // !defined(__clang__) 125 { 126 return boost::asio::query(ex, context); 127 } 128 }; 129 130 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 131 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 132 template <typename T> template <typename E, typename U> 133 const U context_as_t<T>::static_query_v; 134 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 135 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 136 137 #if (defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) \ 138 && defined(BOOST_ASIO_HAS_CONSTEXPR)) \ 139 || defined(GENERATING_DOCUMENTATION) 140 template <typename T> 141 constexpr context_as_t<T> context_as{}; 142 #endif // (defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 143 // && defined(BOOST_ASIO_HAS_CONSTEXPR)) 144 // || defined(GENERATING_DOCUMENTATION) 145 146 } // namespace execution 147 148 #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 149 150 template <typename T, typename U> 151 struct is_applicable_property<T, execution::context_as_t<U> > 152 : integral_constant<bool, 153 execution::is_executor<T>::value 154 || execution::is_sender<T>::value 155 || execution::is_scheduler<T>::value> 156 { 157 }; 158 159 #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 160 161 namespace traits { 162 163 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 164 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 165 166 template <typename T, typename U> 167 struct static_query<T, execution::context_as_t<U>, 168 typename enable_if< 169 static_query<T, execution::context_t>::is_valid 170 >::type> : static_query<T, execution::context_t> 171 { 172 }; 173 174 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 175 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 176 177 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 178 179 template <typename T, typename U> 180 struct query_free<T, execution::context_as_t<U>, 181 typename enable_if< 182 can_query<const T&, const execution::context_t&>::value 183 >::type> 184 { 185 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 186 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = 187 (is_nothrow_query<const T&, const execution::context_t&>::value)); 188 189 typedef U result_type; 190 }; 191 192 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 193 194 } // namespace traits 195 196 #endif // defined(GENERATING_DOCUMENTATION) 197 198 } // namespace asio 199 } // namespace boost 200 201 #include <boost/asio/detail/pop_options.hpp> 202 203 #endif // BOOST_ASIO_EXECUTION_CONTEXT_AS_HPP 204