summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordyknon dyknonr5fjp2026-09-07 23:28:33 +0900
committerdyknon dyknonr5fjp2026-09-07 23:28:33 +0900
commitd98e139d08d2d24426d75384f8789ccc7279bca4 (patch)
treebfe266bd0b382d4145f6a8aa97f9a6848d4b8bd3
parentd13659b841cf8327ed94f9dc282d905008abc94b (diff)
thinfunc
-rw-r--r--thinfunc-example.cc86
-rw-r--r--thinfunc.h87
2 files changed, 173 insertions, 0 deletions
diff --git a/thinfunc-example.cc b/thinfunc-example.cc
new file mode 100644
index 0000000..1cf12d6
--- /dev/null
+++ b/thinfunc-example.cc
@@ -0,0 +1,86 @@
+/* Heap-allocation free & small memory footprint
+ * std::function alternative with limited capabilities.
+ */ // example
+
+/* Copyright (c) 2026 dyknon
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the " Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice
+ * (including the next paragraph) shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "thinfunc.h"
+
+#include <print>
+#include <string>
+#include <ctime>
+
+using namespace tf;
+
+struct test{
+ std::string name;
+ test(std::string name): name(name){}
+
+ anchor<test, void()> m1;
+ func<void()>& get_m1(){
+ return m1.bind<&test::m1, &test::message1>();
+ }
+ anchor<test, void(std::string)> m2;
+ func<void(std::string)>& get_m2(){
+ return m2.bind<&test::m2, &test::message2>();
+ }
+ anchor<test, std::string()> t;
+ func<std::string()>& get_t(){
+ return t.bind<&test::t, &test::time>();
+ }
+
+ void message1(){
+ std::println("hello! I'm {}.", name);
+ }
+ void message2(std::string time){
+ std::println("Good {}! I'm {}.", time, name);
+ }
+ std::string time(){
+ auto t = std::time(nullptr);
+ t /= 60 * 60;
+ t %= 24;
+ if(t < 5){
+ return "night";
+ }else if(t < 12){
+ return "morning";
+ }else if(t < 18){
+ return "afternoon";
+ }else if(t < 20){
+ return "evening";
+ }else{
+ return "night";
+ }
+ }
+};
+
+int main(){
+ test o("a test object");
+ func<void()>& m1 = o.get_m1();
+ func<void(std::string)>& m2 = o.get_m2();
+ o.get_t();
+ func<std::string()>& t = o.t.assume_bound<&test::t, &test::time>();
+
+ m1();
+ m2(t());
+
+ return 0;
+}
diff --git a/thinfunc.h b/thinfunc.h
new file mode 100644
index 0000000..c75c33a
--- /dev/null
+++ b/thinfunc.h
@@ -0,0 +1,87 @@
+/* Heap-allocation free & small memory footprint
+ * std::function alternative with limited capabilities.
+ */ // single-header library
+
+/* Copyright (c) 2026 dyknon
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the " Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice
+ * (including the next paragraph) shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef INC_THINFUNC_H
+#define INC_THINFUNC_H
+
+namespace tf{
+
+template<class F>
+struct func;
+template<class R, class... Args>
+struct func<R(Args...)>{
+ virtual R operator()(Args...) = 0;
+};
+
+template<class T, class F>
+class anchor;
+template<class T, class AT, class MT, AT AV, MT MV>
+class bound_anchor;
+
+template<class T, class R, class... Args>
+class anchor<T, R(Args...)>{
+public:
+ template<anchor<T, R(Args...)> (T::*Self), R (T::*Method)(Args...)>
+ using bound_type = bound_anchor<T,
+ anchor<T, R(Args...)> (T::*), R (T::*)(Args...), Self, Method>;
+private:
+ alignas(bound_type<nullptr, nullptr>)
+ char body[sizeof(bound_type<nullptr, nullptr>)];
+public:
+ template<anchor<T, R(Args...)> (T::*Self), R (T::*Method)(Args...)>
+ auto& bind(){
+ return *(new (this->body) bound_type<Self, Method>());
+ }
+ template<anchor<T, R(Args...)> (T::*Self), R (T::*Method)(Args...)>
+ auto& assume_bound() const{
+ return *(bound_type<Self, Method> *)this->body;
+ }
+};
+
+template<
+ class T, class R, class... Args,
+ anchor<T, R(Args...)> (T::*Self), R (T::*Method)(Args...)
+>
+class bound_anchor<T,
+ anchor<T, R(Args...)> (T::*), R (T::*)(Args...),
+ Self, Method
+ >: public func<R(Args...)>{
+public:
+ bound_anchor(){}
+ bound_anchor(const bound_anchor&) = delete;
+ bound_anchor(const bound_anchor&&) = delete;
+ bound_anchor& operator=(const bound_anchor&) = delete;
+ bound_anchor& operator=(const bound_anchor&&) = delete;
+ virtual R operator()(Args... args){
+ auto offset = (char *)&(((T *)0)->*Self) - (char *)0;
+ T *container = (T *)((char *)this - offset);
+ return (container->*Method)(args...);
+ }
+};
+
+} // namespace rf
+
+#endif //INC_THINFUNC_H