PLCnext API Documentation 24.0.0.71
delegate.hxx
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Core/Impl/StaticFunctor.hxx"
9#include "Arp/System/Core/Impl/MethodFunctor.hxx"
10#include "Arp/System/Core/Impl/ConstMethodFunctor.hxx"
11#include "Arp/System/Core/Impl/LambdaFunctor.hxx"
12#include <memory>
13
14namespace Arp
15{
16
17using namespace Arp::System::Core;
18
20template <typename T> class delegate;
22
23
26
28// class delegate is implemented completely implicite inline to avoid
29// code bloat in used Core classe and therefore reduce compile time
30
46template<class R, class ...A>
47class delegate<R(A...)>
48{
49private: // typedefs/usings
50 using InvokerPtr = R(*)(void*, A && ...);
51 using FunctorPtr = std::shared_ptr<Impl::IDelegateFunctor>;
52
53public: // construction/destruction/assignment
55 template<class Lambda>
56 delegate(Lambda f) : delegate(new Impl::LambdaFunctor<R(A...)>(std::function<R(A...)>(f)), &Impl::LambdaFunctor<R(A...)>::Invoke) {}
58 delegate(void) = default;
61 delegate(const delegate& arg) = default;
64 delegate(delegate&& arg)noexcept = default;
68 delegate& operator=(const delegate& arg) = default;
72 delegate& operator=(delegate&& arg)noexcept = default;
73
74public: // static factory operations
78 static delegate create(R(*const pFunction)(A...))
79 {
80 return{ new Impl::StaticFunctor<R(A...)>(pFunction), &Impl::StaticFunctor<R(A...)>::Invoke };
81 }
82
87 template <class C>
88 static delegate create(C* pObject, R(C::*pMethod)(A...))noexcept
89 {
90 return{ new Impl::MethodFunctor<R(C::*)(A...)>(pObject, pMethod), &Impl::MethodFunctor<R(C::*)(A...)>::Invoke };
91 }
92
97 template <class C>
98 static delegate create(C& object, R(C::*pMethod)(A...))noexcept
99 {
100 return{ new Impl::MethodFunctor<R(C::*)(A...)>(object, pMethod), &Impl::MethodFunctor<R(C::*)(A...)>::Invoke };
101 }
102
107 template <class C>
108 static delegate create(const C* pObject, R(C::*pMethod)(A...)const)noexcept
109 {
110 return{ new Impl::ConstMethodFunctor<R(C::*)(A...)const>(pObject, pMethod), &Impl::ConstMethodFunctor<R(C::*)(A...)const>::Invoke };
111 }
112
117 template <class C>
118 static delegate create(const C& object, R(C::*pMethod)(A...)const)noexcept
119 {
120 return{ new Impl::ConstMethodFunctor<R(C::*)(A...)const>(object, pMethod), &Impl::ConstMethodFunctor<R(C::*)(A...)const>::Invoke };
121 }
122
126 static delegate create(std::function<R(A...)>&& f)
127 {
128 return{ new Impl::LambdaFunctor<R(A...)>(std::move(f)), &Impl::LambdaFunctor<R(A...)>::Invoke };
129 }
130
134 static delegate create(const std::function<R(A...)>& f)
135 {
136 return{ new Impl::LambdaFunctor<R(A...)>(f), &Impl::LambdaFunctor<R(A...)>::Invoke };
137 }
138
139public: // operators
143 bool operator==(const delegate& rhs)const noexcept
144 {
145 return *this->functorPtr == *rhs.functorPtr;
146 }
147
151 bool operator!=(const delegate& rhs)const noexcept
152 {
153 return !(this->operator==(rhs));
154 }
155
156public: // nullptr and bool support
158 delegate(std::nullptr_t) noexcept : delegate(nullptr, nullptr) { }
159
162 bool operator==(std::nullptr_t const)const noexcept
163 {
164 return this->functorPtr == nullptr;
165 }
166
169 bool operator!=(std::nullptr_t const)const noexcept
170 {
171 return this->functorPtr != nullptr;
172 }
173
176 explicit operator bool()const noexcept
177 {
178 return (bool)this->functorPtr;
179 }
180
181public: // property getter
184 bool is_lambda(void)const
185 {
186 return (bool)(*this) && dynamic_cast<Impl::LambdaFunctor<R(A...)>*>(this->functorPtr.get()) != nullptr;
187 }
188
189public: // functor operator()
193 R operator()(A... args)const
194 {
195 return this->pInvoker(this->functorPtr.get(), std::forward<A>(args)...);
196 }
197
198public: // management operations
201 void reset()
202 {
203 this->pInvoker = nullptr;
204 this->functorPtr = nullptr;
205 }
206
207private: // construction
208 delegate(Impl::IDelegateFunctor* pFunctor, InvokerPtr pInvokerArg)noexcept
209 : pInvoker(pInvokerArg)
210 , functorPtr(pFunctor)
211 {
212 }
213
214private: // fields
215 InvokerPtr pInvoker;
216 FunctorPtr functorPtr;
217};
218
220// make_delegate factory function
224template<class R, class ...A>
225inline delegate<R(A...)> make_delegate(R(*const function_ptr)(A...))noexcept
226{
227 return delegate<R(A...)>::create(function_ptr);
228}
229
234template<class C, class R, class ...A>
235inline delegate<R(A...)> make_delegate(C* const pObject, R(C::*const pMethod)(A...))noexcept
236{
237 return delegate<R(A...)>::create(pObject, pMethod);
238}
239
244template<class C, class R, class ...A>
245inline delegate<R(A...)> make_delegate(C const* const pObject, R(C::*const pMethod)(A...)const)noexcept
246{
247 return delegate<R(A...)>::create(pObject, pMethod);
248}
249
254template<class C, class R, class ...A>
255inline delegate<R(A...)> make_delegate(C& object, R(C::*const pMethod)(A...))noexcept
256{
257 return delegate<R(A...)>::create(object, pMethod);
258}
259
264template<class C, class R, class ...A>
265inline delegate<R(A...)> make_delegate(const C& object, R(C::*const pMethod)(A...)const)noexcept
266{
267 return delegate<R(A...)>::create(object, pMethod);
268}
269
273template<class R, class ...A>
274inline delegate<R(A...)> make_delegate(std::function<R(A...)>&& f)noexcept
275{
276 return delegate<R(A...)>::create(std::move(f));
277}
278
282template<class R, class ...A>
283inline delegate<R(A...)> make_delegate(const std::function<R(A...)>& f)noexcept
284{
285 return delegate<R(A...)>::create(f);
286}
287
289
290} // end of namespace Arp
delegate & operator=(const delegate &arg)=default
The default assign operator.
bool is_lambda(void) const
Determines if this instance wraps a lamda expression or std::function
Definition: delegate.hxx:184
bool operator!=(const delegate &rhs) const noexcept
Compares this instance to the as argument passed rhs .
Definition: delegate.hxx:151
delegate(const delegate &arg)=default
The default copy constructor.
delegate(void)=default
The default constructor.
delegate(std::nullptr_t) noexcept
Constructs an empty delegate representing a nullptr.
Definition: delegate.hxx:158
bool operator!=(std::nullptr_t const) const noexcept
Compares this instance to a nullptr.
Definition: delegate.hxx:169
static delegate create(std::function< R(A...)> &&f)
Creates a delegate from a lambda expression or std::function.
Definition: delegate.hxx:126
void reset()
Resets this instance.
Definition: delegate.hxx:201
static delegate create(R(*const pFunction)(A...))
Creates a delegate from a static function.
Definition: delegate.hxx:78
static delegate create(C &object, R(C::*pMethod)(A...)) noexcept
Creates a delegate from a member function and object reference.
Definition: delegate.hxx:98
delegate(Lambda f)
Constructs a delegate through a lambda expression implicitly.
Definition: delegate.hxx:56
delegate(delegate &&arg) noexcept=default
The default move constructor.
static delegate create(const C *pObject, R(C::*pMethod)(A...) const) noexcept
Creates a delegate from a const member function and const object pointer.
Definition: delegate.hxx:108
static delegate create(C *pObject, R(C::*pMethod)(A...)) noexcept
Creates a delegate from a member function and object pointer.
Definition: delegate.hxx:88
static delegate create(const C &object, R(C::*pMethod)(A...) const) noexcept
Creates a delegate from a const member function and const object reference.
Definition: delegate.hxx:118
static delegate create(const std::function< R(A...)> &f)
Creates a delegate from a lambda expression or std::function.
Definition: delegate.hxx:134
R operator()(A... args) const
The functor operator invokes the adapted callable target.
Definition: delegate.hxx:193
bool operator==(const delegate &rhs) const noexcept
Compares this instance to the as argument passed rhs .
Definition: delegate.hxx:143
delegate & operator=(delegate &&arg) noexcept=default
The default move assign operator.
bool operator==(std::nullptr_t const) const noexcept
Compares this instance to a nullptr.
Definition: delegate.hxx:162
delegate< R(A...)> make_delegate(R(*const function_ptr)(A...)) noexcept
Creates a delegate from a static function.
Definition: delegate.hxx:225
bool operator==(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string on equality.
Definition: BasicString.hxx:1908
Root namespace for the PLCnext API
Namespace of the C++ standard library