threadman 0.1.0
Header-only C++23 managed threads, dynamic pools, futures, and executors
Loading...
Searching...
No Matches
executor.hpp
Go to the documentation of this file.
1#pragma once
2
13
14#include <threadman/display.hpp>
15#include <threadman/log.hpp>
16
17#include <commons/display_info.hpp>
18
19#include <concepts>
20#include <functional>
21#include <memory>
22#include <string>
23#include <string_view>
24#include <utility>
25
26namespace threadman {
27
29class IExecutor {
30public:
31 virtual ~IExecutor() = default;
32 virtual void execute(std::function<void()> task) = 0;
33 [[nodiscard]] virtual std::string_view name() const noexcept = 0;
34};
35
39template <class E>
40concept Executor = requires(E& e, std::function<void()> f) {
41 { e.execute(std::move(f)) } -> std::same_as<void>;
42};
43
44namespace detail {
45
48inline void execute_on(IExecutor& exec, std::function<void()> task) {
49 exec.execute(std::move(task));
50}
51
52template <class Exec>
53 requires(Executor<Exec> && !std::is_same_v<Exec, IExecutor>)
54inline void execute_on(Exec& exec, std::function<void()> task) {
55 exec.execute(std::move(task));
56}
57
58} // namespace detail
59
63class InlineExecutor final : public IExecutor {
64public:
65 [[nodiscard]] static InlineExecutor& instance() noexcept {
66 static InlineExecutor inst;
67 return inst;
68 }
69
70 void execute(const std::function<void()> task) override {
71 if (task) {
72 task();
73 }
74 }
75
76 [[nodiscard]] std::string_view name() const noexcept override {
77 return "inline";
78 }
79
80 [[nodiscard]] static const comms::DisplayInfo& display_info() {
81 static const comms::DisplayInfo info{
82 .name = "InlineExecutor",
83 .description = "Executor that runs tasks synchronously on the calling thread.",
84 .icon = comms::Icon::from("mdi:flash"),
85 };
86 return info;
87 }
88
89private:
90 InlineExecutor() = default;
91};
92
95template <class Exec>
96 requires Executor<Exec>
97class ExecutorRef final : public IExecutor {
98public:
99 explicit ExecutorRef(Exec& e, std::string nm = {}) noexcept : exec_(&e), name_(std::move(nm)) {}
100
101 void execute(std::function<void()> task) override {
102 exec_->execute(std::move(task));
103 }
104 [[nodiscard]] std::string_view name() const noexcept override {
105 return name_.empty() ? std::string_view{"executor-ref"} : std::string_view{name_};
106 }
107
108private:
109 Exec* exec_;
110 std::string name_;
111};
112
113} // namespace threadman
Wraps any Executor-conforming type behind the virtual IExecutor interface, so functions that take IEx...
Definition executor.hpp:97
std::string_view name() const noexcept override
Definition executor.hpp:104
ExecutorRef(Exec &e, std::string nm={}) noexcept
Definition executor.hpp:99
void execute(std::function< void()> task) override
Definition executor.hpp:101
Virtual interface for "anything that can run a `std::function<void()>`".
Definition executor.hpp:29
virtual std::string_view name() const noexcept=0
virtual void execute(std::function< void()> task)=0
virtual ~IExecutor()=default
Runs task() synchronously on the calling thread.
Definition executor.hpp:63
std::string_view name() const noexcept override
Definition executor.hpp:76
void execute(const std::function< void()> task) override
Definition executor.hpp:70
static InlineExecutor & instance() noexcept
Definition executor.hpp:65
static const comms::DisplayInfo & display_info()
Definition executor.hpp:80
Duck-typed alternative to IExecutor for templated code that wants to avoid a virtual call.
Definition executor.hpp:40
Re-export <commons/display_info.hpp> and attach non-intrusive comms::HasDisplayInfo<> specializations...
Cached subsystem loggers for the tm.
void execute_on(IExecutor &exec, std::function< void()> task)
Dispatch helper used by Future::then / SharedFuture::then.
Definition executor.hpp:48
Definition exceptions.hpp:22