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