summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-05-28 12:46:51 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-05-28 12:46:51 -0400
commit3612806d5ea470f5dd2fb5a6e7f5be9de716a67e (patch)
tree2f41f52b40059bf05013f30194201934c446864a
parentb9f23559d8bc36356ea0b6264c91d82dba3fb74d (diff)
pktmpln: first-pass, adds _1, _2, and _3
-rw-r--r--Makefile6
-rw-r--r--pk.h.in21
-rw-r--r--pktmpln.h35
3 files changed, 62 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index dc403d6..b0a59c2 100644
--- a/Makefile
+++ b/Makefile
@@ -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"
diff --git a/pk.h.in b/pk.h.in
index 5142c76..d255320 100644
--- a/pk.h.in
+++ b/pk.h.in
@@ -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 */