PLCnext API Documentation  21.0.0.35466
delegate.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
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 
14 namespace Arp
15 {
16 
17 using namespace Arp::System::Core;
18 
20 template <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 
46 template<class R, class ...A>
47 class delegate<R(A...)>
48 {
49 private: // typedefs/usings
50  using InvokerPtr = R(*)(void*, A && ...);
51  using FunctorPtr = std::shared_ptr<Impl::IDelegateFunctor>;
52 
53 public: // construction/destruction/assignment
55  delegate(void) = default;
58  delegate(const delegate& arg) = default;
61  delegate(delegate&& arg) = default;
65  delegate& operator=(const delegate& arg) = default;
69  delegate& operator=(delegate&& arg) = default;
70 
71 public: // static factory operations
75  static delegate create(R(*const pFunction)(A...))
76  {
77  return{ new Impl::StaticFunctor<R(A...)>(pFunction), &Impl::StaticFunctor<R(A...)>::Invoke };
78  }
79 
84  template <class C>
85  static delegate create(C* pObject, R(C::*pMethod)(A...))noexcept
86  {
87  return{ new Impl::MethodFunctor<R(C::*)(A...)>(pObject, pMethod), &Impl::MethodFunctor<R(C::*)(A...)>::Invoke };
88  }
89 
94  template <class C>
95  static delegate create(C& object, R(C::*pMethod)(A...))noexcept
96  {
97  return{ new Impl::MethodFunctor<R(C::*)(A...)>(object, pMethod), &Impl::MethodFunctor<R(C::*)(A...)>::Invoke };
98  }
99 
104  template <class C>
105  static delegate create(const C* pObject, R(C::*pMethod)(A...)const)noexcept
106  {
107  return{ new Impl::ConstMethodFunctor<R(C::*)(A...)const>(pObject, pMethod), &Impl::ConstMethodFunctor<R(C::*)(A...)const>::Invoke };
108  }
109 
114  template <class C>
115  static delegate create(const C& object, R(C::*pMethod)(A...)const)noexcept
116  {
117  return{ new Impl::ConstMethodFunctor<R(C::*)(A...)const>(object, pMethod), &Impl::ConstMethodFunctor<R(C::*)(A...)const>::Invoke };
118  }
119 
123  static delegate create(std::function<R(A...)>&& f)
124  {
125  return{ new Impl::LambdaFunctor<R(A...)>(std::forward<std::function<R(A...)>>(f)), &Impl::LambdaFunctor<R(A...)>::Invoke };
126  }
127 
131  static delegate create(const std::function<R(A...)>& f)
132  {
133  return{ new Impl::LambdaFunctor<R(A...)>(f), &Impl::LambdaFunctor<R(A...)>::Invoke };
134  }
135 
136 public: // operators
140  bool operator==(const delegate& rhs)const noexcept
141  {
142  return *this->functorPtr == *rhs.functorPtr;
143  }
144 
148  bool operator!=(const delegate& rhs)const noexcept
149  {
150  return !(this->operator==(rhs));
151  }
152 
153 public: // nullptr and bool support
155  delegate(std::nullptr_t) noexcept : delegate(nullptr, nullptr) { }
156 
159  bool operator==(std::nullptr_t const)const noexcept
160  {
161  return this->functorPtr == nullptr;
162  }
163 
166  bool operator!=(std::nullptr_t const)const noexcept
167  {
168  return this->functorPtr != nullptr;
169  }
170 
173  explicit operator bool()const noexcept
174  {
175  return (bool)this->functorPtr;
176  }
177 
178 public: // property getter
181  bool is_lambda(void)const
182  {
183  return (bool)(*this) && dynamic_cast<Impl::LambdaFunctor<R(A...)>*>(this->functorPtr.get()) != nullptr;
184  }
185 
186 public: // functor operator()
190  R operator()(A... args)const
191  {
192  return this->pInvoker(this->functorPtr.get(), std::forward<A>(args)...);
193  }
194 
195 public: // management operations
198  void reset()
199  {
200  this->pInvoker = nullptr;
201  this->functorPtr = nullptr;
202  }
203 
204 
205 private: // construction
206  delegate(Impl::IDelegateFunctor* pFunctor, InvokerPtr pInvokerArg)noexcept
207  : pInvoker(pInvokerArg)
208  , functorPtr(pFunctor)
209  {
210  }
211 
212 private: // fields
213  InvokerPtr pInvoker;
214  FunctorPtr functorPtr;
215 };
216 
218 // make_delegate factory function
222 template<class R, class ...A>
223 inline delegate<R(A...)> make_delegate(R(*const function_ptr)(A...))noexcept
224 {
225  return delegate<R(A...)>::create(function_ptr);
226 }
227 
232 template<class C, class R, class ...A>
233 inline delegate<R(A...)> make_delegate(C* const pObject, R(C::*const pMethod)(A...))noexcept
234 {
235  return delegate<R(A...)>::create(pObject, pMethod);
236 }
237 
242 template<class C, class R, class ...A>
243 inline delegate<R(A...)> make_delegate(C const* const pObject, R(C::*const pMethod)(A...)const)noexcept
244 {
245  return delegate<R(A...)>::create(pObject, pMethod);
246 }
247 
252 template<class C, class R, class ...A>
253 inline delegate<R(A...)> make_delegate(C& object, R(C::*const pMethod)(A...))noexcept
254 {
255  return delegate<R(A...)>::create(object, pMethod);
256 }
257 
262 template<class C, class R, class ...A>
263 inline delegate<R(A...)> make_delegate(const C& object, R(C::*const pMethod)(A...)const)noexcept
264 {
265  return delegate<R(A...)>::create(object, pMethod);
266 }
267 
271 template<class R, class ...A>
272 inline delegate<R(A...)> make_delegate(std::function<R(A...)>&& f)noexcept
273 {
274  return delegate<R(A...)>::create(std::forward<std::function<R(A...)>>(f));
275 }
276 
280 template<class R, class ...A>
281 inline delegate<R(A...)> make_delegate(const std::function<R(A...)>& f)noexcept
282 {
283  return delegate<R(A...)>::create(f);
284 }
285 
287 
288 } // end of namespace Arp
bool operator==(const delegate &rhs) const noexcept
Compares this instance to the as argument passed rhs .
Definition: delegate.hxx:140
void reset()
Resets this instance.
Definition: delegate.hxx:198
delegate< R(A...)> make_delegate(R(*const function_ptr)(A...)) noexcept
Creates a delegate from a static function.
Definition: delegate.hxx:223
bool operator!=(std::nullptr_t const) const noexcept
Compares this instance to a nullptr.
Definition: delegate.hxx:166
bool is_lambda(void) const
Determines if this instance wraps a lamda expression or std::function
Definition: delegate.hxx:181
bool operator==(std::nullptr_t const) const noexcept
Compares this instance to a nullptr.
Definition: delegate.hxx:159
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:105
static delegate create(R(*const pFunction)(A...))
Creates a delegate from a static function.
Definition: delegate.hxx:75
static delegate create(C *pObject, R(C::*pMethod)(A...)) noexcept
Creates a delegate from a member function and object pointer.
Definition: delegate.hxx:85
static delegate create(std::function< R(A...)> &&f)
Creates a delegate from a lambda expression or std::function.
Definition: delegate.hxx:123
delegate(std::nullptr_t) noexcept
Constructs an empty delegate representing a nullptr.
Definition: delegate.hxx:155
Root namespace for the PLCnext API
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:1752
Definition: ConstMethodFunctor.hxx:10
bool operator!=(const delegate &rhs) const noexcept
Compares this instance to the as argument passed rhs .
Definition: delegate.hxx:148
static delegate create(C &object, R(C::*pMethod)(A...)) noexcept
Creates a delegate from a member function and object reference.
Definition: delegate.hxx:95
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:115
static delegate create(const std::function< R(A...)> &f)
Creates a delegate from a lambda expression or std::function.
Definition: delegate.hxx:131
R operator()(A... args) const
The functor operator invokes the adapted callable target.
Definition: delegate.hxx:190