1 // 2 // execution/occupancy.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_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 = is_executor<T>::value 72 || is_sender<T>::value || is_scheduler<T>::value); 73 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 74 75 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); 76 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); 77 typedef std::size_t polymorphic_query_result_type; 78 79 BOOST_ASIO_CONSTEXPR occupancy_t() 80 { 81 } 82 83 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 84 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 85 template <typename T> 86 static BOOST_ASIO_CONSTEXPR 87 typename traits::query_static_constexpr_member<T, occupancy_t>::result_type 88 static_query() 89 BOOST_ASIO_NOEXCEPT_IF(( 90 traits::query_static_constexpr_member<T, occupancy_t>::is_noexcept)) 91 { 92 return traits::query_static_constexpr_member<T, occupancy_t>::value(); 93 } 94 95 template <typename E, typename T = decltype(occupancy_t::static_query<E>())> 96 static BOOST_ASIO_CONSTEXPR const T static_query_v 97 = occupancy_t::static_query<E>(); 98 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 99 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 100 101 #if !defined(BOOST_ASIO_HAS_CONSTEXPR) 102 static const occupancy_t instance; 103 #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) 104 }; 105 106 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 107 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 108 template <int I> template <typename E, typename T> 109 const T occupancy_t<I>::static_query_v; 110 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 111 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 112 113 #if !defined(BOOST_ASIO_HAS_CONSTEXPR) 114 template <int I> 115 const occupancy_t<I> occupancy_t<I>::instance; 116 #endif 117 118 } // namespace detail 119 120 typedef detail::occupancy_t<> occupancy_t; 121 122 #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 123 constexpr occupancy_t occupancy; 124 #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 125 namespace { static const occupancy_t& occupancy = occupancy_t::instance; } 126 #endif 127 128 } // namespace execution 129 130 #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 131 132 template <typename T> 133 struct is_applicable_property<T, execution::occupancy_t> 134 : integral_constant<bool, 135 execution::is_executor<T>::value 136 || execution::is_sender<T>::value 137 || execution::is_scheduler<T>::value> 138 { 139 }; 140 141 #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 142 143 namespace traits { 144 145 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 146 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 147 148 template <typename T> 149 struct static_query<T, execution::occupancy_t, 150 typename enable_if< 151 traits::query_static_constexpr_member<T, 152 execution::occupancy_t>::is_valid 153 >::type> 154 { 155 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 156 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 157 158 typedef typename traits::query_static_constexpr_member<T, 159 execution::occupancy_t>::result_type result_type; 160 161 static BOOST_ASIO_CONSTEXPR result_type value() 162 { 163 return traits::query_static_constexpr_member<T, 164 execution::occupancy_t>::value(); 165 } 166 }; 167 168 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 169 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 170 171 } // namespace traits 172 173 #endif // defined(GENERATING_DOCUMENTATION) 174 175 } // namespace asio 176 } // namespace boost 177 178 #include <boost/asio/detail/pop_options.hpp> 179 180 #endif // BOOST_ASIO_EXECUTION_OCCUPANCY_HPP 181