summaryrefslogtreecommitdiff
path: root/src/util/callback.h
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-03-16 10:57:36 +0100
committeraura <nw@moneybot.cc>2026-03-16 10:57:36 +0100
commitb71bb14c7dec546304e3396d7040d88c6c86a3a7 (patch)
treee1bee4e513b7df5647cbfacbe10cab4ebbc5cfc8 /src/util/callback.h
parentfdc5e8760fb7ac0af8e7ebb98a2076db15e31082 (diff)
decreaso allocs for fn class
Diffstat (limited to 'src/util/callback.h')
-rw-r--r--src/util/callback.h90
1 files changed, 43 insertions, 47 deletions
diff --git a/src/util/callback.h b/src/util/callback.h
index df93b59..a2c9477 100644
--- a/src/util/callback.h
+++ b/src/util/callback.h
@@ -3,86 +3,82 @@
template <typename T>
struct FN;
-
+// voodoo
template <typename RET, typename... ARGS>
struct FN<RET(ARGS...)> {
- // voodoo
template <typename T> struct __strip_ref { using type = T; };
template <typename T> struct __strip_ref<T&> { using type = T; };
template <typename T> struct __strip_ref<T&&> { using type = T; };
template <typename R, typename... A> struct __strip_ref<R(A...)> { using type = R(*)(A...); };
template <typename R, typename... A> struct __strip_ref<R(&)(A...)> { using type = R(*)(A...); };
+ static const unsigned int BUF_SIZE = 32;
+
+ alignas(8) char buf[BUF_SIZE];
void* data;
- U32 size;
RET( *invoke )( void*, ARGS... );
void( *destroy )( void* );
- void*( *clone )( void* );
+ void*( *clone )( void*, char* );
template <typename F>
- FN( F&& f ) {
+ FN(F&& f) {
using __stripped = typename __strip_ref<F>::type;
- data = new __stripped( static_cast<F&&>(f) );
- size = sizeof( __stripped );
+
+ if constexpr( sizeof(__stripped) <= BUF_SIZE ) {
+ new (buf) __stripped( f );
+ data = buf;
+ destroy = pfn( void* d ) {
+ ( (__stripped*)d )->~__stripped();
+ };
+ clone = pfn( void* d, char* dst ) -> void* {
+ new (dst) __stripped( *(__stripped*)d );
+ return dst;
+ };
+ } else {
+ data = new __stripped( f );
+ destroy = pfn( void* d ) {
+ delete (__stripped*)d;
+ };
+ clone = pfn( void* d, char* dst ) -> void* {
+ return new __stripped( *(__stripped*)d );
+ };
+ }
+
invoke = pfn( void* d, ARGS... args ) -> RET {
return ( *(__stripped*)d )( args... );
};
- destroy = pfn( void* d ) {
- delete (__stripped*)d;
- };
- clone = pfn( void* data ) {
- return (void*)new __stripped( *(__stripped*)data );
- };
- }
-
- template <>
- FN( int&& ) : data( 0 ), invoke( 0 ), destroy( 0 ) {}
- FN() : data( 0 ), invoke( 0 ), destroy( 0 ) {}
-
- FN( FN&& other ) : data( other.data ), invoke( other.invoke ), destroy( other.destroy ) {
- other.data = 0;
- other.invoke = 0;
- other.destroy = 0;
- }
-
- FN& operator=( FN&& other ) {
- if( this == &other ) return *this;
- if( destroy ) destroy( data );
- data = other.data;
- invoke = other.invoke;
- destroy = other.destroy;
- other.data = 0;
- other.invoke = 0;
- other.destroy = 0;
- return *this;
}
- FN( const FN& other ) {
- *this = other;
- };
+ FN( I32&& ) : data( 0 ), invoke( 0 ), destroy( 0 ), clone( 0 ) {}
+ FN( U32&& ) : data( 0 ), invoke( 0 ), destroy( 0 ), clone( 0 ) {}
+ FN() : data( 0 ), invoke( 0 ), destroy( 0 ), clone( 0 ) {}
- FN& operator=( const FN& other ) {
+ FN( const FN& other ) : invoke( other.invoke ), destroy( other.destroy ), clone( other.clone ) {
if( !other.data ) {
data = 0;
- invoke = 0;
- destroy = 0;
- size = 0;
- return *this;
+ return;
}
- size = other.size;
- data = other.clone( other.data );
+ data = other.clone( other.data, buf );
+ }
+
+ FN& operator=( const FN& other ) {
+ if( this == &other ) return *this;
+ if( destroy && data ) destroy( data );
invoke = other.invoke;
destroy = other.destroy;
clone = other.clone;
+ data = other.data ? other.clone( other.data, buf ) : 0;
return *this;
}
- ~FN() { if( destroy ) destroy( data ); }
- operator bool() const { return !!invoke; }
+ ~FN() {
+ if( destroy && data ) destroy( data );
+ }
RET operator()( ARGS... args ) const {
return invoke( data, args... );
}
+ operator bool() const { return !!invoke; }
};