ThreadSchedule 3.0.0
Modern C++ thread management library
Loading...
Searching...
No Matches
function_ref.hpp
Go to the documentation of this file.
1#pragma once
2
9
10#include <functional>
11#include <memory>
12#include <type_traits>
13#include <utility>
14
16{
17
18template <typename Signature>
20
21template <typename R, typename... Args>
22class function_ref<R(Args...)>
23{
24public:
25 function_ref() = delete;
26
27 function_ref(R (*fn)(Args...)) noexcept : function_(fn)
28 {
29 callback_ = [](void*, R (*function)(Args...), Args... args) -> R
30 {
31 if constexpr (std::is_void_v<R>)
32 {
33 function(std::forward<Args>(args)...);
34 return;
35 }
36 else
37 {
38 return function(std::forward<Args>(args)...);
39 }
40 };
41 }
42
43 template <typename F, typename = std::enable_if_t<!std::is_same_v<remove_cvref_t<F>, function_ref>
44 && std::is_invocable_r_v<R, F&, Args...>>>
45 function_ref(F&& fn) noexcept : object_(const_cast<void*>(static_cast<void const*>(std::addressof(fn))))
46 {
47 callback_ = [](void* object, R (*)(Args...), Args... args) -> R
48 {
49 auto& callable = *static_cast<remove_cvref_t<F>*>(object);
50 if constexpr (std::is_void_v<R>)
51 {
52 callable(std::forward<Args>(args)...);
53 return;
54 }
55 else
56 {
57 return callable(std::forward<Args>(args)...);
58 }
59 };
60 }
61
62 auto
63 operator()(Args... args) const -> R
64 {
65 if constexpr (std::is_void_v<R>)
66 {
67 callback_(object_, function_, std::forward<Args>(args)...);
68 return;
69 }
70 else
71 {
72 return callback_(object_, function_, std::forward<Args>(args)...);
73 }
74 }
75
76private:
77 void* object_ = nullptr;
78 R (*function_)(Args...) = nullptr;
79 R (*callback_)(void*, R (*)(Args...), Args...);
80};
81
82} // namespace threadschedule::detail
Aggregates multiple thread_registry_backend instances into a single queryable view.
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t