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

source code of boost/libs/asio/include/boost/asio/execution/mapping.hpp