1 // 2 // execution/mapping.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_MAPPING_HPP 12 #define BOOST_ASIO_EXECUTION_MAPPING_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/query.hpp> 25 #include <boost/asio/traits/query_free.hpp> 26 #include <boost/asio/traits/query_member.hpp> 27 #include <boost/asio/traits/query_static_constexpr_member.hpp> 28 #include <boost/asio/traits/static_query.hpp> 29 #include <boost/asio/traits/static_require.hpp> 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 to describe what guarantees an executor makes about the mapping 41 /// of execution agents on to threads of execution. 42 struct mapping_t 43 { 44 /// The mapping_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 top-level mapping_t property cannot be required. 50 static constexpr bool is_requirable = false; 51 52 /// The top-level mapping_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 mapping_t polymorphic_query_result_type; 57 58 /// A sub-property that indicates that execution agents are mapped on to 59 /// threads of execution. 60 struct thread_t 61 { 62 /// The mapping_t::thread_t property applies to executors, senders, and 63 /// schedulers. 64 template <typename T> 65 static constexpr bool is_applicable_property_v = 66 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; 67 68 /// The mapping_t::thread_t property can be required. 69 static constexpr bool is_requirable = true; 70 71 /// The mapping_t::thread_t property can be preferred. 72 static constexpr bool is_preferable = true; 73 74 /// The type returned by queries against an @c any_executor. 75 typedef mapping_t polymorphic_query_result_type; 76 77 /// Default constructor. 78 constexpr thread_t(); 79 80 /// Get the value associated with a property object. 81 /** 82 * @returns thread_t(); 83 */ 84 static constexpr mapping_t value(); 85 }; 86 87 /// A sub-property that indicates that execution agents are mapped on to 88 /// new threads of execution. 89 struct new_thread_t 90 { 91 /// The mapping_t::new_thread_t property applies to executors, senders, and 92 /// schedulers. 93 template <typename T> 94 static constexpr bool is_applicable_property_v = 95 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; 96 97 /// The mapping_t::new_thread_t property can be required. 98 static constexpr bool is_requirable = true; 99 100 /// The mapping_t::new_thread_t property can be preferred. 101 static constexpr bool is_preferable = true; 102 103 /// The type returned by queries against an @c any_executor. 104 typedef mapping_t polymorphic_query_result_type; 105 106 /// Default constructor. 107 constexpr new_thread_t(); 108 109 /// Get the value associated with a property object. 110 /** 111 * @returns new_thread_t(); 112 */ 113 static constexpr mapping_t value(); 114 }; 115 116 /// A sub-property that indicates that the mapping of execution agents is 117 /// implementation-defined. 118 struct other_t 119 { 120 /// The mapping_t::other_t property applies to executors, senders, and 121 /// schedulers. 122 template <typename T> 123 static constexpr bool is_applicable_property_v = 124 is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; 125 126 /// The mapping_t::other_t property can be required. 127 static constexpr bool is_requirable = true; 128 129 /// The mapping_t::other_t property can be preferred. 130 static constexpr bool is_preferable = true; 131 132 /// The type returned by queries against an @c any_executor. 133 typedef mapping_t polymorphic_query_result_type; 134 135 /// Default constructor. 136 constexpr other_t(); 137 138 /// Get the value associated with a property object. 139 /** 140 * @returns other_t(); 141 */ 142 static constexpr mapping_t value(); 143 }; 144 145 /// A special value used for accessing the mapping_t::thread_t property. 146 static constexpr thread_t thread; 147 148 /// A special value used for accessing the mapping_t::new_thread_t property. 149 static constexpr new_thread_t new_thread; 150 151 /// A special value used for accessing the mapping_t::other_t property. 152 static constexpr other_t other; 153 154 /// Default constructor. 155 constexpr mapping_t(); 156 157 /// Construct from a sub-property value. 158 constexpr mapping_t(thread_t); 159 160 /// Construct from a sub-property value. 161 constexpr mapping_t(new_thread_t); 162 163 /// Construct from a sub-property value. 164 constexpr mapping_t(other_t); 165 166 /// Compare property values for equality. 167 friend constexpr bool operator==( 168 const mapping_t& a, const mapping_t& b) noexcept; 169 170 /// Compare property values for inequality. 171 friend constexpr bool operator!=( 172 const mapping_t& a, const mapping_t& b) noexcept; 173 }; 174 175 /// A special value used for accessing the mapping_t property. 176 constexpr mapping_t mapping; 177 178 } // namespace execution 179 180 #else // defined(GENERATING_DOCUMENTATION) 181 182 namespace execution { 183 namespace detail { 184 namespace mapping { 185 186 template <int I> struct thread_t; 187 template <int I> struct new_thread_t; 188 template <int I> struct other_t; 189 190 } // namespace mapping 191 192 template <int I = 0> 193 struct mapping_t 194 { 195 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 196 template <typename T> 197 BOOST_ASIO_STATIC_CONSTEXPR(bool, 198 is_applicable_property_v = is_executor<T>::value 199 || is_sender<T>::value || is_scheduler<T>::value); 200 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 201 202 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); 203 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); 204 typedef mapping_t polymorphic_query_result_type; 205 206 typedef detail::mapping::thread_t<I> thread_t; 207 typedef detail::mapping::new_thread_t<I> new_thread_t; 208 typedef detail::mapping::other_t<I> other_t; 209 210 BOOST_ASIO_CONSTEXPR mapping_t() 211 : value_(-1) 212 { 213 } 214 215 BOOST_ASIO_CONSTEXPR mapping_t(thread_t) 216 : value_(0) 217 { 218 } 219 220 BOOST_ASIO_CONSTEXPR mapping_t(new_thread_t) 221 : value_(1) 222 { 223 } 224 225 BOOST_ASIO_CONSTEXPR mapping_t(other_t) 226 : value_(2) 227 { 228 } 229 230 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 231 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 232 template <typename T> 233 static BOOST_ASIO_CONSTEXPR 234 typename traits::query_static_constexpr_member<T, mapping_t>::result_type 235 static_query() 236 BOOST_ASIO_NOEXCEPT_IF(( 237 traits::query_static_constexpr_member<T, mapping_t>::is_noexcept)) 238 { 239 return traits::query_static_constexpr_member<T, mapping_t>::value(); 240 } 241 242 template <typename T> 243 static BOOST_ASIO_CONSTEXPR 244 typename traits::static_query<T, thread_t>::result_type 245 static_query( 246 typename enable_if< 247 !traits::query_static_constexpr_member<T, mapping_t>::is_valid 248 && !traits::query_member<T, mapping_t>::is_valid 249 && traits::static_query<T, thread_t>::is_valid 250 >::type* = 0) BOOST_ASIO_NOEXCEPT 251 { 252 return traits::static_query<T, thread_t>::value(); 253 } 254 255 template <typename T> 256 static BOOST_ASIO_CONSTEXPR 257 typename traits::static_query<T, new_thread_t>::result_type 258 static_query( 259 typename enable_if< 260 !traits::query_static_constexpr_member<T, mapping_t>::is_valid 261 && !traits::query_member<T, mapping_t>::is_valid 262 && !traits::static_query<T, thread_t>::is_valid 263 && traits::static_query<T, new_thread_t>::is_valid 264 >::type* = 0) BOOST_ASIO_NOEXCEPT 265 { 266 return traits::static_query<T, new_thread_t>::value(); 267 } 268 269 template <typename T> 270 static BOOST_ASIO_CONSTEXPR 271 typename traits::static_query<T, other_t>::result_type 272 static_query( 273 typename enable_if< 274 !traits::query_static_constexpr_member<T, mapping_t>::is_valid 275 && !traits::query_member<T, mapping_t>::is_valid 276 && !traits::static_query<T, thread_t>::is_valid 277 && !traits::static_query<T, new_thread_t>::is_valid 278 && traits::static_query<T, other_t>::is_valid 279 >::type* = 0) BOOST_ASIO_NOEXCEPT 280 { 281 return traits::static_query<T, other_t>::value(); 282 } 283 284 template <typename E, typename T = decltype(mapping_t::static_query<E>())> 285 static BOOST_ASIO_CONSTEXPR const T static_query_v 286 = mapping_t::static_query<E>(); 287 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 288 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 289 290 friend BOOST_ASIO_CONSTEXPR bool operator==( 291 const mapping_t& a, const mapping_t& b) 292 { 293 return a.value_ == b.value_; 294 } 295 296 friend BOOST_ASIO_CONSTEXPR bool operator!=( 297 const mapping_t& a, const mapping_t& b) 298 { 299 return a.value_ != b.value_; 300 } 301 302 struct convertible_from_mapping_t 303 { 304 BOOST_ASIO_CONSTEXPR convertible_from_mapping_t(mapping_t) {} 305 }; 306 307 template <typename Executor> 308 friend BOOST_ASIO_CONSTEXPR mapping_t query( 309 const Executor& ex, convertible_from_mapping_t, 310 typename enable_if< 311 can_query<const Executor&, thread_t>::value 312 >::type* = 0) 313 #if !defined(__clang__) // Clang crashes if noexcept is used here. 314 #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. 315 BOOST_ASIO_NOEXCEPT_IF(( 316 is_nothrow_query<const Executor&, mapping_t<>::thread_t>::value)) 317 #else // defined(BOOST_ASIO_MSVC) 318 BOOST_ASIO_NOEXCEPT_IF(( 319 is_nothrow_query<const Executor&, thread_t>::value)) 320 #endif // defined(BOOST_ASIO_MSVC) 321 #endif // !defined(__clang__) 322 { 323 return boost::asio::query(ex, thread_t()); 324 } 325 326 template <typename Executor> 327 friend BOOST_ASIO_CONSTEXPR mapping_t query( 328 const Executor& ex, convertible_from_mapping_t, 329 typename enable_if< 330 !can_query<const Executor&, thread_t>::value 331 && can_query<const Executor&, new_thread_t>::value 332 >::type* = 0) 333 #if !defined(__clang__) // Clang crashes if noexcept is used here. 334 #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. 335 BOOST_ASIO_NOEXCEPT_IF(( 336 is_nothrow_query<const Executor&, mapping_t<>::new_thread_t>::value)) 337 #else // defined(BOOST_ASIO_MSVC) 338 BOOST_ASIO_NOEXCEPT_IF(( 339 is_nothrow_query<const Executor&, new_thread_t>::value)) 340 #endif // defined(BOOST_ASIO_MSVC) 341 #endif // !defined(__clang__) 342 { 343 return boost::asio::query(ex, new_thread_t()); 344 } 345 346 template <typename Executor> 347 friend BOOST_ASIO_CONSTEXPR mapping_t query( 348 const Executor& ex, convertible_from_mapping_t, 349 typename enable_if< 350 !can_query<const Executor&, thread_t>::value 351 && !can_query<const Executor&, new_thread_t>::value 352 && can_query<const Executor&, other_t>::value 353 >::type* = 0) 354 #if !defined(__clang__) // Clang crashes if noexcept is used here. 355 #if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified. 356 BOOST_ASIO_NOEXCEPT_IF(( 357 is_nothrow_query<const Executor&, mapping_t<>::other_t>::value)) 358 #else // defined(BOOST_ASIO_MSVC) 359 BOOST_ASIO_NOEXCEPT_IF(( 360 is_nothrow_query<const Executor&, other_t>::value)) 361 #endif // defined(BOOST_ASIO_MSVC) 362 #endif // !defined(__clang__) 363 { 364 return boost::asio::query(ex, other_t()); 365 } 366 367 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(thread_t, thread); 368 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(new_thread_t, new_thread); 369 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(other_t, other); 370 371 #if !defined(BOOST_ASIO_HAS_CONSTEXPR) 372 static const mapping_t instance; 373 #endif // !defined(BOOST_ASIO_HAS_CONSTEXPR) 374 375 private: 376 int value_; 377 }; 378 379 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 380 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 381 template <int I> template <typename E, typename T> 382 const T mapping_t<I>::static_query_v; 383 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 384 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 385 386 #if !defined(BOOST_ASIO_HAS_CONSTEXPR) 387 template <int I> 388 const mapping_t<I> mapping_t<I>::instance; 389 #endif 390 391 template <int I> 392 const typename mapping_t<I>::thread_t mapping_t<I>::thread; 393 394 template <int I> 395 const typename mapping_t<I>::new_thread_t mapping_t<I>::new_thread; 396 397 template <int I> 398 const typename mapping_t<I>::other_t mapping_t<I>::other; 399 400 namespace mapping { 401 402 template <int I = 0> 403 struct thread_t 404 { 405 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 406 template <typename T> 407 BOOST_ASIO_STATIC_CONSTEXPR(bool, 408 is_applicable_property_v = is_executor<T>::value 409 || is_sender<T>::value || is_scheduler<T>::value); 410 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 411 412 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); 413 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); 414 typedef mapping_t<I> polymorphic_query_result_type; 415 416 BOOST_ASIO_CONSTEXPR thread_t() 417 { 418 } 419 420 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 421 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 422 template <typename T> 423 static BOOST_ASIO_CONSTEXPR 424 typename traits::query_static_constexpr_member<T, thread_t>::result_type 425 static_query() 426 BOOST_ASIO_NOEXCEPT_IF(( 427 traits::query_static_constexpr_member<T, thread_t>::is_noexcept)) 428 { 429 return traits::query_static_constexpr_member<T, thread_t>::value(); 430 } 431 432 template <typename T> 433 static BOOST_ASIO_CONSTEXPR thread_t static_query( 434 typename enable_if< 435 !traits::query_static_constexpr_member<T, thread_t>::is_valid 436 && !traits::query_member<T, thread_t>::is_valid 437 && !traits::query_free<T, thread_t>::is_valid 438 && !can_query<T, new_thread_t<I> >::value 439 && !can_query<T, other_t<I> >::value 440 >::type* = 0) BOOST_ASIO_NOEXCEPT 441 { 442 return thread_t(); 443 } 444 445 template <typename E, typename T = decltype(thread_t::static_query<E>())> 446 static BOOST_ASIO_CONSTEXPR const T static_query_v 447 = thread_t::static_query<E>(); 448 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 449 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 450 451 static BOOST_ASIO_CONSTEXPR mapping_t<I> value() 452 { 453 return thread_t(); 454 } 455 456 friend BOOST_ASIO_CONSTEXPR bool operator==( 457 const thread_t&, const thread_t&) 458 { 459 return true; 460 } 461 462 friend BOOST_ASIO_CONSTEXPR bool operator!=( 463 const thread_t&, const thread_t&) 464 { 465 return false; 466 } 467 }; 468 469 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 470 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 471 template <int I> template <typename E, typename T> 472 const T thread_t<I>::static_query_v; 473 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 474 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 475 476 template <int I = 0> 477 struct new_thread_t 478 { 479 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 480 template <typename T> 481 BOOST_ASIO_STATIC_CONSTEXPR(bool, 482 is_applicable_property_v = is_executor<T>::value 483 || is_sender<T>::value || is_scheduler<T>::value); 484 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 485 486 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); 487 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); 488 typedef mapping_t<I> polymorphic_query_result_type; 489 490 BOOST_ASIO_CONSTEXPR new_thread_t() 491 { 492 } 493 494 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 495 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 496 template <typename T> 497 static BOOST_ASIO_CONSTEXPR 498 typename traits::query_static_constexpr_member<T, new_thread_t>::result_type 499 static_query() 500 BOOST_ASIO_NOEXCEPT_IF(( 501 traits::query_static_constexpr_member<T, new_thread_t>::is_noexcept)) 502 { 503 return traits::query_static_constexpr_member<T, new_thread_t>::value(); 504 } 505 506 template <typename E, typename T = decltype(new_thread_t::static_query<E>())> 507 static BOOST_ASIO_CONSTEXPR const T static_query_v 508 = new_thread_t::static_query<E>(); 509 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 510 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 511 512 static BOOST_ASIO_CONSTEXPR mapping_t<I> value() 513 { 514 return new_thread_t(); 515 } 516 517 friend BOOST_ASIO_CONSTEXPR bool operator==( 518 const new_thread_t&, const new_thread_t&) 519 { 520 return true; 521 } 522 523 friend BOOST_ASIO_CONSTEXPR bool operator!=( 524 const new_thread_t&, const new_thread_t&) 525 { 526 return false; 527 } 528 }; 529 530 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 531 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 532 template <int I> template <typename E, typename T> 533 const T new_thread_t<I>::static_query_v; 534 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 535 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 536 537 template <int I> 538 struct other_t 539 { 540 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 541 template <typename T> 542 BOOST_ASIO_STATIC_CONSTEXPR(bool, 543 is_applicable_property_v = is_executor<T>::value 544 || is_sender<T>::value || is_scheduler<T>::value); 545 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 546 547 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_requirable = true); 548 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); 549 typedef mapping_t<I> polymorphic_query_result_type; 550 551 BOOST_ASIO_CONSTEXPR other_t() 552 { 553 } 554 555 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 556 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 557 template <typename T> 558 static BOOST_ASIO_CONSTEXPR 559 typename traits::query_static_constexpr_member<T, other_t>::result_type 560 static_query() 561 BOOST_ASIO_NOEXCEPT_IF(( 562 traits::query_static_constexpr_member<T, other_t>::is_noexcept)) 563 { 564 return traits::query_static_constexpr_member<T, other_t>::value(); 565 } 566 567 template <typename E, typename T = decltype(other_t::static_query<E>())> 568 static BOOST_ASIO_CONSTEXPR const T static_query_v 569 = other_t::static_query<E>(); 570 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 571 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 572 573 static BOOST_ASIO_CONSTEXPR mapping_t<I> value() 574 { 575 return other_t(); 576 } 577 578 friend BOOST_ASIO_CONSTEXPR bool operator==( 579 const other_t&, const other_t&) 580 { 581 return true; 582 } 583 584 friend BOOST_ASIO_CONSTEXPR bool operator!=( 585 const other_t&, const other_t&) 586 { 587 return false; 588 } 589 }; 590 591 #if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 592 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 593 template <int I> template <typename E, typename T> 594 const T other_t<I>::static_query_v; 595 #endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 596 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 597 598 } // namespace mapping 599 } // namespace detail 600 601 typedef detail::mapping_t<> mapping_t; 602 603 #if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 604 constexpr mapping_t mapping; 605 #else // defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION) 606 namespace { static const mapping_t& mapping = mapping_t::instance; } 607 #endif 608 609 } // namespace execution 610 611 #if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 612 613 template <typename T> 614 struct is_applicable_property<T, execution::mapping_t> 615 : integral_constant<bool, 616 execution::is_executor<T>::value 617 || execution::is_sender<T>::value 618 || execution::is_scheduler<T>::value> 619 { 620 }; 621 622 template <typename T> 623 struct is_applicable_property<T, execution::mapping_t::thread_t> 624 : integral_constant<bool, 625 execution::is_executor<T>::value 626 || execution::is_sender<T>::value 627 || execution::is_scheduler<T>::value> 628 { 629 }; 630 631 template <typename T> 632 struct is_applicable_property<T, execution::mapping_t::new_thread_t> 633 : integral_constant<bool, 634 execution::is_executor<T>::value 635 || execution::is_sender<T>::value 636 || execution::is_scheduler<T>::value> 637 { 638 }; 639 640 template <typename T> 641 struct is_applicable_property<T, execution::mapping_t::other_t> 642 : integral_constant<bool, 643 execution::is_executor<T>::value 644 || execution::is_sender<T>::value 645 || execution::is_scheduler<T>::value> 646 { 647 }; 648 649 #endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) 650 651 namespace traits { 652 653 #if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 654 655 template <typename T> 656 struct query_free_default<T, execution::mapping_t, 657 typename enable_if< 658 can_query<T, execution::mapping_t::thread_t>::value 659 >::type> 660 { 661 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 662 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = 663 (is_nothrow_query<T, execution::mapping_t::thread_t>::value)); 664 665 typedef execution::mapping_t result_type; 666 }; 667 668 template <typename T> 669 struct query_free_default<T, execution::mapping_t, 670 typename enable_if< 671 !can_query<T, execution::mapping_t::thread_t>::value 672 && can_query<T, execution::mapping_t::new_thread_t>::value 673 >::type> 674 { 675 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 676 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = 677 (is_nothrow_query<T, execution::mapping_t::new_thread_t>::value)); 678 679 typedef execution::mapping_t result_type; 680 }; 681 682 template <typename T> 683 struct query_free_default<T, execution::mapping_t, 684 typename enable_if< 685 !can_query<T, execution::mapping_t::thread_t>::value 686 && !can_query<T, execution::mapping_t::new_thread_t>::value 687 && can_query<T, execution::mapping_t::other_t>::value 688 >::type> 689 { 690 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 691 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = 692 (is_nothrow_query<T, execution::mapping_t::other_t>::value)); 693 694 typedef execution::mapping_t result_type; 695 }; 696 697 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) 698 699 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ 700 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 701 702 template <typename T> 703 struct static_query<T, execution::mapping_t, 704 typename enable_if< 705 traits::query_static_constexpr_member<T, 706 execution::mapping_t>::is_valid 707 >::type> 708 { 709 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 710 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 711 712 typedef typename traits::query_static_constexpr_member<T, 713 execution::mapping_t>::result_type result_type; 714 715 static BOOST_ASIO_CONSTEXPR result_type value() 716 { 717 return traits::query_static_constexpr_member<T, 718 execution::mapping_t>::value(); 719 } 720 }; 721 722 template <typename T> 723 struct static_query<T, execution::mapping_t, 724 typename enable_if< 725 !traits::query_static_constexpr_member<T, execution::mapping_t>::is_valid 726 && !traits::query_member<T, execution::mapping_t>::is_valid 727 && traits::static_query<T, execution::mapping_t::thread_t>::is_valid 728 >::type> 729 { 730 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 731 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 732 733 typedef typename traits::static_query<T, 734 execution::mapping_t::thread_t>::result_type result_type; 735 736 static BOOST_ASIO_CONSTEXPR result_type value() 737 { 738 return traits::static_query<T, execution::mapping_t::thread_t>::value(); 739 } 740 }; 741 742 template <typename T> 743 struct static_query<T, execution::mapping_t, 744 typename enable_if< 745 !traits::query_static_constexpr_member<T, execution::mapping_t>::is_valid 746 && !traits::query_member<T, execution::mapping_t>::is_valid 747 && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid 748 && traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid 749 >::type> 750 { 751 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 752 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 753 754 typedef typename traits::static_query<T, 755 execution::mapping_t::new_thread_t>::result_type result_type; 756 757 static BOOST_ASIO_CONSTEXPR result_type value() 758 { 759 return traits::static_query<T, execution::mapping_t::new_thread_t>::value(); 760 } 761 }; 762 763 template <typename T> 764 struct static_query<T, execution::mapping_t, 765 typename enable_if< 766 !traits::query_static_constexpr_member<T, execution::mapping_t>::is_valid 767 && !traits::query_member<T, execution::mapping_t>::is_valid 768 && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid 769 && !traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid 770 && traits::static_query<T, execution::mapping_t::other_t>::is_valid 771 >::type> 772 { 773 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 774 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 775 776 typedef typename traits::static_query<T, 777 execution::mapping_t::other_t>::result_type result_type; 778 779 static BOOST_ASIO_CONSTEXPR result_type value() 780 { 781 return traits::static_query<T, execution::mapping_t::other_t>::value(); 782 } 783 }; 784 785 template <typename T> 786 struct static_query<T, execution::mapping_t::thread_t, 787 typename enable_if< 788 traits::query_static_constexpr_member<T, 789 execution::mapping_t::thread_t>::is_valid 790 >::type> 791 { 792 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 793 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 794 795 typedef typename traits::query_static_constexpr_member<T, 796 execution::mapping_t::thread_t>::result_type result_type; 797 798 static BOOST_ASIO_CONSTEXPR result_type value() 799 { 800 return traits::query_static_constexpr_member<T, 801 execution::mapping_t::thread_t>::value(); 802 } 803 }; 804 805 template <typename T> 806 struct static_query<T, execution::mapping_t::thread_t, 807 typename enable_if< 808 !traits::query_static_constexpr_member<T, 809 execution::mapping_t::thread_t>::is_valid 810 && !traits::query_member<T, execution::mapping_t::thread_t>::is_valid 811 && !traits::query_free<T, execution::mapping_t::thread_t>::is_valid 812 && !can_query<T, execution::mapping_t::new_thread_t>::value 813 && !can_query<T, execution::mapping_t::other_t>::value 814 >::type> 815 { 816 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 817 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 818 819 typedef execution::mapping_t::thread_t result_type; 820 821 static BOOST_ASIO_CONSTEXPR result_type value() 822 { 823 return result_type(); 824 } 825 }; 826 827 template <typename T> 828 struct static_query<T, execution::mapping_t::new_thread_t, 829 typename enable_if< 830 traits::query_static_constexpr_member<T, 831 execution::mapping_t::new_thread_t>::is_valid 832 >::type> 833 { 834 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 835 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 836 837 typedef typename traits::query_static_constexpr_member<T, 838 execution::mapping_t::new_thread_t>::result_type result_type; 839 840 static BOOST_ASIO_CONSTEXPR result_type value() 841 { 842 return traits::query_static_constexpr_member<T, 843 execution::mapping_t::new_thread_t>::value(); 844 } 845 }; 846 847 template <typename T> 848 struct static_query<T, execution::mapping_t::other_t, 849 typename enable_if< 850 traits::query_static_constexpr_member<T, 851 execution::mapping_t::other_t>::is_valid 852 >::type> 853 { 854 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); 855 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); 856 857 typedef typename traits::query_static_constexpr_member<T, 858 execution::mapping_t::other_t>::result_type result_type; 859 860 static BOOST_ASIO_CONSTEXPR result_type value() 861 { 862 return traits::query_static_constexpr_member<T, 863 execution::mapping_t::other_t>::value(); 864 } 865 }; 866 867 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) 868 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) 869 870 #if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) 871 872 template <typename T> 873 struct static_require<T, execution::mapping_t::thread_t, 874 typename enable_if< 875 static_query<T, execution::mapping_t::thread_t>::is_valid 876 >::type> 877 { 878 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = 879 (is_same<typename static_query<T, 880 execution::mapping_t::thread_t>::result_type, 881 execution::mapping_t::thread_t>::value)); 882 }; 883 884 template <typename T> 885 struct static_require<T, execution::mapping_t::new_thread_t, 886 typename enable_if< 887 static_query<T, execution::mapping_t::new_thread_t>::is_valid 888 >::type> 889 { 890 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = 891 (is_same<typename static_query<T, 892 execution::mapping_t::new_thread_t>::result_type, 893 execution::mapping_t::new_thread_t>::value)); 894 }; 895 896 template <typename T> 897 struct static_require<T, execution::mapping_t::other_t, 898 typename enable_if< 899 static_query<T, execution::mapping_t::other_t>::is_valid 900 >::type> 901 { 902 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = 903 (is_same<typename static_query<T, 904 execution::mapping_t::other_t>::result_type, 905 execution::mapping_t::other_t>::value)); 906 }; 907 908 #endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) 909 910 } // namespace traits 911 912 #endif // defined(GENERATING_DOCUMENTATION) 913 914 } // namespace asio 915 } // namespace boost 916 917 #include <boost/asio/detail/pop_options.hpp> 918 919 #endif // BOOST_ASIO_EXECUTION_MAPPING_HPP 920