PLCnext API Documentation  22.9.0.33
slim_delegate.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 
9 namespace Arp
10 {
11 
12 template <typename T> class slim_delegate;
13 
15 // class slim_delegate is implemented completely implicite inline to avoid
16 // code bloat in commonly used Core classe and therefore reduce compile time
17 template<class R, class ...A>
18 class slim_delegate<R(A...)>
19 {
20 private: // typedefs/usings
21  using InvokerPtr = R(*)(void*, A && ...);
22 
23 public: // construction/destruction/assignment
24  slim_delegate(const slim_delegate&) = default;
25  slim_delegate(slim_delegate&&)noexcept = default;
26  slim_delegate& operator=(const slim_delegate&) = default;
27  slim_delegate& operator=(slim_delegate&&)noexcept = default;
28 
29 public: // static factory operations
30  template <R(*TFunction)(A...)>
31  static slim_delegate create(void) noexcept
32  {
33  return{ functionInvoker<TFunction> };
34  }
35 
36  template <class C, R(C::*TMethod)(A...)>
37  static slim_delegate create(C* pObject) noexcept
38  {
39  return{ pObject, methodInvoker<C, TMethod> };
40  }
41 
42  template <class C, R(C::*TMethod)(A...)>
43  static slim_delegate create(C& obj) noexcept
44  {
45  return{ &obj, methodInvoker<C, TMethod> };
46  }
47 
48  template <class C, R(C::*TMethod)(A...)const>
49  static slim_delegate create(const C* pObject) noexcept
50  {
51  return{ const_cast<C*>(pObject), constMethodInvoker<C, TMethod> };
52  }
53 
54  template <class C, R(C::*TMethod)(A...)const>
55  static slim_delegate create(const C& obj) noexcept
56  {
57  return{ const_cast<C*>(&obj), constMethodInvoker<C, TMethod> };
58  }
59 
60 public: // operators
61  bool operator==(const slim_delegate& rhs)const noexcept
62  {
63  if (this->is_static())
64  {
65  return this->pInvoker == rhs.pInvoker;
66  }
67  // else
68  return (this->pInstance == rhs.pInstance) && (this->pInvoker == rhs.pInvoker);
69  }
70 
71  bool operator!=(const slim_delegate& rhs)const noexcept
72  {
73  return !(operator==(rhs));
74  }
75 
76 public: // nullptr and bool support
77  slim_delegate(std::nullptr_t) noexcept : slim_delegate(nullptr, nullptr) { }
78 
79  bool operator==(std::nullptr_t)const noexcept
80  {
81  if (this->is_static())
82  {
83  return this->pInvoker == nullptr;
84  }
85  // else
86  return this->pInstance == nullptr || this->pInvoker == nullptr;
87  }
88 
89  bool operator!=(std::nullptr_t)const noexcept
90  {
91  return !(*this == nullptr);
92  }
93 
94  explicit operator bool()const noexcept
95  {
96  return *this != nullptr;
97  }
98 
99 public: // functor operator ()
100  R operator()(A... args) const
101  {
102  return pInvoker(this->pInstance, std::forward<A>(args)...);
103  }
104 
105 private: // construction
106  slim_delegate(InvokerPtr invokerPtr) noexcept
107  : pInstance(this), pInvoker(invokerPtr) // set pInstance to this a make operator bool work correctly
108  {
109  }
110 
111  slim_delegate(void* pObject, InvokerPtr invokerPtr) noexcept
112  : pInstance(pObject), pInvoker(invokerPtr)
113  {
114  }
115 
116  bool is_static(void)const
117  {
118  return this->pInstance == this;
119  }
120 
121 private: // invoker methods stored by pInvoker
122  template <R(*TFunction)(A...)>
123  static R functionInvoker(void* const, A&& ... args)
124  {
125  return TFunction(std::move(args)...);
126  }
127 
128  template <class C, R(C::*TMethod)(A...)>
129  static R methodInvoker(void* pObject, A&& ... args)
130  {
131  return (static_cast<C*>(pObject)->*TMethod)(std::move(args)...);
132  }
133 
134  template <class C, R(C::*TMethod)(A...) const>
135  static R constMethodInvoker(void* pObject, A&& ... args)
136  {
137  return (static_cast<const C*>(pObject)->*TMethod)(std::move(args)...);
138  }
139 
140 private: // fields
141  void* pInstance;
142  InvokerPtr pInvoker;
143 };
144 
145 } // end of namespace Arp
Definition: slim_delegate.hxx:12
bool operator!=(const BasicString< CharType, Alloc > &left, const BasicString< CharType, Alloc > &right)
Compares the left string to the right string on inequality.
Definition: BasicString.hxx:1912
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:1876
Root namespace for the PLCnext API