1 // 2 // execution/context.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_CONTEXT2_HPP 12 #define BOOST_ASIO_EXECUTION_CONTEXT2_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/executor.hpp> 21 #include <boost/asio/execution/scheduler.hpp> 22 #include <boost/asio/execution/sender.hpp> 23 #include <boost/asio/is_applicable_property.hpp> 24 #include <boost/asio/traits/query_static_constexpr_member.hpp> 25 #include <boost/asio/traits/static_query.hpp> 26 27 #if defined(BOOST_ASIO_HAS_STD_ANY) 28 # include <any> 29 #endif // defined(BOOST_ASIO_HAS_STD_ANY) 30 31 #include <boost/asio/detail/push_options.hpp> 32 33 namespace boost { 34 namespace asio { 35 36 #if defined(GENERATING_DOCUMENTATION) 37 38 namespace execution { 39 40 /// A property that is used to obtain the execution context that is associated 41 /// with an executor. 42 struct context_t 43 { 44 /// The context_t property applies to executors, senders, and schedulers. 45 template <typename T> 46 static constexpr bool is_applicable_property_v = 47 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; 48 49 /// The context_t property cannot be required. 50 static constexpr bool is_requirable = false; 51 52 /// The context_t property cannot be preferred. 53 static constexpr bool is_preferable = false; 54 55 /// The type returned by queries against an @c any_executor. 56 typedef std::any polymorphic_query_result_type; 57 }; 58 59 /// A special value used for accessing the context_t property. 60 constexpr context_t context; 61 62 } // namespace execution 63 64 #else // defined(GENERATING_DOCUMENTATION) 65 66 namespace execution { 67 namespace detail { 68 69 template <int I = 0> 70 struct context_t 71 { 72 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 73 template <typename T> 74 BOOST_ASIO_STATIC_CONSTEXPR(bool, 75 is_applicable_property_v = ( 76 is_executor<T>::value 77 || conditional< 78 is_executor<T>::value, 79 false_type, 80 is_sender<T> 81 >::type::value 82 || conditional< 83 is_executor<T>::value, 84 false_type, 85 is_scheduler<T> 86 >::type::value)); 87 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 88 89 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); 90 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); 91 92 #if defined(BOOST_ASIO_HAS_STD_ANY) 93 typedef std::any polymorphic_query_result_type; 94 #endif // defined(BOOST_ASIO_HAS_STD_ANY) 95 96 BOOST_ASIO_CONSTEXPR context_t() 97 { 98 } 99 100 template <typename T> 101 struct static_proxy 102 { 103 #if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) 104 struct type 105 { 106 template <typename P> 107 static constexpr auto query(BOOST_ASIO_MOVE_ARG(P) p) 108 noexcept( 109 noexcept( 110 conditional<true, T, P>::type::query(BOOST_ASIO_MOVE_CAST(P)(p)) 111 ) 112 ) 113 -> decltype( 114 conditional<true, T, P>::type::query(BOOST_ASIO_MOVE_CAST(P)(p)) 115 ) 116 { 117 return T::query(BOOST_ASIO_MOVE_CAST(P)(p)); 118 } 119 }; 120 #else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) 121 typedef T type; 122 #endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) 123 }; 124 125 template <typename T> 126 struct query_static_constexpr_member : 127 traits::query_static_constexpr_member< 128 typename static_proxy<T>::type, context_t> {}; 129 130 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 131 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 132 template <typename T> 133 static BOOST_ASIO_CONSTEXPR 134 typename query_static_constexpr_member<T>::result_type 135 static_query() 136 BOOST_ASIO_NOEXCEPT_IF(( 137 query_static_constexpr_member<T>::is_noexcept)) 138 { 139 return query_static_constexpr_member<T>::value(); 140 } 141 142 template <typename E, typename T = decltype(context_t::static_query<E>())> 143 static BOOST_ASIO_CONSTEXPR const T static_query_v 144 = context_t::static_query<E>(); 145 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 146 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 147 148 #if !defined(BOOST_ASIO_HAS_CONSTEXPR) 149 static const context_t instance; 150 #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) 151 }; 152 153 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 154 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 155 template <int I> template <typename E, typename T> 156 const T context_t<I>::static_query_v; 157 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 158 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 159 160 #if !defined(BOOST_ASIO_HAS_CONSTEXPR) 161 template <int I> 162 const context_t<I> context_t<I>::instance; 163 #endif 164 165 } // namespace detail 166 167 typedef detail::context_t<> context_t; 168 169 #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 170 constexpr context_t context; 171 #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 172 namespace { static const context_t& context = context_t::instance; } 173 #endif 174 175 } // namespace execution 176 177 #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 178 179 template <typename T> 180 struct is_applicable_property<T, execution::context_t> 181 : integral_constant<bool, 182 execution::is_executor<T>::value 183 || conditional< 184 execution::is_executor<T>::value, 185 false_type, 186 execution::is_sender<T> 187 >::type::value 188 || conditional< 189 execution::is_executor<T>::value, 190 false_type, 191 execution::is_scheduler<T> 192 >::type::value> 193 { 194 }; 195 196 #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 197 198 namespace traits { 199 200 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 201 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 202 203 template <typename T> 204 struct static_query<T, execution::context_t, 205 typename enable_if< 206 execution::detail::context_t<0>:: 207 query_static_constexpr_member<T>::is_valid 208 >::type> 209 { 210 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 211 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 212 213 typedef typename execution::detail::context_t<0>:: 214 query_static_constexpr_member<T>::result_type result_type; 215 216 static BOOST_ASIO_CONSTEXPR result_type value() 217 { 218 return execution::detail::context_t<0>:: 219 query_static_constexpr_member<T>::value(); 220 } 221 }; 222 223 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 224 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 225 226 } // namespace traits 227 228 #endif // defined(GENERATING_DOCUMENTATION) 229 230 } // namespace asio 231 } // namespace boost 232 233 #include <boost/asio/detail/pop_options.hpp> 234 235 #endif // BOOST_ASIO_EXECUTION_CONTEXT2_HPP 236