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