XTL  0.1
eXtended Template Library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
callback.hpp
Go to the documentation of this file.
1 
7 #pragma once
8 #include <xtd/xtd.hpp>
9 
10 #include <memory>
11 #include <vector>
12 
13 
14 namespace xtd{
15 #if (!DOXY_INVOKED)
16  template <typename _FnSig> class callback;
17 #endif
18 
28  template <typename _ReturnT, typename ... _Args> class callback < _ReturnT(_Args...) >{
29  class invoker{
30  public:
31  using ptr = std::unique_ptr<invoker>;
32  using vector = std::vector<ptr>;
33  virtual ~invoker() = default;
34  virtual _ReturnT invoke(_Args...) const = 0;
35  };
36 
37  template <typename _MethodT, _MethodT * _method> class method_invoker : public invoker{
38  public:
39  ~method_invoker() override = default;
40  virtual _ReturnT invoke(_Args...oArgs) const override { return (*_method)(std::forward<_Args>(oArgs)...); }
41  };
42 
43  template <typename _LambdaT> class lamdba_invoker : public invoker{
44  public:
45  ~lamdba_invoker() override = default;
46  virtual _ReturnT invoke(_Args...oArgs) const override { return _Lambda(std::forward<_Args>(oArgs)...); }
47  explicit lamdba_invoker(_LambdaT oLambda) : _Lambda(oLambda){} //NOSONAR
48  lamdba_invoker(lamdba_invoker&& src) : _Lambda(std::move(src._Lambda)){} //NOSONAR
49  lamdba_invoker(const lamdba_invoker& src) : _Lambda(src._Lambda){} //NOSONAR
50  lamdba_invoker& operator=(const lamdba_invoker& src){
51  if (this != &src){
52  _Lambda = src._Lambda;
53  }
54  return *this;
55  }
56  lamdba_invoker& operator=(lamdba_invoker&&) = delete;
57  _LambdaT _Lambda;
58  };
59 
60  template <typename _DestT, _ReturnT(_DestT::*_member)(_Args...)> class member_invoker : public invoker{
61  public:
62  ~member_invoker() override = default;
63  member_invoker() = delete;
64  member_invoker& operator=(const member_invoker&) = delete;
65  member_invoker(member_invoker&& oSrc) : _dest(oSrc._dest){} //NOSONAR
66  member_invoker(const member_invoker& oSrc) : _dest(oSrc._dest){} //NOSONAR
67  explicit member_invoker(_DestT* dest) : _dest(dest){} //NOSONAR
68  virtual _ReturnT invoke(_Args...oArgs) const override { return (_dest->*_member)(oArgs...); }
69  _DestT * _dest;
70  };
71 
72  typename invoker::vector _Invokers;
73 
74  public:
78  return_last
79  };
81  callback() = default;
82  callback(callback&& src) : _Invokers(std::move(src._Invokers)){}
83  callback(const callback&) = delete;
85  ~callback() = default;
86  callback& operator=(const callback&) = delete;
88  _ReturnT operator()(result_policy result, _Args...oArgs) const{
89  _ReturnT oRet;
90  typename invoker::vector::size_type i = 0;
91  for (const auto & oInvoker : _Invokers){
92  if ((result_policy::first == result && 0 == i) || (result_policy::last == result && (_Invokers.size() - 1) == i)){
93  oRet = oInvoker->invoke(std::forward<_Args>(oArgs)...);
94  } else{
95  oInvoker->invoke(oArgs...);
96  }
97  ++i;
98  }
99  return oRet;
100  }
101  //invokes all the attached targets and returns the result of the last target
102  _ReturnT operator()(_Args...oArgs) const{
103  _ReturnT oRet;
104  for (const auto & oInvoker : _Invokers){
105  oRet = oInvoker->invoke(oArgs...);
106  }
107  return oRet;
108  }
109 
111  template <typename _ClassT, _ReturnT(_ClassT::*_MemberT)(_Args...)>
112  void connect(_ClassT *pClass){ _Invokers.emplace_back(new member_invoker<_ClassT, _MemberT>(pClass)); }
113 
115  template <typename method>
116  void connect(method oMethod){ _Invokers.emplace_back(new lamdba_invoker< method >(oMethod)); }
117 
119  template <_ReturnT(*method)(_Args...)>
120  void connect(){ _Invokers.emplace_back(new method_invoker<_ReturnT(_Args...), method>()); }
121 
123 
124  template <typename _Ty>
125  callback& operator += (_Ty&& addend){ connect(std::forward<_Ty>(addend)); return *this; }
126 
127  };
128 
129 
130 #if (!DOXY_INVOKED)
131  template <typename ... _Args> class callback < void(_Args...) >{
132 
133  using _ReturnT = void;
134 
135  class invoker{
136  public:
137  using ptr = std::unique_ptr<invoker>;
138  using vector = std::vector<ptr>;
139  virtual ~invoker() = default;
140  virtual _ReturnT invoke(_Args...) const = 0;
141  };
142 
143  template <typename _MethodT, _MethodT * _method> class method_invoker : public invoker{
144  public:
145  ~method_invoker() override = default;
146  virtual _ReturnT invoke(_Args...oArgs) const override { (*_method)(std::forward<_Args>(oArgs)...); }
147  };
148 
149  template <typename _LambdaT> class lamdba_invoker : public invoker{
150  public:
151  ~lamdba_invoker() override = default;
152  virtual _ReturnT invoke(_Args...oArgs) const override { _Lambda(std::forward<_Args>(oArgs)...); }
153  explicit lamdba_invoker(_LambdaT oLambda) : _Lambda(oLambda){}
154  lamdba_invoker(lamdba_invoker&& src) : _Lambda(std::move(src._Lambda)){}
155  lamdba_invoker(const lamdba_invoker& src) : _Lambda(src._Lambda){}
156  lamdba_invoker& operator=(const lamdba_invoker& src){
157  if (this != &src){
158  _Lambda = src._Lambda;
159  }
160  return *this;
161  }
162  lamdba_invoker& operator=(lamdba_invoker&&) = delete;
163  _LambdaT _Lambda;
164  };
165 
166  template <typename _DestT, _ReturnT(_DestT::*_member)(_Args...)> class member_invoker : public invoker{
167  public:
168  ~member_invoker() override = default;
169  member_invoker() = delete;
170  member_invoker& operator=(const member_invoker&) = delete;
171  member_invoker(member_invoker&& oSrc) : _dest(oSrc._dest){}
172  member_invoker(const member_invoker& oSrc) : _dest(oSrc._dest){}
173  explicit member_invoker(_DestT* dest) : _dest(dest){}
174  virtual _ReturnT invoke(_Args...oArgs)const override { (_dest->*_member)(oArgs...); }
175  _DestT * _dest;
176  };
177 
178  typename invoker::vector _Invokers;
179 
180  public:
181  ~callback() = default;
182  callback() = default;
183  callback(const callback&) = delete;
184  callback(callback&& src) : _Invokers(std::move(src._Invokers)){}
185  callback& operator=(const callback&) = delete;
186 
187 
188  void operator()(_Args...oArgs) const{
189  for (auto & oInvoker : _Invokers){
190  oInvoker->invoke(oArgs...);
191  }
192  }
193 
194  template <typename _ClassT, _ReturnT(_ClassT::*_MemberT)(_Args...)>
195  void connect(_ClassT *pClass){ _Invokers.emplace_back(new member_invoker<_ClassT, _MemberT>(pClass)); }
196 
197  template <typename method>
198  void connect(method oMethod){ _Invokers.emplace_back(new lamdba_invoker< method >(oMethod)); }
199 
200  template <_ReturnT(*method)(_Args...)>
201  void connect(){ _Invokers.emplace_back(new method_invoker<void(_Args...), method>()); }
202 
203  template <typename _Ty>
204  callback& operator += (_Ty&& addend){ connect(std::forward<_Ty>(addend)); return *this; }
205 
206 
207  };
208 #endif
209 }
result_policy
behavior of invocation when multiple receivers are attached
Definition: callback.hpp:76
return the result of the first attached target
Definition: callback.hpp:77
void connect(method oMethod)
connect a lambda
Definition: callback.hpp:116
host, target and build configurations and settings Various components are purpose built for specific ...
void connect()
connect a static method
Definition: callback.hpp:120
_ReturnT operator()(result_policy result, _Args...oArgs) const
Invokes all the attached targets and returns the result of the target as specified by the result poli...
Definition: callback.hpp:88
void connect(_ClassT *pClass)
connect a class instance and member function
Definition: callback.hpp:112