diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-28 12:46:51 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-28 12:46:51 -0400 |
| commit | 3612806d5ea470f5dd2fb5a6e7f5be9de716a67e (patch) | |
| tree | 2f41f52b40059bf05013f30194201934c446864a | |
| parent | b9f23559d8bc36356ea0b6264c91d82dba3fb74d (diff) | |
pktmpln: first-pass, adds _1, _2, and _3
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | pk.h.in | 21 | ||||
| -rw-r--r-- | pktmpln.h | 35 |
3 files changed, 62 insertions, 0 deletions
@@ -15,6 +15,7 @@ SRC = \ pkstn.h \ pkuuid.h \ pkbktarr.h \ + pktmpln.h \ test/pkmacros.c \ test/pkmacros.cpp \ test/pkmem-types.c \ @@ -52,6 +53,7 @@ all: options .WAIT clean .WAIT \ pktmr \ pkuuid \ pkbktarr \ + pktmpln \ test/test-pkmem-types test/test-pkmem-types-cpp \ test/test-pkmem test/test-pkmem-cpp \ test/test-pkmacros test/test-pkmacros-cpp \ @@ -105,6 +107,8 @@ pkuuid: pkuuid.gch pkuuid.gchpp pkbktarr: pkbktarr.gch pkbktarr.gchpp +pktmpln: pktmpln.gch pktmpln.gchpp + build: pkmacros build: pkmem-types build: pkmem @@ -127,6 +131,7 @@ build: pkbktarr pktmr.h \ pkuuid.h \ pkbktarr.h \ + pktmpln.h \ >> pk.h echo "#endif /* PK_SINGLE_HEADER_FILE_H */" >> pk.h sed -i -r \ @@ -207,6 +212,7 @@ test: pkstn test/test-pkstn test/test-pkstn-cpp test: pktmr test/test-pktmr test/test-pktmr-cpp test: pkuuid test/test-pkuuid test/test-pkuuid-cpp test: pkbktarr test/test-pkbktarr test/test-pkbktarr-cpp +test: pktmpln test: @echo "" ./test/test-pkmacros ; echo Result: $$? "\n" @@ -251,6 +251,27 @@ * arr.~pk_bkt_arr<int>(); // manually call dtor for globals * ``` * +******************************************************************************** +* pktmpl.h: only contains c++ templates, no IMPL. +* +* Provides template structs for trampolines, allowing c-style callbacks with +* capturing lambdas. +* +* Examples: +* ```c++ +* int some_counter = 0; +* using IterCbWrapper = pk_tmpln_1<void, int*, void*>; +* IterCbWrapper cb_wrapper{}; +* cb_wrapper.func = [&some_counter](int *lhs) +* { +* (void)lhs; +* some_counter += 1; +* return; +* }; +* pk_bkt_arr_iterate(&bkt_arr, &IterCbWrapper::invoke, &cb_wrapper); +* assert(some_count == 1); +* ``` +* *******************************************************************************/ #define PK_VERSION "@@PK_VERSION@@" diff --git a/pktmpln.h b/pktmpln.h new file mode 100644 index 0000000..64000ef --- /dev/null +++ b/pktmpln.h @@ -0,0 +1,35 @@ +#ifndef PK_PKTMPLN_H +#define PK_PKTMPLN_H + +#if defined (__cplusplus) +#include <functional> +template<typename Ret, typename A1, typename B1> +struct pk_tmpln_1 { + using FuncType = std::function<Ret(A1)>; + FuncType func; + static Ret invoke(void *ptr, B1 b1) { + auto *self = static_cast<pk_tmpln_1*>(ptr); + return self->func(reinterpret_cast<A1>(b1)); + } +}; +template<typename Ret, typename A1, typename A2, typename B1, typename B2> +struct pk_tmpln_2 { + using FuncType = std::function<Ret(A1, A2)>; + FuncType func; + static Ret invoke(void *ptr, B1 b1, B2 b2) { + auto *self = static_cast<pk_tmpln_2*>(ptr); + return self->func(reinterpret_cast<A1>(b1), reinterpret_cast<A2>(b2)); + } +}; +template<typename Ret, typename A1, typename A2, typename A3, typename B1, typename B2, typename B3> +struct pk_tmpln_3 { + using FuncType = std::function<Ret(A1, A2, A3)>; + FuncType func; + static Ret invoke(void *ptr, B1 b1, B2 b2, B3 b3) { + auto *self = static_cast<pk_tmpln_3*>(ptr); + return self->func(reinterpret_cast<A1>(b1), reinterpret_cast<A2>(b2), reinterpret_cast<A3>(b3)); + } +}; +#endif + +#endif /* PK_PKTMPLN_H */ |
