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>
22#include <asio/any_io_executor.hpp>
23#include <asio/execution/execute.hpp>
96 template<
typename T>
class Service :
public service {
99 using service::service;
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;
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()};
287 template<
typename... Properties>
330 template<typename Executor>
354 using super::execute;
358 asio::execution::execute(*
this, [f = std::forward<F>(f)]()
mutable { std::forward<F>(f)(); });
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);
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);
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);
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; }
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(); }
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(); }
420 [[nodiscard]] super& base() noexcept {
return *
this; }
421 [[nodiscard]]
const super& base() const noexcept {
return *
this; }
431 template<
typename Executor>
using TStrand = asio::strand<Executor>;
438 using asio::execution::is_executor;
474 template<traits::executor Executor,
typename F>
decltype(
auto)
defer(Executor executor, F&& func) {
476 return asio::defer(executor, std::forward<F>(func));
481 return asio::defer(executionContext.
getExecutor(), std::forward<F>(func));
484 template<
typename F>
decltype(
auto)
defer(F&& func) {
486 return asio::defer(ExecutionContext::get(), std::forward<F>(func));
540 using asio::dispatch;
542 using asio::execution::execute;
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 {
558 template<traits::executor Executor,
typename Func>
auto with(Executor executor, Func&& func) {
559 return with(std::move(executor)).then(std::forward<Func>(func));
563 return with(context).then(std::forward<Func>(func));
568 using asio::can_prefer;
569 using asio::can_prefer_v;
572 using asio::can_query;
573 using asio::can_query_v;
576 using asio::can_require;
577 using asio::can_require_v;
599 if(std::is_constant_evaluated()) {
603 return (std::max)(std::size_t(1), std::size_t(std::thread::hardware_concurrency()));
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;
632 [[nodiscard]] static constexpr ExecutorMapping::other_t query(ExecutorMapping) noexcept {
return ExecutorMapping::other; }
635 [[nodiscard]]
static constexpr ExecutorBlocking::always_t
query(
ExecutorBlocking)
noexcept {
return ExecutorBlocking::always; }
638 [[nodiscard]]
static constexpr ExecutorRelationship::continuation_t
query(
ExecutorRelationship)
noexcept {
return ExecutorRelationship::continuation; }
642 return ExecutorOutstandingWork::untracked;
646 [[nodiscard]]
static constexpr ExecutorBulkGuarantee::sequenced_t
query(
ExecutorBulkGuarantee)
noexcept {
return ExecutorBulkGuarantee::sequenced; }
653 friend struct asio_execution_execute_fn::impl;
656 template<
typename Function>
static constexpr void execute(
Function&& f) { std::move(f)(); }
664 template<
class T>
struct is_inline_executor : std::conjunction<std::is_same<std::decay_t<T>, InlineExecutor>> {};
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>;
695 [[nodiscard]]
static constexpr ExecutorMapping::new_thread_t
query(
ExecutorMapping)
noexcept {
return ExecutorMapping::new_thread; }
698 [[nodiscard]]
static constexpr ExecutorBlocking::never_t
query(
ExecutorBlocking)
noexcept {
return ExecutorBlocking::never; }
701 [[nodiscard]]
static constexpr ExecutorRelationship::continuation_t
query(
ExecutorRelationship)
noexcept {
return ExecutorRelationship::continuation; }
705 return ExecutorOutstandingWork::untracked;
709 [[nodiscard]]
static constexpr ExecutorBulkGuarantee::parallel_t
query(
ExecutorBulkGuarantee)
noexcept {
return ExecutorBulkGuarantee::parallel; }
716 friend struct asio_execution_execute_fn::impl;
719 template<
typename Function>
static void execute(
Function&& f) { (void)std::async(std::launch::async, std::move(f)); }
727 template<
class T>
struct is_thread_executor : std::conjunction<std::is_same<std::decay_t<T>, ThreadExecutor>> {};
747 template<
class T>
struct is_default_executor : std::conjunction<std::is_same<std::decay_t<T>, DefaultExecutor>> {};
#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
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