PLCnext API Documentation 25.0.2.69
delegate.hxx
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
7
8#ifndef ARP_USE_ARP_SYSTEM_CORE
9
10#include "Arp/Base/Core/delegate.hxx"
11
12#else
13
14#include "Arp/System/Core/Arp.h"
15#include "Arp/System/Core/Impl/StaticFunctor.hxx"
16#include "Arp/System/Core/Impl/MethodFunctor.hxx"
17#include "Arp/System/Core/Impl/ConstMethodFunctor.hxx"
18#include "Arp/System/Core/Impl/LambdaFunctor.hxx"
19#include <memory>
20
21namespace Arp
22{
23
24using namespace Arp::System::Core;
25
27template <typename T> class delegate;
29
30
33
35// class delegate is implemented completely implicite inline to avoid
36// code bloat in used Core classe and therefore reduce compile time
37
53template<class R, class ...A>
54class delegate<R(A...)>
55{
56private: // typedefs/usings
57 using InvokerPtr = R(*)(void*, A && ...);
58 using FunctorPtr = std::shared_ptr<Impl::IDelegateFunctor>;
59
60public: // construction/destruction/assignment
62 template<class Lambda>
63 delegate(Lambda f) : delegate(new Impl::LambdaFunctor<R(A...)>(std::function<R(A...)>(f)), &Impl::LambdaFunctor<R(A...)>::Invoke) {}
65 delegate(void) = default;
68 delegate(const delegate& arg) = default;
71 delegate(delegate&& arg)noexcept = default;
75 delegate& operator=(const delegate& arg) = default;
79 delegate& operator=(delegate&& arg)noexcept = default;
80
81public: // static factory operations
85 static delegate create(R(*const pFunction)(A...))
86 {
87 return{ new Impl::StaticFunctor<R(A...)>(pFunction), &Impl::StaticFunctor<R(A...)>::Invoke };
88 }
89
94 template <class C>
95 static delegate create(C* pObject, R(C::*pMethod)(A...))noexcept
96 {
97 return{ new Impl::MethodFunctor<R(C::*)(A...)>(pObject, pMethod), &Impl::MethodFunctor<R(C::*)(A...)>::Invoke };
98 }
99
104 template <class C>
105 static delegate create(C& object, R(C::*pMethod)(A...))noexcept
106 {
107 return{ new Impl::MethodFunctor<R(C::*)(A...)>(object, pMethod), &Impl::MethodFunctor<R(C::*)(A...)>::Invoke };
108 }
109
114 template <class C>
115 static delegate create(const C* pObject, R(C::*pMethod)(A...)const)noexcept
116 {
117 return{ new Impl::ConstMethodFunctor<R(C::*)(A...)const>(pObject, pMethod), &Impl::ConstMethodFunctor<R(C::*)(A...)const>::Invoke };
118 }
119
124 template <class C>
125 static delegate create(const C& object, R(C::*pMethod)(A...)const)noexcept
126 {
127 return{ new Impl::ConstMethodFunctor<R(C::*)(A...)const>(object, pMethod), &Impl::ConstMethodFunctor<R(C::*)(A...)const>::Invoke };
128 }
129
133 static delegate create(std::function<R(A...)>&& f)
134 {
135 return{ new Impl::LambdaFunctor<R(A...)>(std::move(f)), &Impl::LambdaFunctor<R(A...)>::Invoke };
136 }
137
141 static delegate create(const std::function<R(A...)>& f)
142 {
143 return{ new Impl::LambdaFunctor<R(A...)>(f), &Impl::LambdaFunctor<R(A...)>::Invoke };
144 }
145
146public: // operators
150 bool operator==(const delegate& rhs)const noexcept
151 {
152 return *this->functorPtr == *rhs.functorPtr;
153 }
154
158 bool operator!=(const delegate& rhs)const noexcept
159 {
160 return !(this->operator==(rhs));
161 }
162
163public: // nullptr and bool support
165 delegate(std::nullptr_t) noexcept : delegate(nullptr, nullptr) { }
166
169 bool operator==(std::nullptr_t const)const noexcept
170 {
171 return this->functorPtr == nullptr;
172 }
173
176 bool operator!=(std::nullptr_t const)const noexcept
177 {
178 return this->functorPtr != nullptr;
179 }
180
183 explicit operator bool()const noexcept
184 {
185 return (bool)this->functorPtr;
186 }
187
188public: // property getter
191 bool is_lambda(void)const
192 {
193 return (bool)(*this) && dynamic_cast<Impl::LambdaFunctor<R(A...)>*>(this->functorPtr.get()) != nullptr;
194 }
195
196public: // functor operator()
200 R operator()(A... args)const
201 {
202 return this->pInvoker(this->functorPtr.get(), std::forward<A>(args)...);
203 }
204
205public: // management operations
208 void reset()
209 {
210 this->pInvoker = nullptr;
211 this->functorPtr = nullptr;
212 }
213
214private: // construction
215 delegate(Impl::IDelegateFunctor* pFunctor, InvokerPtr pInvokerArg)noexcept
216 : pInvoker(pInvokerArg)
217 , functorPtr(pFunctor)
218 {
219 }
220
221private: // fields
222 InvokerPtr pInvoker;
223 FunctorPtr functorPtr;
224};
225
227// make_delegate factory function
231template<class R, class ...A>
232inline delegate<R(A...)> make_delegate(R(*const function_ptr)(A...))noexcept
233{
234 return delegate<R(A...)>::create(function_ptr);
235}
236
241template<class C, class R, class ...A>
242inline delegate<R(A...)> make_delegate(C* const pObject, R(C::*const pMethod)(A...))noexcept
243{
244 return delegate<R(A...)>::create(pObject, pMethod);
245}
246
251template<class C, class R, class ...A>
252inline delegate<R(A...)> make_delegate(C const* const pObject, R(C::*const pMethod)(A...)const)noexcept
253{
254 return delegate<R(A...)>::create(pObject, pMethod);
255}
256
261template<class C, class R, class ...A>
262inline delegate<R(A...)> make_delegate(C& object, R(C::*const pMethod)(A...))noexcept
263{
264 return delegate<R(A...)>::create(object, pMethod);
265}
266
271template<class C, class R, class ...A>
272inline delegate<R(A...)> make_delegate(const C& object, R(C::*const pMethod)(A...)const)noexcept
273{
274 return delegate<R(A...)>::create(object, pMethod);
275}
276
280template<class R, class ...A>
281inline delegate<R(A...)> make_delegate(std::function<R(A...)>&& f)noexcept
282{
283 return delegate<R(A...)>::create(std::move(f));
284}
285
289template<class R, class ...A>
290inline delegate<R(A...)> make_delegate(const std::function<R(A...)>& f)noexcept
291{
292 return delegate<R(A...)>::create(f);
293}
294
296
297} // end of namespace Arp
298
299#endif // ndef ARP_USE_ARP_SYSTEM_CORE
Prototyping of delegate template.
Definition: delegate.hxx:14
Root namespace for the PLCnext API
Namespace of the C++ standard library