1 // 2 // execution/context_as.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_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 = ( 75 is_executor<U>::value 76 || conditional< 77 is_executor<U>::value, 78 false_type, 79 is_sender<U> 80 >::type::value 81 || conditional< 82 is_executor<U>::value, 83 false_type, 84 is_scheduler<U> 85 >::type::value)); 86 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 87 88 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); 89 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); 90 91 typedef T polymorphic_query_result_type; 92 93 BOOST_ASIO_CONSTEXPR context_as_t() 94 { 95 } 96 97 BOOST_ASIO_CONSTEXPR context_as_t(context_t) 98 { 99 } 100 101 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 102 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 103 template <typename E> 104 static BOOST_ASIO_CONSTEXPR 105 typename context_t::query_static_constexpr_member<E>::result_type 106 static_query() 107 BOOST_ASIO_NOEXCEPT_IF(( 108 context_t::query_static_constexpr_member<E>::is_noexcept)) 109 { 110 return context_t::query_static_constexpr_member<E>::value(); 111 } 112 113 template <typename E, typename U = decltype(context_as_t::static_query<E>())> 114 static BOOST_ASIO_CONSTEXPR const U static_query_v 115 = context_as_t::static_query<E>(); 116 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 117 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 118 119 template <typename Executor, typename U> 120 friend BOOST_ASIO_CONSTEXPR U query( 121 const Executor& ex, const context_as_t<U>&, 122 typename enable_if< 123 is_same<T, U>::value 124 >::type* = 0, 125 typename enable_if< 126 can_query<const Executor&, const context_t&>::value 127 >::type* = 0) 128 #if !defined(__clang__) // Clang crashes if noexcept is used here. 129 #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. 130 BOOST_ASIO_NOEXCEPT_IF(( 131 is_nothrow_query<const Executor&, const context_t&>::value)) 132 #else // defined(BOOST_ASIO_MSVC) 133 BOOST_ASIO_NOEXCEPT_IF(( 134 is_nothrow_query<const Executor&, const context_t&>::value)) 135 #endif // defined(BOOST_ASIO_MSVC) 136 #endif // !defined(__clang__) 137 { 138 return boost::asio::query(ex, context); 139 } 140 }; 141 142 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 143 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 144 template <typename T> template <typename E, typename U> 145 const U context_as_t<T>::static_query_v; 146 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 147 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 148 149 #if (defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) \ 150 && defined(BOOST_ASIO_HAS_CONSTEXPR)) \ 151 || defined(GENERATING_DOCUMENTATION) 152 template <typename T> 153 constexpr context_as_t<T> context_as{}; 154 #endif // (defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 155 // && defined(BOOST_ASIO_HAS_CONSTEXPR)) 156 // || defined(GENERATING_DOCUMENTATION) 157 158 } // namespace execution 159 160 #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 161 162 template <typename T, typename U> 163 struct is_applicable_property<T, execution::context_as_t<U> > 164 : integral_constant<bool, 165 execution::is_executor<T>::value 166 || conditional< 167 execution::is_executor<T>::value, 168 false_type, 169 execution::is_sender<T> 170 >::type::value 171 || conditional< 172 execution::is_executor<T>::value, 173 false_type, 174 execution::is_scheduler<T> 175 >::type::value> 176 { 177 }; 178 179 #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 180 181 namespace traits { 182 183 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 184 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 185 186 template <typename T, typename U> 187 struct static_query<T, execution::context_as_t<U>, 188 typename enable_if< 189 static_query<T, execution::context_t>::is_valid 190 >::type> : static_query<T, execution::context_t> 191 { 192 }; 193 194 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 195 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 196 197 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 198 199 template <typename T, typename U> 200 struct query_free<T, execution::context_as_t<U>, 201 typename enable_if< 202 can_query<const T&, const execution::context_t&>::value 203 >::type> 204 { 205 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 206 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = 207 (is_nothrow_query<const T&, const execution::context_t&>::value)); 208 209 typedef U result_type; 210 }; 211 212 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 213 214 } // namespace traits 215 216 #endif // defined(GENERATING_DOCUMENTATION) 217 218 } // namespace asio 219 } // namespace boost 220 221 #include <boost/asio/detail/pop_options.hpp> 222 223 #endif // BOOST_ASIO_EXECUTION_CONTEXT_AS_HPP 224