CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
ExecutionContext.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2023 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
12
15
16#include <asio/defer.hpp>
17#include <asio/dispatch.hpp>
18#include <asio/io_context.hpp>
19#include <asio/post.hpp>
20#include <asio/strand.hpp>
21
22#include <asio/any_io_executor.hpp>
23#include <asio/execution/execute.hpp>
24
25namespace CeresEngine {
26
90 class ExecutionContext : public asio::execution_context {
91 public:
93 using ID = id;
94
96 template<typename T> class Service : public service {
97 public:
98 static inline const ID id;
99 using service::service;
100
101 public:
105
109 };
110
111 public:
114
115 public:
124 template<typename T> [[nodiscard]] bool hasService() noexcept { return asio::has_service<T>(*this); }
125
136 template<typename T> [[nodiscard]] T& getService() noexcept { return asio::use_service<T>(*this); }
137
147 template<typename T> [[nodiscard]] T* getServiceIf() noexcept { return hasService<T>() ? &getService<T>() : nullptr; }
148
149 public:
151
155
158
159 public:
165
170
177
178 protected:
180 class Scope {
181 friend class ExecutionContext;
182
183 private:
185 static thread_local const Scope* top;
186
189
192 const Scope* const mPrevious;
193
194 public:
198 explicit Scope(ExecutionContext* executionContext) noexcept;
199
201 ~Scope() noexcept;
202
203 Scope(const Scope&) noexcept = delete;
204 Scope& operator=(const Scope&) noexcept = delete;
205 };
206 };
207
208 using ExecutorExecutionContext = asio::execution::context_t;
209 template<typename T> using ExecutorExecutionContextAs = asio::execution::context_as_t<T>;
210 using ExecutorBlocking = asio::execution::blocking_t;
211 using ExecutorMapping = asio::execution::mapping_t;
212 using ExecutorOccupancy = asio::execution::occupancy_t;
213 using ExecutorOutstandingWork = asio::execution::outstanding_work_t;
214 using ExecutorBulkGuarantee = asio::execution::bulk_guarantee_t;
215 using ExecutorRelationship = asio::execution::relationship_t;
216 template<typename T> using ExecutorAllocator = asio::execution::allocator_t<T>;
217
222 Int32 raw = 0;
223
224 constexpr ExecutorPriority() noexcept = default;
225 explicit constexpr ExecutorPriority(const Int32 raw) noexcept : raw(raw) {}
226
227 [[nodiscard]] friend constexpr ExecutorPriority operator+(const Int32 lhs, const ExecutorPriority& rhs) noexcept { return ExecutorPriority(lhs + rhs.raw); }
228 [[nodiscard]] friend constexpr ExecutorPriority operator+(const ExecutorPriority& lhs, const Int32 rhs) noexcept { return ExecutorPriority(lhs.raw + rhs); }
229
230 [[nodiscard]] friend constexpr ExecutorPriority operator-(const Int32 lhs, const ExecutorPriority& rhs) noexcept { return ExecutorPriority(lhs - rhs.raw); }
231 [[nodiscard]] friend constexpr ExecutorPriority operator-(const ExecutorPriority& lhs, const Int32 rhs) noexcept { return ExecutorPriority(lhs.raw - rhs); }
232
233 [[nodiscard]] friend constexpr Int32 operator-(const ExecutorPriority& lhs, const ExecutorPriority& rhs) noexcept { return lhs.raw - rhs.raw; }
234
235 [[nodiscard]] friend constexpr bool operator==(const ExecutorPriority& lhs, const ExecutorPriority& rhs) noexcept { return lhs.raw == rhs.raw; }
236 [[nodiscard]] friend constexpr bool operator!=(const ExecutorPriority& lhs, const ExecutorPriority& rhs) noexcept { return !(rhs == lhs); }
237
238 [[nodiscard]] friend constexpr bool operator<(const ExecutorPriority& lhs, const ExecutorPriority& rhs) noexcept { return lhs.raw < rhs.raw; }
239 [[nodiscard]] friend constexpr bool operator>(const ExecutorPriority& lhs, const ExecutorPriority& rhs) noexcept { return rhs < lhs; }
240 [[nodiscard]] friend constexpr bool operator<=(const ExecutorPriority& lhs, const ExecutorPriority& rhs) noexcept { return !(rhs < lhs); }
241 [[nodiscard]] friend constexpr bool operator>=(const ExecutorPriority& lhs, const ExecutorPriority& rhs) noexcept { return !(lhs < rhs); }
242
245
247 static const ExecutorPriority Low;
248
251
253 static const ExecutorPriority High;
254
257
262 [[nodiscard]] static constexpr ExecutorPriority interpolate(const double priority) { return interpolate(priority, Lowest, Highest); }
263
267 [[nodiscard]] static constexpr ExecutorPriority interpolate(const double priority, const ExecutorPriority& lowest, const ExecutorPriority& highest) {
268 CE_ASSERT(lowest.raw < highest.raw);
269 return ExecutorPriority(Int32(std::lerp(priority, double(lowest.raw), double(highest.raw))));
270 }
271
272 public: // ASIO executor interface:
273 template<typename T> static constexpr bool is_applicable_property_v = asio::execution::is_executor<T>::value;
274 static constexpr bool is_requirable = true;
275 static constexpr bool is_preferable = true;
277 };
278
279 inline constexpr ExecutorPriority ExecutorPriority::Lowest{std::numeric_limits<Int32>::lowest()};
280 inline constexpr ExecutorPriority ExecutorPriority::Low{std::numeric_limits<Int32>::lowest() / 2};
281 inline constexpr ExecutorPriority ExecutorPriority::Normal{0};
282 inline constexpr ExecutorPriority ExecutorPriority::High{std::numeric_limits<Int32>::max() / 2};
283 inline constexpr ExecutorPriority ExecutorPriority::Highest{std::numeric_limits<Int32>::max()};
284
285 template<typename Property> using ExecutorPreferOnly = asio::execution::prefer_only<Property>;
286
287 template<typename... Properties>
288 using AnyExecutorBase = asio::execution::any_executor<
289 // clang-format off
290// ExecutorExecutionContextAs<asio::execution_context&>,
291// ExecutorContextAsProperty<ExecutionContext&>,
292 Properties...,
293// ExecutorBlocking::never_t,
304 // clang-format on
305 >;
306
309 template<typename... Properties> class TAnyExecutor : private AnyExecutorBase<Properties...> {
310 private:
311 using super = AnyExecutorBase<Properties...>;
312
313 public:
315 TAnyExecutor() noexcept = default;
316
318 TAnyExecutor(const TAnyExecutor& e) noexcept = default;
319
321 TAnyExecutor& operator=(const TAnyExecutor& e) noexcept = default;
322
324 TAnyExecutor(TAnyExecutor&& e) noexcept = default;
325
327 TAnyExecutor& operator=(TAnyExecutor&& e) noexcept = default;
328
330 template<typename Executor>
331 TAnyExecutor(Executor executor) requires(!std::is_same_v<Executor, AnyExecutor> && !std::is_base_of_v<AnyExecutor, Executor>)
332 : super(std::move(executor)) {}
333
335 TAnyExecutor(nullptr_t) noexcept : super(nullptr) {}
336
339 super() = nullptr;
340 return *this;
341 }
342
344 ~TAnyExecutor() = default;
345
347 void swap(TAnyExecutor& other) noexcept { base().swap(other.base()); }
348
349 // using super::context;
350
352 // [[nodiscard]] ExecutionContext& getExecutionContext() const noexcept { return static_cast<ExecutionContext&>(context()); }
353
354 using super::execute;
355
357 template<typename F> void operator()(F&& f) const {
358 asio::execution::execute(*this, [f = std::forward<F>(f)]() mutable { std::forward<F>(f)(); });
359 }
360
371 template<typename Property>
372 [[nodiscard]] decltype(auto) query(const Property& p) const requires asio::traits::query_member<const super&, const Property&>::is_valid {
373 return base().query(p);
374 }
375
386 template<typename Property>
387 [[nodiscard]] TAnyExecutor require(const Property& p) const requires asio::traits::require_member<const super&, const Property&>::is_valid {
388 return base().require(p);
389 }
390
401 template<typename Property>
402 [[nodiscard]] TAnyExecutor prefer(const Property& p) const requires asio::traits::prefer_member<const super&, const Property&>::is_valid {
403 return base().prefer(p);
404 }
405
406 template<typename T> [[nodiscard]] bool is() const noexcept { return this->target_type() == typeid(T); }
407 template<typename T> [[nodiscard]] T& as() const noexcept { return *this->template target<T>(); }
408 template<typename T> [[nodiscard]] T* being() const noexcept { return is<T>() ? &this->template target<T>() : nullptr; }
409
410 public:
411 friend bool operator==(const TAnyExecutor& lhs, const TAnyExecutor& rhs) noexcept { return lhs.base() == rhs.base(); }
412 friend bool operator==(const TAnyExecutor& lhs, std::nullptr_t) noexcept { return lhs.base() == nullptr; }
413 friend bool operator==(std::nullptr_t, const TAnyExecutor& rhs) noexcept { return nullptr == rhs.base(); }
414
415 friend bool operator!=(const TAnyExecutor& lhs, const TAnyExecutor& rhs) noexcept { return lhs.base() != rhs.base(); }
416 friend bool operator!=(const TAnyExecutor& lhs, std::nullptr_t) noexcept { return lhs.base() != nullptr; }
417 friend bool operator!=(std::nullptr_t, const TAnyExecutor& rhs) noexcept { return nullptr != rhs.base(); }
418
419 private:
420 [[nodiscard]] super& base() noexcept { return *this; }
421 [[nodiscard]] const super& base() const noexcept { return *this; }
422 };
423
426
427 template<typename T> ExecutionContext& ExecutionContext::Service<T>::getExecutionContext() noexcept { return static_cast<ExecutionContext&>(context()); }
428 template<typename T> TAnyExecutor<> ExecutionContext::Service<T>::getExecutor() noexcept { return asio::get_associated_executor(context()); }
429
431 template<typename Executor> using TStrand = asio::strand<Executor>;
432
435
436 namespace traits {
438 using asio::execution::is_executor;
439
441 template<typename T> constexpr bool is_executor_v = is_executor<T>::value;
442
444 template<typename T>
445 concept executor = is_executor_v<T>;
446
447 // -----------------------------------------------------------------------------------------
448
450 template<class T> struct is_execution_context : asio::is_convertible<T&, ExecutionContext&> {};
451
453 template<typename T> constexpr bool is_execution_context_v = is_execution_context<T>::value;
454
456 template<typename T>
457 concept execution_context = is_execution_context_v<T>;
458
459 // -----------------------------------------------------------------------------------------
460
462 template<class T> struct is_executor_or_execution_context : std::conjunction<is_executor<T>, is_execution_context<T>> {};
463
466
468 template<typename T>
469 concept executor_or_execution_context = is_executor_or_execution_context_v<T>;
470 } // namespace traits
471
472 // ---------------------------------------------------------------------------------------------
473
474 template<traits::executor Executor, typename F> decltype(auto) defer(Executor executor, F&& func) {
475 // NOTE: If no executor is specified, defer to the current executor.
476 return asio::defer(executor, std::forward<F>(func));
477 }
478
479 template<typename F> decltype(auto) defer(ExecutionContext& executionContext, F&& func) {
480 // NOTE: If no executor is specified, defer to the current executor.
481 return asio::defer(executionContext.getExecutor(), std::forward<F>(func));
482 }
483
484 template<typename F> decltype(auto) defer(F&& func) {
485 // NOTE: If no executor is specified, defer to the current executor.
486 return asio::defer(ExecutionContext::get(), std::forward<F>(func));
487 }
488
489 // ---------------------------------------------------------------------------------------------
490
491 // template<traits::executor Executor, typename F> decltype(auto) dispatch(Executor executor, F&& func) {
492 // // NOTE: If no executor is specified, dispatch to the current executor.
493 // return asio::dispatch(executor, std::forward<F>(func));
494 // }
495 //
496 // template<typename F> decltype(auto) dispatch(ExecutionContext& executionContext, F&& func) {
497 // // NOTE: If no executor is specified, dispatch to the current executor.
498 // return asio::dispatch(executionContext.getExecutor(), std::forward<F>(func));
499 // }
500 //
501 // template<typename F> decltype(auto) dispatch(F&& func) {
502 // // NOTE: If no executor is specified, dispatch to the current executor.
503 // return asio::dispatch(ExecutionContext::get(), std::forward<F>(func));
504 // }
505 //
506 // // ---------------------------------------------------------------------------------------------
507 //
508 // template<traits::executor Executor, typename F> decltype(auto) post(Executor executor, F&& func) {
509 // // NOTE: If no executor is specified, post to the current executor.
510 // return asio::post(executor, std::forward<F>(func));
511 // }
512 //
513 // template<typename F> decltype(auto) post(ExecutionContext& executionContext, F&& func) {
514 // // NOTE: If no executor is specified, post to the current executor.
515 // return asio::post(executionContext.getExecutor(), std::forward<F>(func));
516 // }
517 //
518 // template<typename F> decltype(auto) post(F&& func) {
519 // // NOTE: If no executor is specified, post to the current executor.
520 // return asio::post(ExecutionContext::get(), std::forward<F>(func));
521 // }
522 //
523 // // ---------------------------------------------------------------------------------------------
524 //
525 // template<traits::executor Executor, typename F> decltype(auto) execute(Executor executor, F&& func) {
526 // // NOTE: If no executor is specified, execute to the current executor.
527 // return asio::execution::execute(executor, std::forward<F>(func));
528 // }
529 //
530 // template<typename F> decltype(auto) execute(ExecutionContext& executionContext, F&& func) {
531 // // NOTE: If no executor is specified, execute to the current executor.
532 // return asio::execution::execute(executionContext.getExecutor(), std::forward<F>(func));
533 // }
534 //
535 // template<typename F> decltype(auto) execute(F&& func) {
536 // // NOTE: If no executor is specified, execute to the current executor.
537 // return asio::execution::execute(ExecutionContext::get(), std::forward<F>(func));
538 // }
539
540 using asio::dispatch;
541 using asio::post;
542 using asio::execution::execute;
543
544 // ---------------------------------------------------------------------------------------------
545
546 template<traits::executor Executor> auto with(Executor executor) {
547 return async<void>([executor = std::move(executor)](auto&& promise) {
548 return execute(std::move(executor), [promise = std::forward<decltype(promise)>(promise)]() mutable {
549 promise.set_value();
550 });
551 });
552 }
553
554 inline auto with(ExecutionContext& context) {
555 return with(context.getExecutor());
556 }
557
558 template<traits::executor Executor, typename Func> auto with(Executor executor, Func&& func) {
559 return with(std::move(executor)).then(std::forward<Func>(func)); //
560 }
561
562 template<typename Func> auto with(ExecutionContext& context, Func&& func) {
563 return with(context).then(std::forward<Func>(func)); //
564 }
565
566 using ExecutorWorkGuard = asio::executor_work_guard<AnyExecutor>;
567
568 using asio::can_prefer;
569 using asio::can_prefer_v;
570 using asio::prefer;
571
572 using asio::can_query;
573 using asio::can_query_v;
574 using asio::query;
575
576 using asio::can_require;
577 using asio::can_require_v;
578 using asio::require;
579
597 constexpr std::size_t hardware_concurrency() noexcept {
598 // Cache the value because calculating it may be expensive
599 if(std::is_constant_evaluated()) {
600 return 1;
601 } else {
602 // Return at least 1 core
603 return (std::max)(std::size_t(1), std::size_t(std::thread::hardware_concurrency()));
604 }
605 }
606
607 // ---------------------------------------------------------------------------------------------
608
615 public:
617 [[nodiscard]] friend constexpr bool operator==(const InlineExecutor& lhs, const InlineExecutor& rhs) noexcept { return true; }
618
620 [[nodiscard]] friend constexpr bool operator!=(const InlineExecutor& lhs, const InlineExecutor& rhs) noexcept { return !(lhs == rhs); }
621
622 private:
623 friend struct asio_query_fn::impl;
624 friend struct ExecutorMapping::mapping_t<0>::mapping_t;
625 friend struct ExecutorBlocking::blocking_t<0>::blocking_t;
626 friend struct ExecutorRelationship::relationship_t<0>::relationship_t;
627 friend struct ExecutorOutstandingWork::outstanding_work_t<0>::outstanding_work_t;
628 friend struct ExecutorBulkGuarantee::bulk_guarantee_t<0>::bulk_guarantee_t;
629 friend struct ExecutorOccupancy::occupancy_t<0>::occupancy_t;
630
632 [[nodiscard]] static constexpr ExecutorMapping::other_t query(ExecutorMapping) noexcept { return ExecutorMapping::other; }
633
635 [[nodiscard]] static constexpr ExecutorBlocking::always_t query(ExecutorBlocking) noexcept { return ExecutorBlocking::always; }
636
638 [[nodiscard]] static constexpr ExecutorRelationship::continuation_t query(ExecutorRelationship) noexcept { return ExecutorRelationship::continuation; }
639
641 [[nodiscard]] static constexpr ExecutorOutstandingWork::untracked_t query(ExecutorOutstandingWork) noexcept {
642 return ExecutorOutstandingWork::untracked;
643 }
644
646 [[nodiscard]] static constexpr ExecutorBulkGuarantee::sequenced_t query(ExecutorBulkGuarantee) noexcept { return ExecutorBulkGuarantee::sequenced; }
647
650 [[nodiscard]] static constexpr std::size_t query(ExecutorOccupancy) noexcept { return 1; }
651
652 private:
653 friend struct asio_execution_execute_fn::impl;
654
656 template<typename Function> static constexpr void execute(Function&& f) { std::move(f)(); }
657 };
658
660 inline constexpr auto make_inline_executor() { return InlineExecutor(); }
661
662 namespace traits {
664 template<class T> struct is_inline_executor : std::conjunction<std::is_same<std::decay_t<T>, InlineExecutor>> {};
665
667 template<typename T> constexpr bool is_inline_executor_v = is_inline_executor<T>::value;
668
670 template<typename T>
671 concept inline_executor = is_inline_executor_v<T>;
672 } // namespace traits
673
674 // ---------------------------------------------------------------------------------------------
675
678 public:
680 [[nodiscard]] friend constexpr bool operator==(const ThreadExecutor& lhs, const ThreadExecutor& rhs) noexcept { return true; }
681
683 [[nodiscard]] friend constexpr bool operator!=(const ThreadExecutor& lhs, const ThreadExecutor& rhs) noexcept { return !(lhs == rhs); }
684
685 private:
686 friend struct asio_query_fn::impl;
687 friend struct asio::execution::detail::mapping_t<0>;
688 friend struct asio::execution::detail::blocking_t<0>;
689 friend struct asio::execution::detail::relationship_t<0>;
690 friend struct asio::execution::detail::outstanding_work_t<0>;
691 friend struct asio::execution::detail::bulk_guarantee_t<0>;
692 friend struct asio::execution::detail::occupancy_t<0>;
693
695 [[nodiscard]] static constexpr ExecutorMapping::new_thread_t query(ExecutorMapping) noexcept { return ExecutorMapping::new_thread; }
696
698 [[nodiscard]] static constexpr ExecutorBlocking::never_t query(ExecutorBlocking) noexcept { return ExecutorBlocking::never; }
699
701 [[nodiscard]] static constexpr ExecutorRelationship::continuation_t query(ExecutorRelationship) noexcept { return ExecutorRelationship::continuation; }
702
704 [[nodiscard]] static constexpr ExecutorOutstandingWork::untracked_t query(ExecutorOutstandingWork) noexcept {
705 return ExecutorOutstandingWork::untracked;
706 }
707
709 [[nodiscard]] static constexpr ExecutorBulkGuarantee::parallel_t query(ExecutorBulkGuarantee) noexcept { return ExecutorBulkGuarantee::parallel; }
710
713 [[nodiscard]] static constexpr std::size_t query(ExecutorOccupancy) noexcept { return hardware_concurrency(); }
714
715 private:
716 friend struct asio_execution_execute_fn::impl;
717
719 template<typename Function> static void execute(Function&& f) { (void)std::async(std::launch::async, std::move(f)); }
720 };
721
723 inline auto make_thread_executor() { return ThreadExecutor(); }
724
725 namespace traits {
727 template<class T> struct is_thread_executor : std::conjunction<std::is_same<std::decay_t<T>, ThreadExecutor>> {};
728
730 template<typename T> constexpr bool is_thread_executor_v = is_thread_executor<T>::value;
731
733 template<typename T>
734 concept thread_executor = is_thread_executor_v<T>;
735 } // namespace traits
736
737 // ---------------------------------------------------------------------------------------------
738
741
743 inline auto make_default_executor() { return DefaultExecutor(); }
744
745 namespace traits {
747 template<class T> struct is_default_executor : std::conjunction<std::is_same<std::decay_t<T>, DefaultExecutor>> {};
748
750 template<typename T> constexpr bool is_default_executor_v = is_default_executor<T>::value;
751
753 template<typename T>
754 concept default_executor = is_default_executor_v<T>;
755 } // namespace traits
756
757} // namespace CeresEngine
#define CE_ASSERT(...)
Definition Macros.hpp:323
Scope object that sets the current execution context as current.
Definition ExecutionContext.hpp:180
Scope(ExecutionContext *executionContext) noexcept
Creates a new execution context scope.
static thread_local const Scope * top
The current top-most execution context scope.
Definition ExecutionContext.hpp:185
const Scope *const mPrevious
The previously top-most execution context.
Definition ExecutionContext.hpp:192
~Scope() noexcept
Destroy the execution context scope and marks it as inactive.
ExecutionContext *const mExecutionContext
A pointer the the execution context.
Definition ExecutionContext.hpp:188
Definition ExecutionContext.hpp:96
ExecutionContext & getExecutionContext() noexcept
Returns the execution context to which the service is attached to.
Definition ExecutionContext.hpp:427
static const ID id
Definition ExecutionContext.hpp:98
AnyExecutor getExecutor() noexcept
Returns an executor that run execute scheduled commands on the context.
Definition ExecutionContext.hpp:428
A context for function object execution.
Definition ExecutionContext.hpp:90
T * getServiceIf() noexcept
Obtain the service object corresponding to the given type.
Definition ExecutionContext.hpp:147
id ID
Definition ExecutionContext.hpp:93
static ExecutionContext & get() noexcept
Gets the current execution context, if any is active.
Definition ExecutionContext.hpp:172
virtual AnyExecutor getExecutor() noexcept=0
Returns an executor that run execute scheduled commands on the context.
bool hasService() noexcept
Determine if the ExecutionContext contains the specified service type.
Definition ExecutionContext.hpp:124
bool isActive() const noexcept
Checks if the execution context is currently active.
executor_type get_executor() noexcept
Returns an executor that run execute scheduled commands on the context.
T & getService() noexcept
Obtain the service object corresponding to the given type.
Definition ExecutionContext.hpp:136
static ExecutionContext * getCurrent() noexcept
Gets the current execution context, if any is active.
An executor that runs anything inline.
Definition ExecutionContext.hpp:614
friend constexpr bool operator==(const InlineExecutor &lhs, const InlineExecutor &rhs) noexcept
Compare two executors for equality.
Definition ExecutionContext.hpp:617
static constexpr ExecutorBulkGuarantee::sequenced_t query(ExecutorBulkGuarantee) noexcept
Query the current value of the bulk_guarantee property.
Definition ExecutionContext.hpp:646
static constexpr void execute(Function &&f)
Execution function.
Definition ExecutionContext.hpp:656
static constexpr ExecutorRelationship::continuation_t query(ExecutorRelationship) noexcept
Query the current value of the relationship property.
Definition ExecutionContext.hpp:638
static constexpr ExecutorOutstandingWork::untracked_t query(ExecutorOutstandingWork) noexcept
Query the current value of the outstanding_work property.
Definition ExecutionContext.hpp:641
static constexpr ExecutorBlocking::always_t query(ExecutorBlocking) noexcept
Query the current value of the blocking property.
Definition ExecutionContext.hpp:635
friend constexpr bool operator!=(const InlineExecutor &lhs, const InlineExecutor &rhs) noexcept
Compare two executors for inequality.
Definition ExecutionContext.hpp:620
static constexpr std::size_t query(ExecutorOccupancy) noexcept
Query the occupancy (recommended number of work items) for the system context.
Definition ExecutionContext.hpp:650
void operator()(F &&f) const
Definition ExecutionContext.hpp:357
TAnyExecutor(nullptr_t) noexcept
Construct in an empty state. Equivalent effects to default constructor.
Definition ExecutionContext.hpp:335
~TAnyExecutor()=default
Destructor.
AnyExecutorBase< Properties... > super
Definition ExecutionContext.hpp:311
TAnyExecutor() noexcept=default
Default constructor.
TAnyExecutor & operator=(nullptr_t)
Assignment operator that sets the polymorphic wrapper to the empty state.
Definition ExecutionContext.hpp:338
void swap(TAnyExecutor &other) noexcept
Swap targets with another polymorphic wrapper.
Definition ExecutionContext.hpp:347
An executor that runs anything in a new thread, like std::async does.
Definition ExecutionContext.hpp:677
static constexpr ExecutorOutstandingWork::untracked_t query(ExecutorOutstandingWork) noexcept
Query the current value of the outstanding_work property.
Definition ExecutionContext.hpp:704
friend constexpr bool operator!=(const ThreadExecutor &lhs, const ThreadExecutor &rhs) noexcept
Compare two executors for inequality.
Definition ExecutionContext.hpp:683
friend constexpr bool operator==(const ThreadExecutor &lhs, const ThreadExecutor &rhs) noexcept
Compare two executors for equality.
Definition ExecutionContext.hpp:680
static constexpr ExecutorBulkGuarantee::parallel_t query(ExecutorBulkGuarantee) noexcept
Query the current value of the bulk_guarantee property.
Definition ExecutionContext.hpp:709
static constexpr ExecutorBlocking::never_t query(ExecutorBlocking) noexcept
Query the current value of the blocking property.
Definition ExecutionContext.hpp:698
static constexpr std::size_t query(ExecutorOccupancy) noexcept
Query the occupancy (recommended number of work items) for the system context.
Definition ExecutionContext.hpp:713
static constexpr ExecutorMapping::new_thread_t query(ExecutorMapping) noexcept
Query the current value of the mapping property.
Definition ExecutionContext.hpp:695
static void execute(Function &&f)
Execution function.
Definition ExecutionContext.hpp:719
static constexpr ExecutorRelationship::continuation_t query(ExecutorRelationship) noexcept
Query the current value of the relationship property.
Definition ExecutionContext.hpp:701
Definition ExecutionContext.hpp:754
Definition ExecutionContext.hpp:457
Definition ExecutionContext.hpp:469
Definition ExecutionContext.hpp:445
Definition ExecutionContext.hpp:671
Definition ExecutionContext.hpp:734
constexpr bool is_executor_or_execution_context_v
A type trait that checks if a type is an executor or an ExecutionContext.
Definition ExecutionContext.hpp:465
constexpr bool is_executor_v
Definition ExecutionContext.hpp:441
constexpr bool is_default_executor_v
A type trait that checks if a type is an DefaultExecutor.
Definition ExecutionContext.hpp:750
constexpr bool is_thread_executor_v
A type trait that checks if a type is an ThreadExecutor.
Definition ExecutionContext.hpp:730
constexpr bool is_inline_executor_v
A type trait that checks if a type is an InlineExecutor.
Definition ExecutionContext.hpp:667
constexpr bool is_execution_context_v
A type trait that checks if a type is a ExecutionContext.
Definition ExecutionContext.hpp:453
Definition Application.hpp:19
constexpr auto make_inline_executor()
An executor that runs anything inline.
Definition ExecutionContext.hpp:660
constexpr std::size_t hardware_concurrency() noexcept
A version of hardware_concurrency that always returns at least 1.
Definition ExecutionContext.hpp:597
asio::execution::context_t ExecutorExecutionContext
Definition ExecutionContext.hpp:208
auto with(Executor executor)
Definition ExecutionContext.hpp:546
asio::execution::prefer_only< Property > ExecutorPreferOnly
Definition ExecutionContext.hpp:285
asio::execution::relationship_t ExecutorRelationship
Definition ExecutionContext.hpp:215
bool operator!=(const ShortAllocator< T, N, A1 > &x, const ShortAllocator< U, M, A2 > &y) noexcept
Definition Allocator.hpp:416
auto make_default_executor()
The default executor to be used when no other executor is provided.
Definition ExecutionContext.hpp:743
std::int32_t Int32
Definition DataTypes.hpp:21
asio::execution::any_executor< Properties..., ExecutorPreferOnly< ExecutorPriority >, ExecutorPreferOnly< ExecutorBlocking::possibly_t >, ExecutorPreferOnly< ExecutorBlocking::never_t >, ExecutorPreferOnly< ExecutorOutstandingWork::tracked_t >, ExecutorPreferOnly< ExecutorOutstandingWork::untracked_t >, ExecutorPreferOnly< ExecutorRelationship::fork_t >, ExecutorPreferOnly< ExecutorRelationship::continuation_t >, ExecutorPreferOnly< ExecutorBulkGuarantee::parallel_t >, ExecutorPreferOnly< ExecutorBulkGuarantee::sequenced_t >, ExecutorPreferOnly< ExecutorBulkGuarantee::unsequenced_t > > AnyExecutorBase
Definition ExecutionContext.hpp:305
asio::execution::mapping_t ExecutorMapping
Definition ExecutionContext.hpp:211
TAnyExecutor<> AnyExecutor
Definition Forward.hpp:15
asio::strand< Executor > TStrand
Definition ExecutionContext.hpp:431
asio::execution::bulk_guarantee_t ExecutorBulkGuarantee
Definition ExecutionContext.hpp:214
asio::execution::occupancy_t ExecutorOccupancy
Definition ExecutionContext.hpp:212
auto make_thread_executor()
An executor that runs anything in a new thread, like std::async does.
Definition ExecutionContext.hpp:723
FunctionBase< true, true, fu2::capacity_default, true, false, Signatures... > Function
An owning copyable function wrapper for arbitrary callable types.
Definition Function.hpp:54
bool operator==(const ShortAllocator< T, N, A1 > &x, const ShortAllocator< U, M, A2 > &y) noexcept
Definition Allocator.hpp:411
decltype(auto) defer(Executor executor, F &&func)
Definition ExecutionContext.hpp:474
asio::execution::allocator_t< T > ExecutorAllocator
Definition ExecutionContext.hpp:216
asio::execution::blocking_t ExecutorBlocking
Definition ExecutionContext.hpp:210
asio::executor_work_guard< AnyExecutor > ExecutorWorkGuard
Definition ExecutionContext.hpp:566
TStrand< AnyExecutor > Strand
Definition ExecutionContext.hpp:434
asio::execution::context_as_t< T > ExecutorExecutionContextAs
Definition ExecutionContext.hpp:209
asio::execution::outstanding_work_t ExecutorOutstandingWork
Definition ExecutionContext.hpp:213
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Definition Span.hpp:668
Determines the priority to which an executor should schedule its tasks.
Definition ExecutionContext.hpp:220
friend constexpr ExecutorPriority operator+(const ExecutorPriority &lhs, const Int32 rhs) noexcept
Definition ExecutionContext.hpp:228
Int32 raw
The raw priority value.
Definition ExecutionContext.hpp:222
static const ExecutorPriority High
The default value for high-priority tasks.
Definition ExecutionContext.hpp:253
static const ExecutorPriority Lowest
The lowest possible executor priority value,.
Definition ExecutionContext.hpp:244
friend constexpr bool operator>=(const ExecutorPriority &lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:241
friend constexpr ExecutorPriority operator+(const Int32 lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:227
friend constexpr bool operator>(const ExecutorPriority &lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:239
constexpr ExecutorPriority() noexcept=default
friend constexpr bool operator!=(const ExecutorPriority &lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:236
friend constexpr bool operator==(const ExecutorPriority &lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:235
friend constexpr bool operator<(const ExecutorPriority &lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:238
static constexpr ExecutorPriority interpolate(const double priority, const ExecutorPriority &lowest, const ExecutorPriority &highest)
Creates a new priority from an a priority range from 0.0 to 1.0, where 0.0 is the lowest priority and...
Definition ExecutionContext.hpp:267
friend constexpr ExecutorPriority operator-(const Int32 lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:230
friend constexpr ExecutorPriority operator-(const ExecutorPriority &lhs, const Int32 rhs) noexcept
Definition ExecutionContext.hpp:231
static const ExecutorPriority Highest
The highest possible executor priority value,.
Definition ExecutionContext.hpp:256
static const ExecutorPriority Normal
The default value for regular tasks.
Definition ExecutionContext.hpp:250
static constexpr ExecutorPriority interpolate(const double priority)
Creates a new priority from an a priority range from 0.0 to 1.0, where 0.0 is the lowest priority pos...
Definition ExecutionContext.hpp:262
friend constexpr Int32 operator-(const ExecutorPriority &lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:233
static const ExecutorPriority Low
The default value for low-priority tasks.
Definition ExecutionContext.hpp:247
friend constexpr bool operator<=(const ExecutorPriority &lhs, const ExecutorPriority &rhs) noexcept
Definition ExecutionContext.hpp:240
A type trait that checks if a type is an DefaultExecutor.
Definition ExecutionContext.hpp:747
A type trait that checks if a type is a ExecutionContext.
Definition ExecutionContext.hpp:450
A type trait that checks if a type is an executor or an ExecutionContext.
Definition ExecutionContext.hpp:462
A type trait that checks if a type is an InlineExecutor.
Definition ExecutionContext.hpp:664
A type trait that checks if a type is an ThreadExecutor.
Definition ExecutionContext.hpp:727