DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
Func.h
Go to the documentation of this file.
1
5
6#pragma once
7#include <type_traits>
8#include <utility>
9
10namespace DotNetDupe {
11 namespace System {
12 namespace Internal {
14 template <typename TResult, typename... Args>
16 virtual ~IFunctorHolder() = default;
17 virtual TResult Invoke(Args... args) = 0;
18 virtual IFunctorHolder* Clone() const = 0;
19 };
20
22 template <typename F, typename TResult, typename... Args>
23 struct FunctorHolder : IFunctorHolder<TResult, Args...> {
25 FunctorHolder(const F& fn) : m_fn(fn) {}
26 FunctorHolder(F&& fn) : m_fn(static_cast<F&&>(fn)) {}
27
28 TResult Invoke(Args... args) override {
29 return m_fn(args...);
30 }
31
32 IFunctorHolder<TResult, Args...>* Clone() const override {
33 return new FunctorHolder<F, TResult, Args...>(m_fn);
34 }
35 };
36 }
37
41 template<typename TResult, typename... Args>
42 class Func;
43
49 template<typename TResult>
50 class Func<TResult> {
51 public:
53 Func() : m_pHolder(nullptr) {}
54
56 Func(decltype(nullptr)) : m_pHolder(nullptr) {}
57
61 template<typename F, typename = std::enable_if_t<!std::is_same_v<std::decay_t<F>, Func> && std::is_invocable_r_v<TResult, std::decay_t<F>>>>
62 Func(F&& func) : m_pHolder(new Internal::FunctorHolder<std::decay_t<F>, TResult>(static_cast<F&&>(func))) {}
63
66 Func(const Func& other) : m_pHolder(other.m_pHolder ? other.m_pHolder->Clone() : nullptr) {}
67
70 Func(Func&& other) noexcept : m_pHolder(other.m_pHolder) {
71 other.m_pHolder = nullptr;
72 }
73
77 Func& operator=(const Func& other) {
78 if (this != &other) {
79 delete m_pHolder;
80 m_pHolder = other.m_pHolder ? other.m_pHolder->Clone() : nullptr;
81 }
82 return *this;
83 }
84
88 Func& operator=(Func&& other) noexcept {
89 if (this != &other) {
90 delete m_pHolder;
91 m_pHolder = other.m_pHolder;
92 other.m_pHolder = nullptr;
93 }
94 return *this;
95 }
96
99 delete m_pHolder;
100 m_pHolder = nullptr;
101 }
102
105 TResult Invoke() const {
106 if (m_pHolder) return m_pHolder->Invoke();
107 return TResult();
108 }
109
112 TResult operator()() const {
113 return Invoke();
114 }
115
118 explicit operator bool() const { return m_pHolder != nullptr; }
119
120 private:
122 };
123
132 template<typename TResult, typename Arg1, typename... Args>
133 class Func<TResult, Arg1, Args...> {
134 public:
136 Func() : m_pHolder(nullptr) {}
137
139 Func(decltype(nullptr)) : m_pHolder(nullptr) {}
140
144 template<typename F, typename = std::enable_if_t<!std::is_same_v<std::decay_t<F>, Func> && std::is_invocable_r_v<TResult, std::decay_t<F>, Arg1, Args...>>>
145 Func(F&& func) : m_pHolder(new Internal::FunctorHolder<std::decay_t<F>, TResult, Arg1, Args...>(static_cast<F&&>(func))) {}
146
149 Func(const Func& other) : m_pHolder(other.m_pHolder ? other.m_pHolder->Clone() : nullptr) {}
150
153 Func(Func&& other) noexcept : m_pHolder(other.m_pHolder) {
154 other.m_pHolder = nullptr;
155 }
156
160 Func& operator=(const Func& other) {
161 if (this != &other) {
162 delete m_pHolder;
163 m_pHolder = other.m_pHolder ? other.m_pHolder->Clone() : nullptr;
164 }
165 return *this;
166 }
167
171 Func& operator=(Func&& other) noexcept {
172 if (this != &other) {
173 delete m_pHolder;
174 m_pHolder = other.m_pHolder;
175 other.m_pHolder = nullptr;
176 }
177 return *this;
178 }
179
182 delete m_pHolder;
183 m_pHolder = nullptr;
184 }
185
190 TResult Invoke(Arg1 arg1, Args... args) const {
191 if (m_pHolder) return m_pHolder->Invoke(arg1, args...);
192 return TResult();
193 }
194
199 TResult operator()(Arg1 arg1, Args... args) const {
200 return Invoke(arg1, args...);
201 }
202
205 explicit operator bool() const { return m_pHolder != nullptr; }
206
207 private:
208 Internal::IFunctorHolder<TResult, Arg1, Args...>* m_pHolder;
209 };
210 }
211}
TResult operator()(Arg1 arg1, Args... args) const
Function call operator forwarding to Invoke().
Definition Func.h:199
Func & operator=(const Func &other)
Copy assignment operator.
Definition Func.h:160
TResult Invoke(Arg1 arg1, Args... args) const
Invokes the encapsulated method with specified parameters and returns the result.
Definition Func.h:190
Func(F &&func)
Constructs a Func delegate from an invocable callable object or lambda.
Definition Func.h:145
Func & operator=(Func &&other) noexcept
Move assignment operator.
Definition Func.h:171
Func(decltype(nullptr))
Initializes an empty instance from a null pointer.
Definition Func.h:139
~Func()
Destructor releasing functor resources.
Definition Func.h:181
Func()
Initializes an empty instance of the parameterized Func delegate.
Definition Func.h:136
Func(const Func &other)
Copy constructor.
Definition Func.h:149
Func(Func &&other) noexcept
Move constructor.
Definition Func.h:153
Func()
Initializes an empty instance of the Func delegate.
Definition Func.h:53
Func(F &&func)
Constructs a Func delegate from an invocable callable object or lambda.
Definition Func.h:62
~Func()
Destructor releasing functor resources.
Definition Func.h:98
Func & operator=(const Func &other)
Copy assignment operator.
Definition Func.h:77
TResult operator()() const
Function call operator forwarding to Invoke().
Definition Func.h:112
Func(const Func &other)
Copy constructor.
Definition Func.h:66
Func & operator=(Func &&other) noexcept
Move assignment operator.
Definition Func.h:88
TResult Invoke() const
Invokes the encapsulated method and returns the result.
Definition Func.h:105
Func(decltype(nullptr))
Initializes an empty instance from a null pointer.
Definition Func.h:56
Func(Func &&other) noexcept
Move constructor.
Definition Func.h:70
Primary template declaration for the Func delegate family.
Definition Func.h:42
TResult Invoke(Args... args) override
Definition Func.h:28
IFunctorHolder< TResult, Args... > * Clone() const override
Definition Func.h:32
Internal interface defining type-erased functor execution and cloning.
Definition Func.h:15
virtual TResult Invoke(Args... args)=0
virtual IFunctorHolder * Clone() const =0