DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
Action.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 {
15 template <typename... Args>
17 virtual ~IActionHolder() = default;
18 virtual void Invoke(Args... args) = 0;
19 virtual IActionHolder* Clone() const = 0;
20 };
21
24 template <typename F, typename... Args>
25 struct ActionHolder : IActionHolder<Args...> {
27 ActionHolder(const F& fn) : m_fn(fn) {}
28 ActionHolder(F&& fn) : m_fn(static_cast<F&&>(fn)) {}
29
30 void Invoke(Args... args) override {
31 m_fn(args...);
32 }
33
34 IActionHolder<Args...>* Clone() const override {
35 return new ActionHolder<F, Args...>(m_fn);
36 }
37 };
38 }
39
45 template<typename... Args>
46 class Action;
47
50 template<>
51 class Action<> {
52 public:
54 Action() : m_pHolder(nullptr) {}
55
57 Action(decltype(nullptr)) : m_pHolder(nullptr) {}
58
62 template<typename F, typename = std::enable_if_t<!std::is_same_v<std::decay_t<F>, Action> && std::is_invocable_v<std::decay_t<F>>>>
63 Action(F&& func) : m_pHolder(new Internal::ActionHolder<std::decay_t<F>>(static_cast<F&&>(func))) {}
64
67 Action(const Action& other) : m_pHolder(other.m_pHolder ? other.m_pHolder->Clone() : nullptr) {}
68
71 Action(Action&& other) noexcept : m_pHolder(other.m_pHolder) {
72 other.m_pHolder = nullptr;
73 }
74
76 Action& operator=(const Action& other) {
77 if (this != &other) {
78 delete m_pHolder;
79 m_pHolder = other.m_pHolder ? other.m_pHolder->Clone() : nullptr;
80 }
81 return *this;
82 }
83
85 Action& operator=(Action&& other) noexcept {
86 if (this != &other) {
87 delete m_pHolder;
88 m_pHolder = other.m_pHolder;
89 other.m_pHolder = nullptr;
90 }
91 return *this;
92 }
93
96 delete m_pHolder;
97 m_pHolder = nullptr;
98 }
99
101 void Invoke() const {
102 if (m_pHolder) m_pHolder->Invoke();
103 }
104
106 void operator()() const {
107 Invoke();
108 }
109
111 explicit operator bool() const { return m_pHolder != nullptr; }
112
113 private:
114 Internal::IActionHolder<>* m_pHolder;
115 };
116
119 template<typename Arg1, typename... Args>
120 class Action<Arg1, Args...> {
121 public:
123 Action() : m_pHolder(nullptr) {}
124
126 Action(decltype(nullptr)) : m_pHolder(nullptr) {}
127
129 template<typename F, typename = std::enable_if_t<!std::is_same_v<std::decay_t<F>, Action> && std::is_invocable_v<std::decay_t<F>, Arg1, Args...>>>
130 Action(F&& func) : m_pHolder(new Internal::ActionHolder<std::decay_t<F>, Arg1, Args...>(static_cast<F&&>(func))) {}
131
133 Action(const Action& other) : m_pHolder(other.m_pHolder ? other.m_pHolder->Clone() : nullptr) {}
134
136 Action(Action&& other) noexcept : m_pHolder(other.m_pHolder) {
137 other.m_pHolder = nullptr;
138 }
139
141 Action& operator=(const Action& other) {
142 if (this != &other) {
143 delete m_pHolder;
144 m_pHolder = other.m_pHolder ? other.m_pHolder->Clone() : nullptr;
145 }
146 return *this;
147 }
148
150 Action& operator=(Action&& other) noexcept {
151 if (this != &other) {
152 delete m_pHolder;
153 m_pHolder = other.m_pHolder;
154 other.m_pHolder = nullptr;
155 }
156 return *this;
157 }
158
161 delete m_pHolder;
162 m_pHolder = nullptr;
163 }
164
166 void Invoke(Arg1 arg1, Args... args) const {
167 if (m_pHolder) m_pHolder->Invoke(arg1, args...);
168 }
169
171 void operator()(Arg1 arg1, Args... args) const {
172 Invoke(arg1, args...);
173 }
174
176 explicit operator bool() const { return m_pHolder != nullptr; }
177
178 private:
179 Internal::IActionHolder<Arg1, Args...>* m_pHolder;
180 };
181
182 }
183}
Action & operator=(const Action &other)
Copy assignment operator.
Definition Action.h:141
Action(F &&func)
Constructs an Action wrapping the specified callable object.
Definition Action.h:130
Action(const Action &other)
Copy constructor.
Definition Action.h:133
Action(decltype(nullptr))
Nullptr constructor.
Definition Action.h:126
Action & operator=(Action &&other) noexcept
Move assignment operator.
Definition Action.h:150
Action(Action &&other) noexcept
Move constructor.
Definition Action.h:136
void operator()(Arg1 arg1, Args... args) const
Function call operator executing Invoke.
Definition Action.h:171
void Invoke(Arg1 arg1, Args... args) const
Invokes the wrapped action delegate with arguments.
Definition Action.h:166
Action & operator=(Action &&other) noexcept
Move assignment operator.
Definition Action.h:85
Action(decltype(nullptr))
Constructs an empty Action from nullptr.
Definition Action.h:57
~Action()
Destructor releasing target callable holder.
Definition Action.h:95
Action(Action &&other) noexcept
Move constructor transferring delegate ownership.
Definition Action.h:71
Action()
Default constructor creating an empty unassigned Action.
Definition Action.h:54
Action & operator=(const Action &other)
Copy assignment operator.
Definition Action.h:76
Action(const Action &other)
Copy constructor performing deep clone of target delegate.
Definition Action.h:67
Action(F &&func)
Constructs an Action wrapping the specified callable functor.
Definition Action.h:63
void operator()() const
Function call operator executing Invoke.
Definition Action.h:106
void Invoke() const
Invokes the wrapped action delegate.
Definition Action.h:101
Encapsulates a method that has parameters and does not return a value.
Definition Action.h:46
IActionHolder< Args... > * Clone() const override
Definition Action.h:34
void Invoke(Args... args) override
Definition Action.h:30
Type-erased polymorphic interface for invocable action delegates.
Definition Action.h:16
virtual void Invoke(Args... args)=0
virtual IActionHolder * Clone() const =0