Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
thread_concepts.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
25#include <type_traits>
26#include <functional>
27#include <chrono>
28#include <string>
29
30#ifdef USE_STD_CONCEPTS
31#include <concepts>
32#endif
33
35
36// ============================================================================
37// Type Traits (always available)
38// ============================================================================
39
43template<typename T>
44struct is_duration : std::false_type {};
45
46template<typename Rep, typename Period>
47struct is_duration<std::chrono::duration<Rep, Period>> : std::true_type {};
48
49template<typename T>
50inline constexpr bool is_duration_v = is_duration<T>::value;
51
55template<typename T, typename = void>
56struct has_get_method : std::false_type {};
57
58template<typename T>
59struct has_get_method<T, std::void_t<decltype(std::declval<T>().get())>>
60 : std::true_type {};
61
62template<typename T>
64
68template<typename T, typename = void>
69struct has_wait_method : std::false_type {};
70
71template<typename T>
72struct has_wait_method<T, std::void_t<decltype(std::declval<T>().wait())>>
73 : std::true_type {};
74
75template<typename T>
77
81template<typename T>
82struct is_future_like : std::bool_constant<has_get_method_v<T> && has_wait_method_v<T>> {};
83
84template<typename T>
85inline constexpr bool is_future_like_v = is_future_like<T>::value;
86
90template<typename F, typename = void>
92 using type = void;
93};
94
95template<typename F>
96struct callable_return_type<F, std::enable_if_t<std::is_invocable_v<F>>> {
97 using type = std::invoke_result_t<F>;
98};
99
100template<typename F>
102
103// ============================================================================
104// C++20 Concepts (when USE_STD_CONCEPTS is defined)
105// ============================================================================
106
107#ifdef USE_STD_CONCEPTS
108
112template<typename F>
113concept Callable = std::is_invocable_v<F>;
114
118template<typename F>
119concept VoidCallable = Callable<F> && std::is_void_v<std::invoke_result_t<F>>;
120
124template<typename F>
125concept ReturningCallable = Callable<F> && !std::is_void_v<std::invoke_result_t<F>>;
126
130template<typename F, typename... Args>
131concept CallableWith = std::is_invocable_v<F, Args...>;
132
136template<typename T>
137concept Duration = is_duration_v<T>;
138
142template<typename T>
143concept FutureLike = is_future_like_v<T>;
144
154template<typename T>
155concept JobType = std::is_enum_v<T> ||
156 (std::is_integral_v<T> && !std::is_same_v<T, bool>);
157
165template<typename F>
166concept JobCallable = std::is_invocable_v<F> &&
167 (std::is_void_v<std::invoke_result_t<F>> ||
168 std::is_same_v<std::invoke_result_t<F>, bool> ||
169 std::is_convertible_v<std::invoke_result_t<F>, std::string>);
170
178template<typename Job>
179concept PoolJob = Callable<Job> &&
181 std::is_convertible_v<callable_return_type_t<Job>, bool>);
182
183#else
184// ============================================================================
185// C++17 Fallback (constexpr bool instead of concepts)
186// ============================================================================
187
191template<typename F>
192inline constexpr bool Callable = std::is_invocable_v<F>;
193
197template<typename F>
198inline constexpr bool VoidCallable = std::is_invocable_v<F> &&
199 std::is_void_v<std::invoke_result_t<F>>;
200
204template<typename F>
205inline constexpr bool ReturningCallable = std::is_invocable_v<F> &&
206 !std::is_void_v<std::invoke_result_t<F>>;
207
211template<typename F, typename... Args>
212inline constexpr bool CallableWith = std::is_invocable_v<F, Args...>;
213
217template<typename T>
218inline constexpr bool Duration = is_duration_v<T>;
219
223template<typename T>
224inline constexpr bool FutureLike = is_future_like_v<T>;
225
229template<typename T>
230inline constexpr bool JobType = std::is_enum_v<T> ||
231 (std::is_integral_v<T> && !std::is_same_v<T, bool>);
232
236template<typename F>
237inline constexpr bool JobCallable = std::is_invocable_v<F> &&
238 (std::is_void_v<std::invoke_result_t<F>> ||
239 std::is_same_v<std::invoke_result_t<F>, bool> ||
240 std::is_convertible_v<std::invoke_result_t<F>, std::string>);
241
245template<typename Job>
246inline constexpr bool PoolJob = Callable<Job> &&
248 std::is_convertible_v<callable_return_type_t<Job>, bool>);
249
250#endif // USE_STD_CONCEPTS
251
252// ============================================================================
253// Concept Validation Helpers
254// ============================================================================
255
259template<typename T, typename = void>
260struct is_valid_job_type : std::false_type {};
261
262template<typename T>
263struct is_valid_job_type<T, std::enable_if_t<JobType<T>>> : std::true_type {};
264
265template<typename T>
266inline constexpr bool is_valid_job_type_v = is_valid_job_type<T>::value;
267
271template<typename F>
272struct is_nothrow_callable : std::bool_constant<std::is_nothrow_invocable_v<F>> {};
273
274template<typename F>
275inline constexpr bool is_nothrow_callable_v = is_nothrow_callable<F>::value;
276
277} // namespace kcenon::thread::concepts
278
279// ============================================================================
280// Backward Compatibility: Re-export to detail namespace
281// ============================================================================
282
283namespace kcenon::thread::detail {
284
295
296#ifdef USE_STD_CONCEPTS
306#else
307// For C++17 fallback, we need to use inline constexpr
308template<typename F>
309inline constexpr bool Callable = concepts::Callable<F>;
310
311template<typename F>
313
314template<typename F>
316
317template<typename F, typename... Args>
318inline constexpr bool CallableWith = concepts::CallableWith<F, Args...>;
319
320template<typename T>
321inline constexpr bool Duration = concepts::Duration<T>;
322
323template<typename T>
324inline constexpr bool FutureLike = concepts::FutureLike<T>;
325
326template<typename T>
327inline constexpr bool JobType = concepts::JobType<T>;
328
329template<typename F>
330inline constexpr bool JobCallable = concepts::JobCallable<F>;
331
332template<typename Job>
333inline constexpr bool PoolJob = concepts::PoolJob<Job>;
334#endif
335
336} // namespace kcenon::thread::detail
typename callable_return_type< F >::type callable_return_type_t
constexpr bool has_wait_method_v
constexpr bool ReturningCallable
Fallback for ReturningCallable concept.
constexpr bool Callable
Fallback for Callable concept.
constexpr bool JobCallable
Fallback for JobCallable concept.
constexpr bool VoidCallable
Fallback for VoidCallable concept.
constexpr bool FutureLike
Fallback for FutureLike concept.
constexpr bool PoolJob
Fallback for PoolJob concept.
constexpr bool CallableWith
Fallback for CallableWith concept.
constexpr bool is_future_like_v
constexpr bool is_valid_job_type_v
constexpr bool has_get_method_v
constexpr bool JobType
Fallback for JobType concept.
constexpr bool is_nothrow_callable_v
constexpr bool Duration
Fallback for Duration concept.
constexpr bool CallableWith
constexpr bool VoidCallable
constexpr bool ReturningCallable
STL namespace.
Type trait to extract return type from a callable.
SFINAE helper to detect if a type has a get() method.
SFINAE helper to detect if a type has a wait() method.
Type trait to detect if a type is a std::chrono::duration.
Type trait to detect future-like types (has get() and wait() methods)
Helper to check if a callable is noexcept.
SFINAE helper for JobType validation.