Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
function_def.hpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  * Copyright (c) 2020 ZAFENA AB
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifndef JAU_FUNCTION_HPP_
27 #define JAU_FUNCTION_HPP_
28 
29 #include <cstring>
30 #include <string>
31 #include <memory>
32 #include <cstdint>
33 #include <vector>
34 #include <functional>
35 
36 #include <jau/basic_types.hpp>
37 
38 namespace jau {
39 
40  /**
41  * One goal to _produce_ the member-function type instance
42  * is to be class type agnostic for storing in the toolkit.
43  * This is essential to utilize a function-callback API,
44  * where only the provider of an instance knows about its class type.
45  *
46  * Further we can't utilize std::function and std::bind,
47  * as std::function doesn't provide details about the
48  * member-function-call identity and hence lacks of
49  * the equality operator and
50  * std::bind doesn't even specify a return type.
51  *
52  * A capturing lambda in C++-11, does produce decoration code
53  * accessing the captured elements, i.e. an anonymous helper class.
54  * Due to this fact, the return type is an undefined lambda specific
55  * and hence we can't use it to feed the function invocation
56  * into ClassFunction<> using a well specified type.
57  *
58  * <pre>
59  template<typename R, typename C, typename... A>
60  inline ClassFunction<R, A...>
61  bindClassFunction(C *base, R(C::*mfunc)(A...)) {
62  return ClassFunction<R, A...>(
63  (void*)base,
64  (void*)(*((void**)&mfunc)),
65  [&](A... args)->R{ (base->*mfunc)(args...); });
66  ^
67  | Capturing lambda function-pointer are undefined!
68  }
69  </pre>
70  *
71  * Hence we need to manually produce the on-the-fly invocation data type
72  * to capture details on the caller's class type for the member-function-call,
73  * which are then being passed to the ClassFunction<> anonymously
74  * while still being able to perform certain operations
75  * like equality operation for identity.
76  */
77  template<typename R, typename... A>
79  protected:
80  InvocationFunc() noexcept {}
81 
82  public:
83  virtual ~InvocationFunc() noexcept {}
84 
85  InvocationFunc(const InvocationFunc &o) noexcept = default;
86  InvocationFunc(InvocationFunc &&o) noexcept = default;
87  InvocationFunc& operator=(const InvocationFunc &o) noexcept = default;
88  InvocationFunc& operator=(InvocationFunc &&o) noexcept = default;
89 
90  /** Poor man's RTTI */
91  virtual int getType() const noexcept = 0;
92 
93  virtual InvocationFunc<R, A...> * clone() const noexcept = 0;
94 
95  virtual R invoke(A... args) = 0;
96 
97  virtual bool operator==(const InvocationFunc<R, A...>& rhs) const noexcept = 0;
98 
99  virtual bool operator!=(const InvocationFunc<R, A...>& rhs) const noexcept = 0;
100 
101  virtual std::string toString() const = 0;
102  };
103 
104  template<typename R, typename... A>
105  class NullInvocationFunc : public InvocationFunc<R, A...> {
106  public:
107  NullInvocationFunc() noexcept { }
108 
109  int getType() const noexcept override { return 0; }
110 
111  InvocationFunc<R, A...> * clone() const noexcept override { return new NullInvocationFunc(); }
112 
113  R invoke(A...) override {
114  return (R)0;
115  }
116 
117  bool operator==(const InvocationFunc<R, A...>& rhs) const noexcept override
118  {
119  return getType() == rhs.getType();
120  }
121 
122  bool operator!=(const InvocationFunc<R, A...>& rhs) const noexcept override
123  {
124  return !( *this == rhs );
125  }
126 
127  std::string toString() const override {
128  return "NullInvocation";
129  }
130  };
131 
132  template<typename R, typename C, typename... A>
133  class ClassInvocationFunc : public InvocationFunc<R, A...> {
134  private:
135  C* base;
136  R(C::*member)(A...);
137 
138  public:
139  ClassInvocationFunc(C *_base, R(C::*_member)(A...)) noexcept
140  : base(_base), member(_member) {
141  }
142 
143  int getType() const noexcept override { return 1; }
144 
145  InvocationFunc<R, A...> * clone() const noexcept override { return new ClassInvocationFunc(*this); }
146 
147  R invoke(A... args) override {
148  return (base->*member)(args...);
149  }
150 
151  bool operator==(const InvocationFunc<R, A...>& rhs) const noexcept override
152  {
153  if( &rhs == this ) {
154  return true;
155  }
156  if( getType() != rhs.getType() ) {
157  return false;
158  }
159  const ClassInvocationFunc<R, C, A...> * prhs = static_cast<const ClassInvocationFunc<R, C, A...>*>(&rhs);
160  return base == prhs->base && member == prhs->member;
161  }
162 
163  bool operator!=(const InvocationFunc<R, A...>& rhs) const noexcept override
164  {
165  return !( *this == rhs );
166  }
167 
168  std::string toString() const override {
169  // hack to convert member pointer to void *: '*((void**)&member)'
170  return "ClassInvocation "+to_hexstring((uint64_t)base)+"->"+to_hexstring( *((void**)&member) );
171  }
172  };
173 
174  template<typename R, typename... A>
175  class PlainInvocationFunc : public InvocationFunc<R, A...> {
176  private:
177  R(*function)(A...);
178 
179  public:
180  PlainInvocationFunc(R(*_function)(A...)) noexcept
181  : function(_function) {
182  }
183 
184  int getType() const noexcept override { return 2; }
185 
186  InvocationFunc<R, A...> * clone() const noexcept override { return new PlainInvocationFunc(*this); }
187 
188  R invoke(A... args) override {
189  return (*function)(args...);
190  }
191 
192  bool operator==(const InvocationFunc<R, A...>& rhs) const noexcept override
193  {
194  if( &rhs == this ) {
195  return true;
196  }
197  if( getType() != rhs.getType() ) {
198  return false;
199  }
200  const PlainInvocationFunc<R, A...> * prhs = static_cast<const PlainInvocationFunc<R, A...>*>(&rhs);
201  return function == prhs->function;
202  }
203 
204  bool operator!=(const InvocationFunc<R, A...>& rhs) const noexcept override
205  {
206  return !( *this == rhs );
207  }
208 
209  std::string toString() const override {
210  // hack to convert function pointer to void *: '*((void**)&function)'
211  return "PlainInvocation "+to_hexstring( *((void**)&function) );
212  }
213  };
214 
215  template<typename R, typename I, typename... A>
216  class CaptureInvocationFunc : public InvocationFunc<R, A...> {
217  private:
218  I data;
219  R(*function)(I&, A...);
220  bool dataIsIdentity;
221 
222  public:
223  /** Utilizes copy-ctor from 'const I& _data' */
224  CaptureInvocationFunc(const I& _data, R(*_function)(I&, A...), bool dataIsIdentity_) noexcept
225  : data(_data), function(_function), dataIsIdentity(dataIsIdentity_) {
226  }
227 
228  /** Utilizes move-ctor from moved 'I&& _data' */
229  CaptureInvocationFunc(I&& _data, R(*_function)(I&, A...), bool dataIsIdentity_) noexcept
230  : data(std::move(_data)), function(_function), dataIsIdentity(dataIsIdentity_) {
231  }
232 
233  int getType() const noexcept override { return 3; }
234 
235  InvocationFunc<R, A...> * clone() const noexcept override { return new CaptureInvocationFunc(*this); }
236 
237  R invoke(A... args) override {
238  return (*function)(data, args...);
239  }
240 
241  bool operator==(const InvocationFunc<R, A...>& rhs) const noexcept override
242  {
243  if( &rhs == this ) {
244  return true;
245  }
246  if( getType() != rhs.getType() ) {
247  return false;
248  }
249  const CaptureInvocationFunc<R, I, A...> * prhs = static_cast<const CaptureInvocationFunc<R, I, A...>*>(&rhs);
250  return dataIsIdentity == prhs->dataIsIdentity && function == prhs->function && ( !dataIsIdentity || data == prhs->data );
251  }
252 
253  bool operator!=(const InvocationFunc<R, A...>& rhs) const noexcept override
254  {
255  return !( *this == rhs );
256  }
257 
258  std::string toString() const override {
259  // hack to convert function pointer to void *: '*((void**)&function)'
260  return "CaptureInvocation "+to_hexstring( *((void**)&function) );
261  }
262  };
263 
264  template<typename R, typename... A>
265  class StdInvocationFunc : public InvocationFunc<R, A...> {
266  private:
267  uint64_t id;
268  std::function<R(A...)> function;
269 
270  public:
271  StdInvocationFunc(uint64_t _id, std::function<R(A...)> _function) noexcept
272  : id(_id), function(_function) {
273  }
274  StdInvocationFunc(uint64_t _id) noexcept
275  : id(_id), function() {
276  }
277 
278  int getType() const noexcept override { return 10; }
279 
280  InvocationFunc<R, A...> * clone() const noexcept override { return new StdInvocationFunc(*this); }
281 
282  R invoke(A... args) override {
283  return function(args...);
284  }
285 
286  bool operator==(const InvocationFunc<R, A...>& rhs) const noexcept override
287  {
288  if( &rhs == this ) {
289  return true;
290  }
291  if( getType() != rhs.getType() ) {
292  return false;
293  }
294  const StdInvocationFunc<R, A...> * prhs = static_cast<const StdInvocationFunc<R, A...>*>(&rhs);
295  return id == prhs->id;
296  }
297 
298  bool operator!=(const InvocationFunc<R, A...>& rhs) const noexcept override
299  {
300  return !( *this == rhs );
301  }
302 
303  std::string toString() const override {
304  return "StdInvocation "+to_hexstring( id );
305  }
306  };
307 
308  template<typename R, typename... A>
309  class FunctionDef {
310  private:
311  std::shared_ptr<InvocationFunc<R, A...>> func;
312 
313  public:
314  /**
315  * Constructs an instance with a null function.
316  */
317  FunctionDef() noexcept
318  : func( new NullInvocationFunc<R, A...>() ) { }
319 
320  /**
321  * Constructs an instance by wrapping the given naked InvocationFunc<R, A...> function pointer
322  * in a shared_ptr and taking ownership.
323  */
325  : func( _funcPtr ) { }
326 
327  /**
328  * Constructs an instance using the shared InvocationFunc<R, A...> function.
329  */
330  explicit FunctionDef(std::shared_ptr<InvocationFunc<R, A...>> _func) noexcept
331  : func( _func ) { }
332 
333  FunctionDef(const FunctionDef &o) noexcept = default;
334  FunctionDef(FunctionDef &&o) noexcept = default;
335  FunctionDef& operator=(const FunctionDef &o) noexcept = default;
336  FunctionDef& operator=(FunctionDef &&o) noexcept= default;
337 
338  bool operator==(const FunctionDef<R, A...>& rhs) const noexcept
339  { return *func == *rhs.func; }
340 
341  bool operator!=(const FunctionDef<R, A...>& rhs) const noexcept
342  { return *func != *rhs.func; }
343 
344  /** Returns the shared InvocationFunc<R, A...> function */
345  std::shared_ptr<InvocationFunc<R, A...>> getFunction() noexcept { return func; }
346 
347  /** Returns a new instance of the held InvocationFunc<R, A...> function. */
348  InvocationFunc<R, A...> * cloneFunction() const noexcept { return func->clone(); }
349 
350  std::string toString() const {
351  return "FunctionDef["+func->toString()+"]";
352  }
353 
354  R invoke(A... args) {
355  return func->invoke(args...);
356  }
357  };
358 
359  template<typename R, typename C, typename... A>
360  inline jau::FunctionDef<R, A...>
361  bindMemberFunc(C *base, R(C::*mfunc)(A...)) noexcept {
362  return FunctionDef<R, A...>( new ClassInvocationFunc<R, C, A...>(base, mfunc) );
363  }
364 
365  template<typename R, typename... A>
366  inline jau::FunctionDef<R, A...>
367  bindPlainFunc(R(*func)(A...)) noexcept {
368  return FunctionDef<R, A...>( new PlainInvocationFunc<R, A...>(func) );
369  }
370 
371  /**
372  * <code>const I& data</code> will be copied into the InvocationFunc<..> specialization
373  * and hence captured by copy.
374  * <p>
375  * The function call will have the reference of the copied data being passed for efficiency.
376  * </p>
377  */
378  template<typename R, typename I, typename... A>
379  inline jau::FunctionDef<R, A...>
380  bindCaptureFunc(const I& data, R(*func)(I&, A...), bool dataIsIdentity=true) noexcept {
381  return FunctionDef<R, A...>( new CaptureInvocationFunc<R, I, A...>(data, func, dataIsIdentity) );
382  }
383 
384  /**
385  * <code>I&& data</code> will be moved into the InvocationFunc<..> specialization.
386  * <p>
387  * The function call will have the reference of the copied data being passed for efficiency.
388  * </p>
389  */
390  template<typename R, typename I, typename... A>
391  inline jau::FunctionDef<R, A...>
392  bindCaptureFunc(I&& data, R(*func)(I&, A...), bool dataIsIdentity=true) noexcept {
393  return FunctionDef<R, A...>( new CaptureInvocationFunc<R, I, A...>(std::move(data), func, dataIsIdentity) );
394  }
395 
396  template<typename R, typename... A>
397  inline jau::FunctionDef<R, A...>
398  bindStdFunc(uint64_t id, std::function<R(A...)> func) noexcept {
399  return FunctionDef<R, A...>( new StdInvocationFunc<R, A...>(id, func) );
400  }
401  template<typename R, typename... A>
402  inline jau::FunctionDef<R, A...>
403  bindStdFunc(uint64_t id) noexcept {
404  return FunctionDef<R, A...>( new StdInvocationFunc<R, A...>(id) );
405  }
406 
407 } // namespace jau
408 
409 /** \example test_functiondef01.cpp
410  * This C++ unit test validates the jau::FunctionDef and all its jau::InvocationFunc specializations.
411  */
412 
413 #endif /* JAU_FUNCTION_HPP_ */
jau::FunctionDef::cloneFunction
InvocationFunc< R, A... > * cloneFunction() const noexcept
Returns a new instance of the held InvocationFunc<R, A...> function.
Definition: function_def.hpp:348
jau::NullInvocationFunc::clone
InvocationFunc< R, A... > * clone() const noexcept override
Definition: function_def.hpp:111
jau::PlainInvocationFunc::getType
int getType() const noexcept override
Definition: function_def.hpp:184
jau::NullInvocationFunc::NullInvocationFunc
NullInvocationFunc() noexcept
Definition: function_def.hpp:107
jau::bindCaptureFunc
jau::FunctionDef< R, A... > bindCaptureFunc(const I &data, R(*func)(I &, A...), bool dataIsIdentity=true) noexcept
const I& data will be copied into the InvocationFunc<..> specialization and hence captured by copy.
Definition: function_def.hpp:380
jau::FunctionDef::toString
std::string toString() const
Definition: function_def.hpp:350
jau::ClassInvocationFunc::invoke
R invoke(A... args) override
Definition: function_def.hpp:147
jau::NullInvocationFunc::operator!=
bool operator!=(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:122
jau::InvocationFunc::operator=
InvocationFunc & operator=(InvocationFunc &&o) noexcept=default
jau::NullInvocationFunc::toString
std::string toString() const override
Definition: function_def.hpp:127
jau::StdInvocationFunc::toString
std::string toString() const override
Definition: function_def.hpp:303
jau
Definition: basic_algos.hpp:34
jau::InvocationFunc
One goal to produce the member-function type instance is to be class type agnostic for storing in the...
Definition: function_def.hpp:78
jau::CaptureInvocationFunc::toString
std::string toString() const override
Definition: function_def.hpp:258
jau::NullInvocationFunc
Definition: function_def.hpp:105
jau::FunctionDef
Definition: function_def.hpp:309
jau::ClassInvocationFunc::toString
std::string toString() const override
Definition: function_def.hpp:168
jau::PlainInvocationFunc::invoke
R invoke(A... args) override
Definition: function_def.hpp:188
jau::CaptureInvocationFunc::invoke
R invoke(A... args) override
Definition: function_def.hpp:237
jau::ClassInvocationFunc::operator!=
bool operator!=(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:163
jau::InvocationFunc::InvocationFunc
InvocationFunc(const InvocationFunc &o) noexcept=default
jau::CaptureInvocationFunc::CaptureInvocationFunc
CaptureInvocationFunc(I &&_data, R(*_function)(I &, A...), bool dataIsIdentity_) noexcept
Utilizes move-ctor from moved 'I&& _data'.
Definition: function_def.hpp:229
jau::PlainInvocationFunc::toString
std::string toString() const override
Definition: function_def.hpp:209
jau::StdInvocationFunc
Definition: function_def.hpp:265
jau::CaptureInvocationFunc
Definition: function_def.hpp:216
jau::NullInvocationFunc::invoke
R invoke(A...) override
Definition: function_def.hpp:113
jau::PlainInvocationFunc::operator!=
bool operator!=(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:204
jau::CaptureInvocationFunc::operator!=
bool operator!=(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:253
jau::StdInvocationFunc::clone
InvocationFunc< R, A... > * clone() const noexcept override
Definition: function_def.hpp:280
jau::bindMemberFunc
jau::FunctionDef< R, A... > bindMemberFunc(C *base, R(C::*mfunc)(A...)) noexcept
Definition: function_def.hpp:361
jau::CaptureInvocationFunc::clone
InvocationFunc< R, A... > * clone() const noexcept override
Definition: function_def.hpp:235
jau::bindPlainFunc
jau::FunctionDef< R, A... > bindPlainFunc(R(*func)(A...)) noexcept
Definition: function_def.hpp:367
jau::ClassInvocationFunc::getType
int getType() const noexcept override
Definition: function_def.hpp:143
jau::FunctionDef::FunctionDef
FunctionDef(std::shared_ptr< InvocationFunc< R, A... >> _func) noexcept
Constructs an instance using the shared InvocationFunc<R, A...> function.
Definition: function_def.hpp:330
jau::PlainInvocationFunc
Definition: function_def.hpp:175
jau::NullInvocationFunc::operator==
bool operator==(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:117
jau::StdInvocationFunc::StdInvocationFunc
StdInvocationFunc(uint64_t _id) noexcept
Definition: function_def.hpp:274
jau::bindStdFunc
jau::FunctionDef< R, A... > bindStdFunc(uint64_t id, std::function< R(A...)> func) noexcept
Definition: function_def.hpp:398
jau::FunctionDef::FunctionDef
FunctionDef() noexcept
Constructs an instance with a null function.
Definition: function_def.hpp:317
jau::ClassInvocationFunc::clone
InvocationFunc< R, A... > * clone() const noexcept override
Definition: function_def.hpp:145
jau::FunctionDef::FunctionDef
FunctionDef(FunctionDef &&o) noexcept=default
jau::ClassInvocationFunc::operator==
bool operator==(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:151
jau::StdInvocationFunc::StdInvocationFunc
StdInvocationFunc(uint64_t _id, std::function< R(A...)> _function) noexcept
Definition: function_def.hpp:271
jau::InvocationFunc::~InvocationFunc
virtual ~InvocationFunc() noexcept
Definition: function_def.hpp:83
jau::CaptureInvocationFunc::operator==
bool operator==(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:241
jau::FunctionDef::operator==
bool operator==(const FunctionDef< R, A... > &rhs) const noexcept
Definition: function_def.hpp:338
jau::to_hexstring
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
Definition: string_util.hpp:104
jau::InvocationFunc::InvocationFunc
InvocationFunc(InvocationFunc &&o) noexcept=default
jau::CaptureInvocationFunc::getType
int getType() const noexcept override
Definition: function_def.hpp:233
jau::InvocationFunc::getType
virtual int getType() const noexcept=0
Poor man's RTTI.
jau::StdInvocationFunc::getType
int getType() const noexcept override
Definition: function_def.hpp:278
jau::FunctionDef::invoke
R invoke(A... args)
Definition: function_def.hpp:354
jau::PlainInvocationFunc::operator==
bool operator==(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:192
jau::InvocationFunc::InvocationFunc
InvocationFunc() noexcept
Definition: function_def.hpp:80
jau::InvocationFunc::operator=
InvocationFunc & operator=(const InvocationFunc &o) noexcept=default
jau::StdInvocationFunc::operator!=
bool operator!=(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:298
jau::FunctionDef::getFunction
std::shared_ptr< InvocationFunc< R, A... > > getFunction() noexcept
Returns the shared InvocationFunc<R, A...> function.
Definition: function_def.hpp:345
jau::FunctionDef::operator=
FunctionDef & operator=(const FunctionDef &o) noexcept=default
jau::FunctionDef::FunctionDef
FunctionDef(InvocationFunc< R, A... > *_funcPtr) noexcept
Constructs an instance by wrapping the given naked InvocationFunc<R, A...> function pointer in a shar...
Definition: function_def.hpp:324
basic_types.hpp
jau::FunctionDef::FunctionDef
FunctionDef(const FunctionDef &o) noexcept=default
jau::InvocationFunc::clone
virtual InvocationFunc< R, A... > * clone() const noexcept=0
jau::PlainInvocationFunc::clone
InvocationFunc< R, A... > * clone() const noexcept override
Definition: function_def.hpp:186
jau::StdInvocationFunc::operator==
bool operator==(const InvocationFunc< R, A... > &rhs) const noexcept override
Definition: function_def.hpp:286
jau::CaptureInvocationFunc::CaptureInvocationFunc
CaptureInvocationFunc(const I &_data, R(*_function)(I &, A...), bool dataIsIdentity_) noexcept
Utilizes copy-ctor from 'const I& _data'.
Definition: function_def.hpp:224
jau::FunctionDef::operator=
FunctionDef & operator=(FunctionDef &&o) noexcept=default
jau::InvocationFunc::invoke
virtual R invoke(A... args)=0
jau::ClassInvocationFunc::ClassInvocationFunc
ClassInvocationFunc(C *_base, R(C::*_member)(A...)) noexcept
Definition: function_def.hpp:139
jau::InvocationFunc::toString
virtual std::string toString() const =0
jau::ClassInvocationFunc
Definition: function_def.hpp:133
jau::PlainInvocationFunc::PlainInvocationFunc
PlainInvocationFunc(R(*_function)(A...)) noexcept
Definition: function_def.hpp:180
jau::StdInvocationFunc::invoke
R invoke(A... args) override
Definition: function_def.hpp:282
jau::FunctionDef::operator!=
bool operator!=(const FunctionDef< R, A... > &rhs) const noexcept
Definition: function_def.hpp:341
jau::NullInvocationFunc::getType
int getType() const noexcept override
Definition: function_def.hpp:109