ThreadSchedule 2.2.0
Modern C++ thread management library
Loading...
Searching...
No Matches
inline_pool.hpp
Go to the documentation of this file.
1#pragma once
2
12
13#include "expected.hpp"
14#include "thread_pool.hpp"
15#include <functional>
16#include <future>
17#include <system_error>
18#include <type_traits>
19#include <vector>
20
21namespace threadschedule
22{
23
43{
44 public:
45 explicit InlinePool(size_t /*num_threads*/ = 0)
46 {
47 }
48
49 template <typename F, typename... Args>
50 auto submit(F&& f, Args&&... args) -> std::future<std::invoke_result_t<F, Args...>>
51 {
52 auto result = try_submit(std::forward<F>(f), std::forward<Args>(args)...);
53 if (!result.has_value())
54 throw std::runtime_error("InlinePool is shut down");
55 return std::move(result.value());
56 }
57
58 template <typename F, typename... Args>
59 auto try_submit(F&& f, Args&&... args) -> expected<std::future<std::invoke_result_t<F, Args...>>, std::error_code>
60 {
61 using R = std::invoke_result_t<F, Args...>;
62 if (stop_)
63 return unexpected(std::make_error_code(std::errc::operation_canceled));
64
65 std::promise<R> p;
66 auto future = p.get_future();
67 try
68 {
69 if constexpr (std::is_void_v<R>)
70 {
71 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
72 p.set_value();
73 }
74 else
75 {
76 p.set_value(std::invoke(std::forward<F>(f), std::forward<Args>(args)...));
77 }
78 }
79 catch (...)
80 {
81 p.set_exception(std::current_exception());
82 }
83 return future;
84 }
85
86 template <typename F, typename... Args>
87 void post(F&& f, Args&&... args)
88 {
89 auto r = try_post(std::forward<F>(f), std::forward<Args>(args)...);
90 if (!r.has_value())
91 throw std::runtime_error("InlinePool is shut down");
92 }
93
94 template <typename F, typename... Args>
95 auto try_post(F&& f, Args&&... args) -> expected<void, std::error_code>
96 {
97 if (stop_)
98 return unexpected(std::make_error_code(std::errc::operation_canceled));
99 try
100 {
101 std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
102 }
103 catch (...)
104 {
105 }
106 return {};
107 }
108
109 template <typename Iterator>
110 auto try_submit_batch(Iterator begin, Iterator end) -> expected<std::vector<std::future<void>>, std::error_code>
111 {
112 if (stop_)
113 return unexpected(std::make_error_code(std::errc::operation_canceled));
114
115 std::vector<std::future<void>> futures;
116 for (auto it = begin; it != end; ++it)
117 {
118 std::promise<void> p;
119 futures.push_back(p.get_future());
120 try
121 {
122 (*it)();
123 p.set_value();
124 }
125 catch (...)
126 {
127 p.set_exception(std::current_exception());
128 }
129 }
130 return futures;
131 }
132
133 template <typename Iterator>
134 auto submit_batch(Iterator begin, Iterator end) -> std::vector<std::future<void>>
135 {
136 auto result = try_submit_batch(begin, end);
137 if (!result.has_value())
138 throw std::runtime_error("InlinePool is shut down");
139 return std::move(result.value());
140 }
141
142 template <typename Iterator, typename F>
143 void parallel_for_each(Iterator begin, Iterator end, F&& func)
144 {
145 for (auto it = begin; it != end; ++it)
146 func(*it);
147 }
148
149 [[nodiscard]] auto size() const noexcept -> size_t { return 0; }
150 [[nodiscard]] auto pending_tasks() const noexcept -> size_t { return 0; }
151
153 void shutdown(ShutdownPolicy /*policy*/ = ShutdownPolicy::drain) { stop_ = true; }
154
155 private:
156 bool stop_{false};
157};
158
159} // namespace threadschedule
auto submit(F &&f, Args &&... args) -> std::future< std::invoke_result_t< F, Args... > >
auto pending_tasks() const noexcept -> size_t
void shutdown(ShutdownPolicy=ShutdownPolicy::drain)
auto size() const noexcept -> size_t
auto try_post(F &&f, Args &&... args) -> expected< void, std::error_code >
auto try_submit_batch(Iterator begin, Iterator end) -> expected< std::vector< std::future< void > >, std::error_code >
void post(F &&f, Args &&... args)
void parallel_for_each(Iterator begin, Iterator end, F &&func)
auto try_submit(F &&f, Args &&... args) -> expected< std::future< std::invoke_result_t< F, Args... > >, std::error_code >
auto submit_batch(Iterator begin, Iterator end) -> std::vector< std::future< void > >
A result type that holds either a value of type T or an error of type E.
Definition expected.hpp:215
Exception thrown by expected::value() when the object is in the error state.
Definition expected.hpp:162
Polyfill for std::expected (C++23) for pre-C++23 compilers.
ShutdownPolicy
Controls how a pool handles pending tasks during shutdown.
@ drain
Finish all queued tasks before stopping (default).
Thread pools: HighPerformancePool, ThreadPoolBase, LightweightPoolT, and GlobalPool.