Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
functional2.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020-2022 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_FUNCTIONAL_HPP_
27#define JAU_FUNCTIONAL_HPP_
28
29#include <cstring>
30#include <string>
31#include <memory>
32#include <cstdint>
33#include <type_traits>
34#include <functional>
35
36#include <jau/basic_types.hpp>
37#include <jau/cpp_lang_util.hpp>
38
39namespace jau {
40
41 /** @defgroup FunctionWrap Function Wrapper
42 * Supporting general-purpose polymorphic function wrapper via jau::function<R(A...)>.
43 *
44 * @anchor function_overview
45 * ### Function Overview
46 * Similar to std::function, [jau::function<R(A...)>](@ref function_def) stores any callable target function
47 * solely described by its return type `R` and arguments types `A...` from any source,
48 * e.g. free functions, capturing and non-capturing lambda function, member functions,
49 *
50 * [jau::function<R(A...)>](@ref function_def) supports equality operations for all func::target_t source types,
51 * allowing to manage container of [jau::function](@ref function_def)s.
52 *
53 * See [limitations](@ref function_limitations) below.
54 *
55 * If a [jau::function](@ref function_def) contains no target, see jau::function<R(A...)>::is_null(), it is empty.
56 * Invoking the target of an empty [jau::function](@ref function_def) is a no-operation and has no side effects.
57 *
58 * [jau::function](@ref function_def) satisfies the requirements of CopyConstructible and CopyAssignable.
59 *
60 * Compared to `std::function<R(A...)>`, `jau::function<R(A...)>`
61 * - supports equality operations,
62 * - supports capturing lambda functions
63 * - See [limitations on their equality operator w/o RTTI on `gcc`](@ref function_limitations).
64 * - most operations are `noexcept`, except for the user given function invocation.
65 * - exposes the target function signature jau::type_info via jau::function::signature()
66 *
67 * Instances of [jau::function](@ref function_def) can store, copy, and invoke any of its callable targets
68 * - free functions
69 * - bind_free()
70 * - includes non-capturing lambda
71 * - constructor [jau::function<R(A...)>::function(R(*func)(A...))](@ref function_ctor_free)
72 * - member functions
73 * - bind_member()
74 * - constructor [`function(C *base, R(C::*mfunc)(A...))`](@ref function_ctor_member)
75 * - lambda functions
76 * - constructor [`template<typename L> function(L func)`](@ref function_ctor_lambda)
77 * - see [limitations on their equality operator w/o RTTI on `gcc`](@ref function_limitations).
78 * - lambda alike functions using a captured data type by reference
79 * - bind_capref()
80 * - constructor [function(I* data_ptr, R(*func)(I*, A...))](@ref function_ctor_capref)
81 * - lambda alike functions using a captured data type by value
82 * - bind_capval()
83 * - constructor copy [function(const I& data, R(*func)(I&, A...))](@ref function_ctor_capval_copy)
84 * - constructor move [function(I&& data, R(*func)(I&, A...))](@ref function_ctor_capval_move)
85 * - std::function
86 * - bind_std()
87 * - constructor [function(uint64_t id, std::function<R(A...)> func)](@ref function_ctor_std)
88 *
89 * @anchor function_usage
90 * #### Function Usage
91 *
92 * A detailed API usage is covered within [test_functional01.cpp](test_functional01_8cpp-example.html), see function `test00_usage()`.
93 *
94 * Let's assume we like to bind to the following
95 * function prototype `bool func(int)`, which results to `jau::function<bool(int)>`:
96 *
97 * - Free functions via [constructor](@ref function_ctor_free) and jau::bind_free()
98 * - Prologue
99 * ```
100 * typedef bool(*cfunc)(int); // to force non-capturing lambda into a free function template type deduction
101 *
102 * bool my_func(int v) { return 0 == v; }
103 *
104 * struct MyClass {
105 * static bool func(int v) { return 0 == v; }
106 * };
107 * ```
108 *
109 * - Constructor [function(R(*func)(A...))](@ref function_ctor_free)
110 * ```
111 * jau::function<bool(int)> func0 = my_func;
112 *
113 * jau::function<bool(int)> func1 = &MyClass:func;
114 *
115 * jau::function<bool(int)> func2 = (cfunc) ( [](int v) -> bool { // forced free via cast
116 * return 0 == v;
117 * } );
118 *
119 * ```
120 *
121 * - Bind `jau::function<R(A...)> jau::bind_free(R(*func)(A...))`
122 * ```
123 * jau::function<bool(int)> func0 = jau::bind_free(&MyClass:func);
124 *
125 * jau::function<bool(int)> func1 = jau::bind_free(my_func);
126 * ```
127 *
128 * - Class member functions via [constructor](@ref function_ctor_member) and jau::bind_member()
129 * - Prologue
130 * ```
131 * struct MyClass {
132 * bool m_func(int v) { return 0 == v; }
133 * };
134 * MyClass i1;
135 * ```
136 *
137 * - Constructor [function(C *base, R(C::*mfunc)(A...))](@ref function_ctor_member)
138 * ```
139 * jau::function<bool(int)> func(&i1, &MyClass::m_func);
140 * ```
141 *
142 * - Bind `jau::function<R(A...)> jau::bind_member(C *base, R(C::*mfunc)(A...))`
143 * ```
144 * jau::function<bool(int)> func = jau::bind_member(&i1, &MyClass::m_func);
145 * ```
146 *
147 * - Lambda functions via [constructor](@ref function_ctor_lambda)
148 * - Prologue
149 * ```
150 * int sum = 0;
151 * ```
152 *
153 * - Constructor [template<typename L> function(L func)](@ref function_ctor_lambda)
154 * ```
155 * jau::function<bool(int)> func0 = [](int v) -> bool {
156 * return 0 == v;
157 * };
158 *
159 * jau::function<bool(int)> func1 = [&](int v) -> bool {
160 * sum += v;
161 * return 0 == v;
162 * };
163 *
164 * auto func2_stub = [&](int v) -> bool {
165 * sum += v;
166 * return 0 == v;
167 * };
168 *
169 * jau::function<bool(int)> func2 = func2_stub;
170 * ```
171 *
172 * - Lambda alike capture by reference to value via [constructor](@ref function_ctor_capref) and jau::bind_capref()
173 * - Prologue
174 * ```
175 * struct big_data {
176 * int sum;
177 * };
178 * big_data data { 0 };
179 *
180 * typedef bool(*cfunc)(big_data*, int); // to force non-capturing lambda into a free function template type deduction
181 * ```
182 *
183 * - Constructor [function(I* data_ptr, R(*func)(I*, A...))](@ref function_ctor_capref)
184 * ```
185 * function<int(int)> func(&data,
186 * (cfunc) ( [](big_data* data, int v) -> bool {
187 * stats_ptr->sum += v;
188 * return 0 == v;
189 * } ) );
190 * ```
191 *
192 * - Bind `jau::function<R(A...)> jau::bind_capref(I* data_ptr, R(*func)(I*, A...))`
193 * ```
194 * jau::function<bool(int)> func = jau::bind_capref(&data,
195 * (cfunc) ( [](big_data* data, int v) -> bool {
196 * stats_ptr->sum += v;
197 * return 0 == v;
198 * } ) );
199 * ```
200 *
201 * - Lambda alike capture by copy of value via constructor and jau::bind_capval()
202 * - Constructor copy [function(const I& data, R(*func)(I&, A...))](@ref function_ctor_capval_copy)
203 * - Constructor move [function(I&& data, R(*func)(I&, A...))](@ref function_ctor_capval_move)
204 * - Bind copy `jau::function<R(A...)> jau::bind_capval(const I& data, R(*func)(I&, A...))`
205 * - Bind move `jau::function<R(A...)> jau::bind_capval(I&& data, R(*func)(I&, A...))` <br />
206 * See example of *Capture by reference to value* above.
207 *
208 * - std::function function via [constructor](@ref function_ctor_std) and jau::bind_std()
209 * - Prologue
210 * ```
211 * std::function<bool(int)> func_stdlambda = [](int i)->bool {
212 * return 0 == i;
213 * };
214 * ```
215 *
216 * - Constructor [function(uint64_t id, std::function<R(A...)> func)](@ref function_ctor_std)
217 * ```
218 * jau::function<bool(int)> func(100, func_stdlambda);
219 * ```
220 *
221 * - Bind `function<R(A...)> jau::bind_std(uint64_t id, std::function<R(A...)> func)`
222 * ```
223 * jau::function<bool(int)> func = jau::bind_std(100, func_stdlambda);
224 * ```
225 * @anchor function_limitations
226 * #### Function Limitations
227 *
228 * ##### Non unique lambda type names without RTTI using `gcc` or non `clang` compiler
229 *
230 * Due to [limitations of jau::make_ctti<R, L, A...>()](@ref ctti_name_lambda_limitations),
231 * *not using RTTI on `gcc` or non `clang` compiler* will *erroneously mistake* different lambda
232 * *functions defined within one function and using same function prototype `R<A...>`* to be the same.
233 *
234 * jau::type_info::limited_lambda_id will expose the potential limitation.
235 *
236 * See [CTTI lambda name limitations](@ref ctti_name_lambda_limitations) and [limitations of jau::type_info](@ref type_info_limitations).
237 *
238 * #### C++11 Capturing Lambda Restrictions using std::function
239 * A capturing lambda in C++11 produces decoration code accessing the captured elements,<br />
240 * i.e. an anonymous helper class.<br />
241 * Due to this fact, the return type is an undefined lambda specific
242 * and hence `std::function` didn't support it when specified, probably.
243 *
244 * <pre>
245 template<typename R, typename C, typename... A>
246 inline function<R(A...)>
247 bind_member(C *base, R(C::*mfunc)(A...)) {
248 return ClassFunction<R, A...>(
249 (void*)base,
250 (void*)(*((void**)&mfunc)),
251 [&](A... args)->R{ (base->*mfunc)(args...); });
252 ^
253 | Capturing lambda function-pointer are undefined!
254 }
255 </pre>
256 *
257 * Capturing lambdas are supported by jau::function using func::lambda_target_t
258 * via constructor [`template<typename L> function(L func)`](@ref function_ctor_lambda), see above.
259 *
260 *
261 * @{
262 */
263
264 namespace func {
265
266 /** \addtogroup FunctionWrap
267 *
268 * @{
269 */
270
271 /**
272 * func::target_type identifier for specializations of func::target_t
273 * used by jau::function<R(A...)>::type().
274 *
275 * @see @ref function_overview "Function Overview"
276 */
277 enum class target_type : uint32_t {
278 /** Denotes a func::null_target_t */
279 null = 0,
280 /** Denotes a func::member_target_t */
281 member = 1,
282 /** Denotes a func::free_target_t */
283 free = 2,
284 /** Denotes a func::lambda_target_t */
285 lambda = 3,
286 /** Denotes a func::capval_target_t */
287 capval = 4,
288 /** Denotes a func::capref_target_t */
289 capref = 5,
290 /** Denotes a func::std_target_t */
291 std = 6
292 };
293
294 /**
295 * func::target_t pure-virtual interface for [jau::function](@ref function_def).
296 *
297 * @tparam R function return type
298 * @tparam A function arguments
299 * @see @ref function_overview "Function Overview"
300 */
301 template<typename R, typename... A>
302 class target_t {
303 private:
304 target_type ttype;
305
306 protected:
307 target_t(target_type ttype_) noexcept
308 : ttype(ttype_) {}
309
310 public:
311 virtual ~target_t() noexcept {}
312
313 target_t(const target_t &o) noexcept = default;
314 target_t(target_t &&o) noexcept = default;
315 target_t& operator=(const target_t &o) noexcept = default;
316 target_t& operator=(target_t &&o) noexcept = default;
317
318 /** Return the func::target_type of this invocation function wrapper */
319 constexpr target_type type() const noexcept { return ttype; }
320
321 virtual R operator()(A... args) = 0;
322 virtual bool operator==(const target_t<R, A...>& rhs) const noexcept = 0;
323 };
324
325 /**
326 * func::null_target_t implementation for no function.
327 * identifiable as jau::func::target_type::null via jau::function<R(A...)>::type().
328 *
329 * This special type is used for an empty [jau::function](@ref function_def) instance w/o holding a function,
330 * e.g. when created with the default constructor.
331 *
332 * @tparam R function return type
333 * @tparam A function arguments
334 * @see @ref function_overview "Function Overview"
335 */
336 template<typename R, typename... A>
337 class null_target_t final : public target_t<R, A...> {
338 public:
339 null_target_t() noexcept
340 : target_t<R, A...>( target_type::null )
341 { }
342
343 R operator()(A...) override {
344 return R();
345 }
346
347 bool operator==(const target_t<R, A...>& rhs) const noexcept override {
348 return target_t<R, A...>::type() == rhs.type();
349 }
350 };
351
352 /**
353 * func::member_target_t implementation for class member functions,
354 * identifiable as func::target_type::member via jau::function<R(A...)>::type().
355 *
356 * @tparam R function return type
357 * @tparam C0 class type holding the member-function
358 * @tparam C1 class derived from C0 or C0 of this base-pointer used to invoke the member-function
359 * @tparam A function arguments
360 * @see @ref function_overview "Function Overview"
361 */
362 template<typename R, typename C0, typename C1, typename... A>
363 class member_target_t final : public target_t<R, A...> {
364 private:
365 C1* base;
366 R(C0::*member)(A...);
367
368 public:
369 /**
370 * Construct a target_t<R, A...> instance from given this base-pointer and member-function.
371 *
372 * This factory function is only enabled if C0 is base of C1.
373 *
374 * @param _base this base-pointer of class C1 derived from C0 or C0 used to invoke the member-function
375 * @param _member member-function of class C0
376 * @return target_t<R, A...> instance holding the target-function details.
377 */
378 member_target_t(C1 *_base, R(C0::*_member)(A...),
379 std::enable_if_t<std::is_base_of_v<C0, C1>, bool> = true) noexcept
380 : target_t<R, A...>( target_type::member ),
381 base(_base), member(_member) { }
382
383 R operator()(A... args) override {
384 return (base->*member)(args...);
385 }
386
387 bool operator==(const target_t<R, A...>& rhs) const noexcept override {
388 const member_target_t<R, C0, C1, A...>* prhs = static_cast<const member_target_t<R, C0, C1, A...>*>(&rhs);
389 return this == prhs ||
390 ( target_t<R, A...>::type() == rhs.type() &&
391 base == prhs->base &&
392 member == prhs->member
393 );
394 }
395 };
396
397 /**
398 * func::free_target_t implementation for free functions,
399 * identifiable as func::target_type::free via jau::function<R(A...)>::type().
400 *
401 * @tparam R function return type
402 * @tparam A function arguments
403 * @see @ref function_overview "Function Overview"
404 */
405 template<typename R, typename... A>
406 class free_target_t final : public target_t<R, A...> {
407 private:
408 R(*function)(A...);
409
410 public:
411 free_target_t(R(*_function)(A...)) noexcept
412 : target_t<R, A...>( target_type::free ),
413 function(_function) { }
414
415 R operator()(A... args) override {
416 return (*function)(args...);
417 }
418
419 bool operator==(const target_t<R, A...>& rhs) const noexcept override {
420 const free_target_t<R, A...>* prhs = static_cast<const free_target_t<R, A...>*>(&rhs);
421 return this == prhs ||
422 ( target_t<R, A...>::type() == rhs.type() &&
423 function == prhs->function
424 );
425 }
426 };
427
428 /**
429 * func::lambda_target_t implementation for lambda closures,
430 * identifiable as func::target_type::lambda via jau::function<R(A...)>::type().
431 *
432 * @tparam R function return type
433 * @tparam L typename holding the lambda closure
434 * @tparam A function arguments
435 * @see @ref function_overview "Function Overview"
436 */
437 template<typename R, typename L, typename...A>
438 class lambda_target_t final : public target_t<R, A...>
439 {
440 private:
441 jau::type_info sig;
442 L function;
443
444 constexpr size_t detail_size() const noexcept { return sizeof(function); }
445
446 public:
447 lambda_target_t(L function_) noexcept
448 : target_t<R, A...>( target_type::lambda ),
449 sig( jau::make_ctti<R, L, A...>() ), function(function_)
450 { }
451
452 R operator()(A... args) override {
453 return function(args...);
454 }
455
456 bool operator==(const target_t<R, A...>& rhs) const noexcept override {
457 const lambda_target_t<R, L, A...>* prhs = static_cast<const lambda_target_t<R, L, A...>*>(&rhs);
458 return this == prhs ||
459 ( target_t<R, A...>::type() == rhs.type() &&
460 detail_size() == prhs->detail_size() && // fast: wrong size -> false, otherwise ...
461 sig == prhs->sig && // mixed: wrong jau::type_info -> false, otherwise ...
462 0 == ::memcmp((void*)&function, (void*)&prhs->function, sizeof(function)) // slow: compare the anonymous data chunk of the lambda
463 );
464 }
465 };
466
467 /**
468 * func::capval_target_t implementation for functions using a copy of a captured value,
469 * identifiable as func::target_type::capval via jau::function<R(A...)>::type().
470 *
471 * @tparam R function return type
472 * @tparam I typename holding the captured data used by the function
473 * @tparam A function arguments
474 * @see @ref function_overview "Function Overview"
475 */
476 template<typename R, typename I, typename... A>
477 class capval_target_t final : public target_t<R, A...> {
478 private:
479 R(*function)(I&, A...);
480 I data;
481
482 public:
483 /** Utilizes copy-ctor from 'const I& _data' */
484 capval_target_t(const I& _data, R(*_function)(I&, A...)) noexcept
485 : target_t<R, A...>( target_type::capval ),
486 function(_function), data(_data) { }
487
488 /** Utilizes move-ctor from moved 'I&& _data' */
489 capval_target_t(I&& _data, R(*_function)(I&, A...)) noexcept
490 : target_t<R, A...>( target_type::capval ),
491 function(_function), data(std::move(_data)) { }
492
493 R operator()(A... args) override {
494 return (*function)(data, args...);
495 }
496
497 bool operator==(const target_t<R, A...>& rhs) const noexcept override {
498 const capval_target_t<R, I, A...>* prhs = static_cast<const capval_target_t<R, I, A...>*>(&rhs);
499 return this == prhs ||
500 ( target_t<R, A...>::type() == rhs.type() &&
501 function == prhs->function &&
502 data == prhs->data
503 );
504 }
505 };
506
507 /**
508 * func::capref_target_t implementation for functions using a reference to a captured value,
509 * identifiable as func::target_type::capref via jau::function<R(A...)>::type().
510 *
511 * @tparam R function return type
512 * @tparam I typename holding the captured data used by the function
513 * @tparam A function arguments
514 * @see @ref function_overview "Function Overview"
515 */
516 template<typename R, typename I, typename... A>
517 class capref_target_t final : public target_t<R, A...> {
518 private:
519 R(*function)(I*, A...);
520 I* data_ptr;
521
522 public:
523 capref_target_t(I* _data_ptr, R(*_function)(I*, A...)) noexcept
524 : target_t<R, A...>( target_type::capref ),
525 function(_function), data_ptr(_data_ptr) { }
526
527 R operator()(A... args) override {
528 return (*function)(data_ptr, args...);
529 }
530
531 bool operator==(const target_t<R, A...>& rhs) const noexcept override {
532 const capref_target_t<R, I, A...>* prhs = static_cast<const capref_target_t<R, I, A...>*>(&rhs);
533 return this == prhs ||
534 ( target_t<R, A...>::type() == rhs.type() &&
535 function == prhs->function &&
536 data_ptr == prhs->data_ptr
537 );
538 }
539 };
540
541 /**
542 * func::std_target_t implementation for std::function instances,
543 * identifiable as func::target_type::std via jau::function<R(A...)>::type().
544 *
545 * Notable, instance is holding a unique uint64_t identifier
546 * to allow implementing the equality operator, not supported by std::function.
547 *
548 * @tparam R function return type
549 * @tparam A function arguments
550 * @see @ref function_overview "Function Overview"
551 */
552 template<typename R, typename... A>
553 class std_target_t : public target_t<R, A...> {
554 private:
555 uint64_t id;
556 std::function<R(A...)> function;
557
558 constexpr size_t detail_size() const noexcept { return sizeof(id)+sizeof(function); }
559
560 public:
561 std_target_t(uint64_t _id, std::function<R(A...)> _function) noexcept
562 : target_t<R, A...>( target_type::std ),
563 id(_id), function(_function) { }
564
565 std_target_t(uint64_t _id) noexcept
566 : target_t<R, A...>( target_type::std ),
567 id(_id), function() { }
568
569 R operator()(A... args) override {
570 return function(args...);
571 }
572
573 bool operator==(const target_t<R, A...>& rhs) const noexcept override {
574 const std_target_t<R, A...>* prhs = static_cast<const std_target_t<R, A...>*>(&rhs);
575 return this == prhs ||
576 ( target_t<R, A...>::type() == rhs.type() &&
577 id == prhs->id &&
578 detail_size() && prhs->detail_size()
579 );
580 }
581 };
582
583 /**@}*/
584
585 } /* namespace func */
586
587 constexpr uint32_t number(const func::target_type rhs) noexcept {
588 return static_cast<uint32_t>(rhs);
589 }
590 std::string to_string(const func::target_type v) noexcept;
591
592 /**
593 * Class template [jau::function](@ref function_def) is a general-purpose polymorphic function wrapper.
594 *
595 * See @ref function_overview "Function Overview".
596 *
597 * This is the dummy template variant, allowing the void- and non-void return type target specializations.
598 *
599 * @see @ref function_def "Function template definition"
600 */
601 template<typename Signature>
602 class function;
603
604 /**
605 * @anchor function_def
606 * Class template [jau::function](@ref function_def) is a general-purpose polymorphic function wrapper.
607 *
608 * See @ref function_overview "Function Overview".
609 *
610 * @tparam R function return type
611 * @tparam A function arguments
612 * @see @ref function_overview "Function Overview"
613 * @see @ref function_usage "Function Usage"
614 */
615 template<typename R, typename... A>
616 class function<R(A...)> final {
617 public:
618 /** The target function type, i.e. func::target_t<R, A...> */
619 typedef func::target_t<R, A...> target_type;
620
621 private:
622 std::shared_ptr<target_type> target_func;
623 size_t target_func_size;
624
625 public:
626 /** The target function return type R */
627 typedef R result_type;
628
629 /**
630 * \brief Null function constructor
631 *
632 * @anchor function_ctor_def
633 * Constructs an instance with a null target function.
634 * @see @ref function_overview "function Overview"
635 * @see @ref function_usage "function Usage"
636 */
637 function() noexcept
638 : target_func( std::make_shared<func::null_target_t<R, A...>>() ),
639 target_func_size( sizeof(func::null_target_t<R, A...>))
640 { }
641
642 /**
643 * \brief Null function constructor
644 *
645 * @anchor function_ctor_nullptr
646 * Constructs an instance with a null target function.
647 * @see @ref function_overview "function Overview"
648 * @see @ref function_usage "function Usage"
649 */
650 function(std::nullptr_t ) noexcept
651 : target_func( std::make_shared<func::null_target_t<R, A...>>() ),
652 target_func_size( sizeof(func::null_target_t<R, A...>))
653 { }
654
655 /**
656 * \brief target_type constructor
657 *
658 * @anchor function_ctor_target_type
659 * Constructs an instance with the given shared target function pointer.
660 * @see @ref function_overview "function Overview"
661 * @see @ref function_usage "function Usage"
662 */
663 explicit function(std::shared_ptr<target_type> _funcPtr, size_t asize_) noexcept
664 : target_func( _funcPtr ),
665 target_func_size( asize_ )
666 { }
667
668 /**
669 * \brief Free function constructor
670 *
671 * @anchor function_ctor_free
672 * Constructs an instance by taking a free target function, which may also be a non-capturing lambda if explicitly bind_free().
673 * @see @ref function_overview "function Overview"
674 * @see @ref function_usage "function Usage"
675 */
676 function(R(*func)(A...)) noexcept
677 : target_func( std::make_shared<func::free_target_t<R, A...>>(func) ),
678 target_func_size( sizeof(func::free_target_t<R, A...>))
679 { }
680
681 /**
682 * \brief Lambda function constructor
683 *
684 * @anchor function_ctor_lambda
685 * Constructs an instance by taking a lambda function.
686 * @tparam L typename holding the lambda closure
687 * @param func the lambda reference
688 * @see @ref function_overview "function Overview"
689 * @see @ref function_usage "function Usage"
690 */
691 template<typename L,
692 std::enable_if_t<!std::is_same_v<L, std::shared_ptr<target_type>> &&
693 !std::is_pointer_v<L> &&
694 !std::is_same_v<L, R(A...)> &&
695 !std::is_same_v<L, function<R(A...)>>
696 , bool> = true>
697 function(L func) noexcept
698 : target_func( std::make_shared<func::lambda_target_t<R, L, A...>>(func) ),
699 target_func_size( sizeof(func::lambda_target_t<R, L, A...>))
700 { }
701
702 /**
703 * \brief Member function constructor
704 *
705 * \anchor function_ctor_member
706 * Constructs an instance by taking a member target function.
707 * @tparam C0 class type holding the member-function
708 * @tparam C1 class derived from C0 or C0 of this base-pointer used to invoke the member-function
709 * @param base pointer to the class instance of the member function
710 * @param mfunc member function of class
711 * @see @ref function_overview "function Overview"
712 * @see @ref function_usage "function Usage"
713 */
714 template<typename C0, typename C1>
715 function(C1 *base, R(C0::*mfunc)(A...)) noexcept
716 : target_func( std::make_shared<func::member_target_t<R, C0, C1, A...>>(base, mfunc) ),
717 target_func_size( sizeof(func::member_target_t<R, C0, C1, A...>))
718 { }
719
720 /**
721 * \brief Capture by value (copy) function constructor
722 *
723 * @anchor function_ctor_capval_copy
724 * Constructs an instance by copying the captured value and the given non-void function to
725 * an anonymous function using func::capval_target_t.
726 *
727 * `const I& data` will be copied into func::capval_target_t and hence captured by copy.
728 *
729 * The function invocation will have the reference of the copied data being passed to the target function for efficiency.
730 *
731 * @tparam I typename holding the captured data used by the function
732 * @param data data type instance holding the captured data
733 * @param func function with `R` return value and `A...` arguments.
734 * @see @ref function_overview "function Overview"
735 * @see @ref function_usage "function Usage"
736 */
737 template<typename I>
738 function(const I& data, R(*func)(I&, A...)) noexcept
739 : target_func( std::make_shared<func::capval_target_t<R, I, A...>>(data, func) ),
740 target_func_size( sizeof(func::capval_target_t<R, I, A...>))
741 { }
742
743 /**
744 * \brief Capture by value (move) function constructor
745 *
746 * @anchor function_ctor_capval_move
747 * Constructs an instance by moving the captured value and copying the given non-void function to
748 * an anonymous function using func::capval_target_t.
749 *
750 * `I&& data` will be moved into func::capval_target_t.
751 *
752 * The function invocation will have the reference of the moved data being passed to the target function for efficiency.
753 *
754 * @tparam I typename holding the captured data used by the function
755 * @param data data type instance holding the captured data
756 * @param func function with `R` return value and `A...` arguments.
757 * @see @ref function_overview "function Overview"
758 * @see @ref function_usage "function Usage"
759 */
760 template<typename I>
761 function(I&& data, R(*func)(I&, A...)) noexcept
762 : target_func( std::make_shared<func::capval_target_t<R, I, A...>>(std::move(data), func) ),
763 target_func_size( sizeof(func::capval_target_t<R, I, A...>))
764 { }
765
766 /**
767 * \brief Capture by reference function constructor
768 *
769 * @anchor function_ctor_capref
770 * Constructs an instance by passing the captured reference (pointer) to the value and non-void function to
771 * an anonymous function using func::capref_target_t.
772 *
773 * The function invocation will have the reference of the data being passed to the target function.
774 *
775 * @tparam I typename holding the captured data used by the function
776 * @param data_ptr data type reference to instance holding the captured data
777 * @param func function with `R` return value and `A...` arguments.
778 * @see @ref function_overview "function Overview"
779 * @see @ref function_usage "function Usage"
780 */
781 template<typename I>
782 function(I* data_ptr, R(*func)(I*, A...)) noexcept
783 : target_func( std::make_shared<func::capref_target_t<R, I, A...>>(data_ptr, func) ),
784 target_func_size( sizeof(func::capref_target_t<R, I, A...>))
785 { }
786
787 /**
788 * \brief std::function constructor
789 *
790 * @anchor function_ctor_std
791 * Constructs an instance by copying the std::function to
792 * an anonymous function using func::std_target_t.
793 *
794 * Notable, instance is holding the given unique uint64_t identifier
795 * to allow implementing the equality operator w/o RTTI, not supported by std::function.
796 *
797 * @param func free-function with `R` return value and `A...` arguments.
798 * @see @ref function_overview "function Overview"
799 * @see @ref function_usage "function Usage"
800 */
801 function(uint64_t id, std::function<R(A...)> func) noexcept
802 : target_func( std::make_shared<func::std_target_t<R, A...>>(id, func) ),
803 target_func_size( sizeof(func::std_target_t<R, A...>))
804 { }
805
806 function(const function &o) noexcept = default;
807 function(function &&o) noexcept = default;
808 function& operator=(const function &o) noexcept = default;
809 function& operator=(function &&o) noexcept = default;
810
811 /** Return the jau::func::type of this instance */
812 constexpr func::target_type type() const noexcept { return target_func->type(); }
813
814 /** Returns true if this instance does not hold a callable target function, i.e. is of func::target_type::null. */
815 constexpr bool is_null() const noexcept { return func::target_type::null == target_func->type(); }
816
817 /** Returns true if this instance holds a callable target function, i.e. is not of func::target_type::null. */
818 explicit constexpr operator bool() const noexcept { return !is_null(); }
819
820 /** Returns signature of this function prototype R(A...) w/o underlying target function details. */
821 jau::type_info signature() const noexcept {
822 return jau::make_ctti<R(A...)>();
823 }
824
825 /** Returns the size of the target type */
826 constexpr size_t target_size() const noexcept { return target_func_size; }
827
828 std::string toString() const {
829 return "function<" + to_string( type() ) + ", " + signature().demangled_name() + ">( sz target_data " +
830 std::to_string( target_func_size ) + " + shared_ptr " +
831 std::to_string( sizeof( target_func ) ) + " + extra " +
832 std::to_string( sizeof( target_func_size ) ) + " -> " +
833 std::to_string( sizeof( *this ) + target_func_size ) + " ) ";
834 }
835
836 constexpr R operator()(A... args) const {
837 return (*target_func)(args...);
838 }
839 constexpr R operator()(A... args) {
840 return (*target_func)(args...);
841 }
842
843 constexpr bool operator==(const function<R(A...)>& rhs) const noexcept {
844 return target_func->operator==(*rhs.target_func);
845 }
846 constexpr bool operator!=(const function<R(A...)>& rhs) const noexcept {
847 return !operator==(rhs);
848 }
849 };
850
851 /**
852 * Equal operator using different jau::function<R(A...)> return and argument types for both arguments,
853 * always returns false.
854 * @tparam Rl left function return type
855 * @tparam Al left function arguments
856 * @tparam Fl left function Fl<Rl(<Al...)>
857 * @tparam Rr right function return type
858 * @tparam Ar right function arguments
859 * @tparam Fr right function Fr<Rr(<Ar...)>
860 * @param lhs left function Fl<Rl(<Al...)>
861 * @param rhs right function Fr<Rr(<Ar...)>
862 * @return false
863 * @see @ref function_overview "function Overview"
864 * @see @ref function_usage "function Usage"
865 */
866 template<typename Rl, typename... Al, template <typename...> class Fl = function,
867 typename Rr, typename... Ar, template <typename...> class Fr = function,
868 std::enable_if_t< !std::is_same_v< Fl<Rl(Al...)>, Fr<Rr(Ar...)> >
869 , bool> = true>
870 bool operator==(const function<Rl(Al...)>& lhs, const function<Rr(Ar...)>& rhs) noexcept
871 {
872 (void)lhs;
873 (void)rhs;
874 return false;
875 }
876
877 /**
878 * Equal operator using same jau::function<R(A...)> return and argument types for both arguments,
879 * returning actual result of equality operation.
880 * @tparam Rl left function return type
881 * @tparam Al left function arguments
882 * @tparam Fl left function Fl<Rl(<Al...)>
883 * @tparam Rr right function return type
884 * @tparam Ar right function arguments
885 * @tparam Fr right function Fr<Rr(<Ar...)>
886 * @param lhs left function Fl<Rl(<Al...)>
887 * @param rhs right function Fr<Rr(<Ar...)>
888 * @return equality result of same type functions
889 * @see @ref function_overview "function Overview"
890 * @see @ref function_usage "function Usage"
891 */
892 template<typename Rl, typename... Al, template <typename...> class Fl = function,
893 typename Rr, typename... Ar, template <typename...> class Fr = function,
894 std::enable_if_t< std::is_same_v< Fl<Rl(Al...)>, Fr<Rr(Ar...)> >
895 , bool> = true>
896 bool operator==(const function<Rl(Al...)>& lhs, const function<Rr(Ar...)>& rhs) noexcept
897 { return lhs.operator==( rhs ); }
898
899 /**
900 * Unequal operator using two jau::function<R(A...)> types for both arguments.
901 * @tparam Rl left function return type
902 * @tparam Al left function arguments
903 * @tparam Fl left function Fl<Rl(<Al...)>
904 * @tparam Rr right function return type
905 * @tparam Ar right function arguments
906 * @tparam Fr right function Fr<Rr(<Ar...)>
907 * @param lhs left function Fl<Rl(<Al...)>
908 * @param rhs right function Fr<Rr(<Ar...)>
909 * @return unequality result of same type functions
910 * @see @ref function_overview "function Overview"
911 * @see @ref function_usage "function Usage"
912 */
913 template<typename Rl, typename... Al, template <typename...> typename Fl = function,
914 typename Rr, typename... Ar, template <typename...> typename Fr = function>
915 bool operator!=(const function<Rl(Al...)>& lhs, const function<Rr(Ar...)>& rhs) noexcept
916 { return !( lhs == rhs ); }
917
918 /**
919 * Bind given class instance and non-void member function to
920 * an anonymous function using func_member_targer_t.
921 *
922 * @tparam R function return type
923 * @tparam C0 class type holding the member-function
924 * @tparam C1 class derived from C0 or C0 of this base-pointer used to invoke the member-function
925 * @tparam A function arguments
926 * @param base class instance `this` pointer
927 * @param mfunc member-function with `R` return value and `A...` arguments.
928 * @return anonymous function
929 * @see @ref function_ctor_member "function constructor for member function"
930 * @see @ref function_overview "function Overview"
931 * @see @ref function_usage "function Usage"
932 */
933 template<typename R, typename C0, typename C1, typename... A>
934 inline jau::function<R(A...)>
935 bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept {
936 return function<R(A...)>( std::make_shared<func::member_target_t<R, C0, C1, A...>>(base, mfunc),
937 sizeof(func::member_target_t<R, C0, C1, A...>) );
938 }
939
940 /**
941 * Bind given class instance and non-void member function to
942 * an anonymous function using func_member_targer_t.
943 *
944 * @tparam R function return type
945 * @tparam C class type holding the member-function and of this base pointer
946 * @tparam A function arguments
947 * @param base class instance `this` pointer
948 * @param mfunc member-function with `R` return value and `A...` arguments.
949 * @return anonymous function
950 * @see @ref function_ctor_member "function constructor for member function"
951 * @see @ref function_overview "function Overview"
952 * @see @ref function_usage "function Usage"
953 */
954 template<typename R, typename C, typename... A>
955 inline jau::function<R(A...)>
956 bind_member(C *base, R(C::*mfunc)(A...)) noexcept {
957 return function<R(A...)>( std::make_shared<func::member_target_t<R, C, C, A...>>(base, mfunc),
958 sizeof(func::member_target_t<R, C, C, A...>) );
959 }
960
961 /**
962 * Bind given class instance and void member function to
963 * an anonymous function using func_member_targer_t.
964 *
965 * @tparam C0 class type holding the member-function
966 * @tparam C1 class derived from C0 or C0 of this base-pointer used to invoke the member-function
967 * @tparam A function arguments
968 * @param base class instance `this` pointer
969 * @param mfunc member-function with `A...` arguments.
970 * @return anonymous function
971 * @see @ref function_ctor_member "function constructor for member function"
972 * @see @ref function_overview "function Overview"
973 * @see @ref function_usage "function Usage"
974 */
975 template<typename C0, typename C1, typename... A>
976 inline jau::function<void(A...)>
977 bind_member(C1 *base, void(C0::*mfunc)(A...)) noexcept {
978 return function<void(A...)>( std::make_shared<func::member_target_t<void, C0, C1, A...>>(base, mfunc),
979 sizeof(func::member_target_t<void, C0, C1, A...>) );
980 }
981
982 /**
983 * Bind given class instance and void member function to
984 * an anonymous function using func_member_targer_t.
985 *
986 * @tparam C class type holding the member-function and of this base pointer
987 * @tparam A function arguments
988 * @param base class instance `this` pointer
989 * @param mfunc member-function with `A...` arguments.
990 * @return anonymous function
991 * @see @ref function_ctor_member "function constructor for member function"
992 * @see @ref function_overview "function Overview"
993 * @see @ref function_usage "function Usage"
994 */
995 template<typename C, typename... A>
996 inline jau::function<void(A...)>
997 bind_member(C *base, void(C::*mfunc)(A...)) noexcept {
998 return function<void(A...)>( std::make_shared<func::member_target_t<void, C, C, A...>>(base, mfunc),
999 sizeof(func::member_target_t<void, C, C, A...>) );
1000 }
1001
1002 /**
1003 * Bind given non-void free-function to
1004 * an anonymous function using func::free_target_t.
1005 *
1006 * @tparam R function return type
1007 * @tparam A function arguments
1008 * @param func free-function with `R` return value and `A...` arguments.
1009 * @return anonymous function
1010 * @see @ref function_ctor_free "function constructor for free function"
1011 * @see @ref function_overview "function Overview"
1012 * @see @ref function_usage "function Usage"
1013 */
1014 template<typename R, typename... A>
1015 inline jau::function<R(A...)>
1016 bind_free(R(*func)(A...)) noexcept {
1017 return function<R(A...)>( std::make_shared<func::free_target_t<R, A...>>(func),
1018 sizeof(func::free_target_t<R, A...>) );
1019 }
1020
1021 /**
1022 * Bind given void free-function to
1023 * an anonymous function using func::free_target_t.
1024 *
1025 * @tparam A function arguments
1026 * @param func free-function with `A...` arguments.
1027 * @return anonymous function
1028 * @see @ref function_ctor_free "function constructor for free function"
1029 * @see @ref function_overview "function Overview"
1030 * @see @ref function_usage "function Usage"
1031 */
1032 template<typename... A>
1033 inline jau::function<void(A...)>
1034 bind_free(void(*func)(A...)) noexcept {
1035 return function<void(A...)>( std::make_shared<func::free_target_t<void, A...>>(func),
1036 sizeof(func::free_target_t<void, A...>) );
1037 }
1038
1039#if 0
1040 // Lacks proper template type deduction, sadly
1041
1042 /**
1043 * Bind given capturing non-void returning lambda by copying the it to
1044 * an anonymous function using func::lambda_target_t.
1045 *
1046 * @tparam R function return type
1047 * @tparam L typename holding the lambda closure
1048 * @tparam A function arguments
1049 * @param func the lambda reference
1050 * @return anonymous function
1051 * @see @ref function_ctor_lambda "function constructor for lambda"
1052 * @see @ref function_overview "function Overview"
1053 * @see @ref function_usage "function Usage"
1054 */
1055 template<typename R, typename L, typename... A>
1056 inline jau::function<R(A...)>
1057 bind_lambda(L func) noexcept {
1058 return function<R(A...)>( std::make_shared<func::lambda_target_t<R, L, A...>>(func),
1059 sizeof(func::lambda_target_t<R, L, A...>) );
1060 }
1061
1062 /**
1063 * Bind given capturing void returning lambda by copying the it to
1064 * an anonymous function using func::lambda_target_t.
1065 *
1066 * @tparam L typename holding the lambda closure
1067 * @tparam A function arguments
1068 * @param func the lambda reference
1069 * @return anonymous function
1070 * @see @ref function_ctor_lambda "function constructor for lambda"
1071 * @see @ref function_overview "function Overview"
1072 * @see @ref function_usage "function Usage"
1073 */
1074 template<typename L, typename... A>
1075 inline jau::function<void(A...)>
1076 bind_lambda(L func) noexcept {
1077 return function<void(A...)>( std::make_shared<func::lambda_target_t<void, L, A...>>(func),
1078 sizeof(func::lambda_target_t<void, L, A...>) );
1079 }
1080#endif
1081
1082 /**
1083 * Bind given data by copying the captured value and the given non-void function to
1084 * an anonymous function using func::capval_target_t.
1085 *
1086 * `const I& data` will be copied into func::capval_target_t and hence captured by copy.
1087 *
1088 * The function invocation will have the reference of the copied data being passed to the target function for efficiency.
1089 *
1090 * @tparam R function return type
1091 * @tparam I typename holding the captured data used by the function
1092 * @tparam A function arguments
1093 * @param data data type instance holding the captured data
1094 * @param func function with `R` return value and `A...` arguments.
1095 * @return anonymous function
1096 * @see @ref function_ctor_capval_copy "function constructor for copying capturing value"
1097 * @see @ref function_overview "function Overview"
1098 * @see @ref function_usage "function Usage"
1099 */
1100 template<typename R, typename I, typename... A>
1101 inline jau::function<R(A...)>
1102 bind_capval(const I& data, R(*func)(I&, A...)) noexcept {
1103 return function<R(A...)>( std::make_shared<func::capval_target_t<R, I, A...>>(data, func),
1104 sizeof(func::capval_target_t<R, I, A...>) );
1105 }
1106
1107 /**
1108 * Bind given data by copying the captured value and the given void function to
1109 * an anonymous function using func::capval_target_t.
1110 *
1111 * `const I& data` will be copied into func::capval_target_t and hence captured by copy.
1112 *
1113 * The function invocation will have the reference of the copied data being passed to the target function for efficiency.
1114 *
1115 * @tparam I typename holding the captured data used by the function
1116 * @tparam A function arguments
1117 * @param data data type instance holding the captured data
1118 * @param func function with `A...` arguments.
1119 * @return anonymous function
1120 * @see @ref function_ctor_capval_copy "function constructor for copying capturing value"
1121 * @see @ref function_overview "function Overview"
1122 * @see @ref function_usage "function Usage"
1123 */
1124 template<typename I, typename... A>
1125 inline jau::function<void(A...)>
1126 bind_capval(const I& data, void(*func)(I&, A...)) noexcept {
1127 return function<void(A...)>( std::make_shared<func::capval_target_t<void, I, A...>>(data, func),
1128 sizeof(func::capval_target_t<void, I, A...>) );
1129 }
1130
1131 /**
1132 * Bind given data by moving the captured value and copying the given non-void function to
1133 * an anonymous function using func::capval_target_t.
1134 *
1135 * `I&& data` will be moved into func::capval_target_t.
1136 *
1137 * The function invocation will have the reference of the moved data being passed to the target function for efficiency.
1138 *
1139 * @tparam R function return type
1140 * @tparam I typename holding the captured data used by the function
1141 * @tparam A function arguments
1142 * @param data data type instance holding the captured data
1143 * @param func function with `R` return value and `A...` arguments.
1144 * @return anonymous function
1145 * @see @ref function_ctor_capval_move "function constructor for moving capturing value"
1146 * @see @ref function_overview "function Overview"
1147 * @see @ref function_usage "function Usage"
1148 */
1149 template<typename R, typename I, typename... A>
1150 inline jau::function<R(A...)>
1151 bind_capval(I&& data, R(*func)(I&, A...)) noexcept {
1152 return function<R(A...)>( std::make_shared<func::capval_target_t<R, I, A...>>(std::move(data), func),
1153 sizeof(func::capval_target_t<R, I, A...>) );
1154 }
1155
1156 /**
1157 * Bind given data by moving the captured value and copying the given void function to
1158 * an anonymous function using func::capval_target_t.
1159 *
1160 * `I&& data` will be moved into func::capval_target_t.
1161 *
1162 * The function invocation will have the reference of the moved data being passed to the target function for efficiency.
1163 *
1164 * @tparam I typename holding the captured data used by the function
1165 * @tparam A function arguments
1166 * @param data data type instance holding the captured data
1167 * @param func function with `A...` arguments.
1168 * @return anonymous function
1169 * @see @ref function_ctor_capval_move "function constructor for moving capturing value"
1170 * @see @ref function_overview "function Overview"
1171 * @see @ref function_usage "function Usage"
1172 */
1173 template<typename I, typename... A>
1174 inline jau::function<void(A...)>
1175 bind_capval(I&& data, void(*func)(I&, A...)) noexcept {
1176 return function<void(A...)>( std::make_shared<func::capval_target_t<void, I, A...>>(std::move(data), func),
1177 sizeof(func::capval_target_t<void, I, A...>) );
1178 }
1179
1180 /**
1181 * Bind given data by passing the captured reference (pointer) to the value and non-void function to
1182 * an anonymous function using func::capref_target_t.
1183 *
1184 * The function invocation will have the reference of the data being passed to the target function.
1185 *
1186 * @tparam R function return type
1187 * @tparam I typename holding the captured data used by the function
1188 * @tparam A function arguments
1189 * @param data_ptr data type reference to instance holding the captured data
1190 * @param func function with `R` return value and `A...` arguments.
1191 * @return anonymous function
1192 * @see @ref function_ctor_capref "function constructor for capturing reference"
1193 * @see @ref function_overview "function Overview"
1194 * @see @ref function_usage "function Usage"
1195 */
1196 template<typename R, typename I, typename... A>
1197 inline jau::function<R(A...)>
1198 bind_capref(I* data_ptr, R(*func)(I*, A...)) noexcept {
1199 return function<R(A...)>( std::make_shared<func::capref_target_t<R, I, A...>>(data_ptr, func),
1200 sizeof(func::capref_target_t<R, I, A...>) );
1201 }
1202
1203 /**
1204 * Bind given data by passing the captured reference (pointer) to the value and void function to
1205 * an anonymous function using func::capref_target_t.
1206 *
1207 * The function invocation will have the reference of the data being passed to the target function.
1208 *
1209 * @tparam I typename holding the captured data used by the function
1210 * @tparam A function arguments
1211 * @param data_ptr data type reference to instance holding the captured data
1212 * @param func function with `A...` arguments.
1213 * @return anonymous function
1214 * @see @ref function_ctor_capref "function constructor for capturing reference"
1215 * @see @ref function_overview "function Overview"
1216 * @see @ref function_usage "function Usage"
1217 */
1218 template<typename I, typename... A>
1219 inline jau::function<void(A...)>
1220 bind_capref(I* data_ptr, void(*func)(I*, A...)) noexcept {
1221 return function<void(A...)>( std::make_shared<func::capref_target_t<void, I, A...>>(data_ptr, func),
1222 sizeof(func::capref_target_t<void, I, A...>) );
1223 }
1224
1225 /**
1226 * Bind given non-void std::function to
1227 * an anonymous function using func::std_target_t.
1228 *
1229 * Notable, instance is holding the given unique uint64_t identifier
1230 * to allow implementing the equality operator w/o RTTI, not supported by std::function.
1231 *
1232 * @tparam R function return type
1233 * @tparam A function arguments
1234 * @param func free-function with `R` return value and `A...` arguments.
1235 * @return anonymous function
1236 * @see @ref function_ctor_std "function constructor for std::function"
1237 * @see @ref function_overview "function Overview"
1238 * @see @ref function_usage "function Usage"
1239 */
1240 template<typename R, typename... A>
1241 inline jau::function<R(A...)>
1242 bind_std(uint64_t id, std::function<R(A...)> func) noexcept {
1243 return function<R(A...)>( std::make_shared<func::std_target_t<R, A...>>(id, func),
1244 sizeof(func::std_target_t<R, A...>) );
1245 }
1246
1247 /**
1248 * Bind given void std::function to
1249 * an anonymous function using func::std_target_t.
1250 *
1251 * Notable, instance is holding the given unique uint64_t identifier
1252 * to allow implementing the equality operator w/o RTTI, not supported by std::function.
1253 *
1254 * @tparam A function arguments
1255 * @param func free-function with `A...` arguments.
1256 * @return anonymous function
1257 * @see @ref function_ctor_std "function constructor for std::function"
1258 * @see @ref function_overview "function Overview"
1259 * @see @ref function_usage "function Usage"
1260 */
1261 template<typename... A>
1262 inline jau::function<void(A...)>
1263 bind_std(uint64_t id, std::function<void(A...)> func) noexcept {
1264 return function<void(A...)>( std::make_shared<func::std_target_t<void, A...>>(id, func),
1265 sizeof(func::std_target_t<void, A...>) );
1266 }
1267
1268 /**@}*/
1269
1270} // namespace jau
1271
1272/** \example test_functional01.cpp
1273 * This C++ unit test validates the jau::function<R(A...)> and all its jau::func::target_t specializations.
1274 */
1275
1276/** \example test_functional_perf.hpp
1277 * This C++ unit test benchmarks the jau::function<R(A...)> and all its jau::func::target_t specializations.
1278 */
1279
1280#endif /* JAU_FUNCTIONAL_HPP_ */
func::capref_target_t implementation for functions using a reference to a captured value,...
R operator()(A... args) override
bool operator==(const target_t< R, A... > &rhs) const noexcept override
capref_target_t(I *_data_ptr, R(*_function)(I *, A...)) noexcept
func::capval_target_t implementation for functions using a copy of a captured value,...
capval_target_t(const I &_data, R(*_function)(I &, A...)) noexcept
Utilizes copy-ctor from 'const I& _data'.
bool operator==(const target_t< R, A... > &rhs) const noexcept override
capval_target_t(I &&_data, R(*_function)(I &, A...)) noexcept
Utilizes move-ctor from moved 'I&& _data'.
R operator()(A... args) override
func::free_target_t implementation for free functions, identifiable as func::target_type::free via ja...
Definition: functional.hpp:881
free_target_t(R(*_function)(A...)) noexcept
bool operator==(const target_t< R, A... > &rhs) const noexcept override
R operator()(A... args) override
func::lambda_target_t implementation for lambda closures, identifiable as func::target_type::lambda v...
Definition: functional.hpp:922
R operator()(A... args) override
lambda_target_t(L function_) noexcept
bool operator==(const target_t< R, A... > &rhs) const noexcept override
func::member_target_t implementation for class member functions, identifiable as func::target_type::m...
Definition: functional.hpp:783
R operator()(A... args) override
member_target_t(C1 *_base, R(C0::*_member)(A...), std::enable_if_t< std::is_base_of_v< C0, C1 >, bool >=true) noexcept
Construct a target_t<R, A...> instance from given this base-pointer and member-function.
bool operator==(const target_t< R, A... > &rhs) const noexcept override
func::null_target_t implementation for no function.
Definition: functional.hpp:749
R operator()(A...) override
bool operator==(const target_t< R, A... > &rhs) const noexcept override
func::std_target_t implementation for std::function instances, identifiable as func::target_type::std...
R operator()(A... args) override
std_target_t(uint64_t _id, std::function< R(A...)> _function) noexcept
bool operator==(const target_t< R, A... > &rhs) const noexcept override
std_target_t(uint64_t _id) noexcept
func::target_t pure-virtual interface for jau::function.
target_t & operator=(const target_t &o) noexcept=default
target_t(const target_t &o) noexcept=default
target_t(target_type ttype_) noexcept
virtual R operator()(A... args)=0
target_t(target_t &&o) noexcept=default
target_t & operator=(target_t &&o) noexcept=default
virtual ~target_t() noexcept
virtual bool operator==(const target_t< R, A... > &rhs) const noexcept=0
constexpr target_type type() const noexcept
Return the func::target_type of this invocation function wrapper.
func::target_t< R, A... > target_type
The target function type, i.e.
function(C1 *base, R(C0::*mfunc)(A...)) noexcept
Member function constructor.
function & operator=(function &&o) noexcept=default
constexpr bool operator!=(const function< R(A...)> &rhs) const noexcept
constexpr size_t target_size() const noexcept
Returns the size of the target type
constexpr func::target_type type() const noexcept
Return the jau::func::type of this instance.
function(L func) noexcept
Lambda function constructor.
std::string toString() const
constexpr bool operator==(const function< R(A...)> &rhs) const noexcept
function(uint64_t id, std::function< R(A...)> func) noexcept
std::function constructor
function(I &&data, R(*func)(I &, A...)) noexcept
Capture by value (move) function constructor.
function(const I &data, R(*func)(I &, A...)) noexcept
Capture by value (copy) function constructor.
function(R(*func)(A...)) noexcept
Free function constructor.
constexpr bool is_null() const noexcept
Returns true if this instance does not hold a callable target function, i.e.
function() noexcept
Null function constructor.
function(std::shared_ptr< target_type > _funcPtr, size_t asize_) noexcept
target_type constructor
R result_type
The target function return type R.
function & operator=(const function &o) noexcept=default
constexpr R operator()(A... args) const
function(function &&o) noexcept=default
jau::type_info signature() const noexcept
Returns signature of this function prototype R(A...) w/o underlying target function details.
function(const function &o) noexcept=default
function(I *data_ptr, R(*func)(I *, A...)) noexcept
Capture by reference function constructor.
function(std::nullptr_t) noexcept
Null function constructor.
constexpr R operator()(A... args)
Class template jau::function is a general-purpose static-polymorphic function wrapper.
Generic type information using either Runtime type information (RTTI) or Compile time type informatio...
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
jau::type_info make_ctti() noexcept
Constructs a jau::type_info instance based on given type T using template Compile Time Type Informati...
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
target_type
func::target_type identifier for the target function delegate_t<R, A...> object, exposed by jau::func...
Definition: functional.hpp:341
jau::function< R(A...)> bind_free(R(*func)(A...)) noexcept
Bind given non-void free-function to an anonymous function using func::free_target_t.
jau::function< R(A...)> bind_std(uint64_t id, std::function< R(A...)> func) noexcept
Bind given non-void std::function to an anonymous function using func::std_target_t.
jau::function< R(A...)> bind_capval(const I &data, R(*func)(I &, A...)) noexcept
Bind given data by copying the captured value and the given non-void function to an anonymous functio...
jau::function< R(A...)> bind_capref(I *data_ptr, R(*func)(I *, A...)) noexcept
Bind given data by passing the captured reference (pointer) to the value and non-void function to an ...
constexpr uint32_t number(const func::target_type rhs) noexcept
@ null
Denotes a func::null_target_t.
@ lambda
Denotes a func::lambda_target_t.
@ capval
Denotes a func::capval_target_t.
@ capref
Denotes a func::capref_target_t.
@ member
Denotes a func::member_target_t.
@ free
Denotes a func::free_target_t.
@ std
Denotes a func::std_target_t.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:150
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Definition: callocator.hpp:163
STL namespace.