-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: rxvt-unicode-sixel
action: commit
revision:
path_from:
revision_from: d2c3a6b3b5c4b2629b0a156d1a1cfac2e7158d09:
path_to:
revision_to:

git.thebackupbox.net

rxvt-unicode-sixel

git://git.thebackupbox.net/rxvt-unicode-sixel

commit d2c3a6b3b5c4b2629b0a156d1a1cfac2e7158d09
Author: Marc Lehmann <schmorp@schmorp.de>
Date:   Tue Dec 4 14:50:44 2007 +0000

    experimental new callbacks, totally standards compliant, faster, smaller

diff --git a/src/callback.h b/src/callback.h

index aa16f6ec81c70ad6b884787c9f6f514bb119a134..

index ..5a12ea48f9fd17907999e3fd9f1ac1c1f8b7d425 100644

--- a/src/callback.h
+++ b/src/callback.h
@@ -28,37 +28,50 @@

 #define CALLBACK_H_VERSION 3

-template<class signature>
-struct callback_funtype_trait;
+template<typename signature>
+struct callback;

-template<int arity, class signature>
-struct callback_get_impl;
+#define callback_set(callback,obj,klass,method) callback.set<klass, &klass::method> (obj)

 template<class R>
-class callback0
+struct callback<R ()>
 {
-  struct klass; // it is vital that this is never defined
+  typedef R (*ptr_type)(void *self);

-  typedef R (klass::*ptr_type)();
+private:

-  klass *o;
-  R (klass::*m)();
+  void *self;
+  ptr_type func;
+
+protected:
+
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)()>
+  static R thunk (void *self)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) ();
+  }

 public:
-  template<class O1, class O2>
-  explicit callback0 (O1 *object, R (O2::*method)())
+  template<class K, R (K::*method)()>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)()>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call() const
+  R call () const
   {
-    return (o->*m) ();
+    return func (self);
   }

   R operator ()() const
@@ -67,52 +80,45 @@ public:
   }
 };

-template<class R>
-struct callback_funtype_trait0
+template<class R, class A1>
+struct callback<R (A1)>
 {
-  static const int arity = 0;
-  typedef R type (void);
-  typedef R result_type;
-
-};
+  typedef R (*ptr_type)(void *self, A1);

-template<class R>
-struct callback_funtype_trait<R ()> : callback_funtype_trait0<R>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<0, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback0<typename T::result_type> type;
-};
-
-template<class R, class A1>
-class callback1
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;

-  typedef R (klass::*ptr_type)(A1);
+protected:

-  klass *o;
-  R (klass::*m)(A1);
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1)>
+  static R thunk (void *self, A1 a1)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback1 (O1 *object, R (O2::*method)(A1))
+  template<class K, R (K::*method)(A1)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1) const
+  R call (A1 a1) const
   {
-    return (o->*m) (a1);
+    return func (self, a1);
   }

   R operator ()(A1 a1) const
@@ -121,52 +127,45 @@ public:
   }
 };

-template<class R, class A1>
-struct callback_funtype_trait1
+template<class R, class A1, class A2>
+struct callback<R (A1, A2)>
 {
-  static const int arity = 1;
-  typedef R type (A1);
-  typedef R result_type;
-  typedef A1 arg1_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2);

-template<class R, class A1>
-struct callback_funtype_trait<R (A1)> : callback_funtype_trait1<R, A1>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<1, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback1<typename T::result_type, typename T::arg1_type> type;
-};
-
-template<class R, class A1, class A2>
-class callback2
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;
+
+protected:

-  typedef R (klass::*ptr_type)(A1, A2);
+  template<typename method>
+  struct thunktype;

-  klass *o;
-  R (klass::*m)(A1, A2);
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2)>
+  static R thunk (void *self, A1 a1, A2 a2)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback2 (O1 *object, R (O2::*method)(A1, A2))
+  template<class K, R (K::*method)(A1, A2)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2) const
+  R call (A1 a1, A2 a2) const
   {
-    return (o->*m) (a1, a2);
+    return func (self, a1, a2);
   }

   R operator ()(A1 a1, A2 a2) const
@@ -175,52 +174,45 @@ public:
   }
 };

-template<class R, class A1, class A2>
-struct callback_funtype_trait2
+template<class R, class A1, class A2, class A3>
+struct callback<R (A1, A2, A3)>
 {
-  static const int arity = 2;
-  typedef R type (A1, A2);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3);

-template<class R, class A1, class A2>
-struct callback_funtype_trait<R (A1, A2)> : callback_funtype_trait2<R, A1, A2>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<2, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback2<typename T::result_type, typename T::arg1_type, typename T::arg2_type> type;
-};
-
-template<class R, class A1, class A2, class A3>
-class callback3
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;

-  typedef R (klass::*ptr_type)(A1, A2, A3);
+protected:

-  klass *o;
-  R (klass::*m)(A1, A2, A3);
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2, A3)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback3 (O1 *object, R (O2::*method)(A1, A2, A3))
+  template<class K, R (K::*method)(A1, A2, A3)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3) const
+  R call (A1 a1, A2 a2, A3 a3) const
   {
-    return (o->*m) (a1, a2, a3);
+    return func (self, a1, a2, a3);
   }

   R operator ()(A1 a1, A2 a2, A3 a3) const
@@ -229,52 +221,45 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3>
-struct callback_funtype_trait3
+template<class R, class A1, class A2, class A3, class A4>
+struct callback<R (A1, A2, A3, A4)>
 {
-  static const int arity = 3;
-  typedef R type (A1, A2, A3);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3, A4);

-template<class R, class A1, class A2, class A3>
-struct callback_funtype_trait<R (A1, A2, A3)> : callback_funtype_trait3<R, A1, A2, A3>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<3, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback3<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4>
-class callback4
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;
+
+protected:

-  typedef R (klass::*ptr_type)(A1, A2, A3, A4);
+  template<typename method>
+  struct thunktype;

-  klass *o;
-  R (klass::*m)(A1, A2, A3, A4);
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2, A3, A4)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3, a4);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback4 (O1 *object, R (O2::*method)(A1, A2, A3, A4))
+  template<class K, R (K::*method)(A1, A2, A3, A4)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3, A4 a4) const
+  R call (A1 a1, A2 a2, A3 a3, A4 a4) const
   {
-    return (o->*m) (a1, a2, a3, a4);
+    return func (self, a1, a2, a3, a4);
   }

   R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) const
@@ -283,52 +268,45 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3, class A4>
-struct callback_funtype_trait4
+template<class R, class A1, class A2, class A3, class A4, class A5>
+struct callback<R (A1, A2, A3, A4, A5)>
 {
-  static const int arity = 4;
-  typedef R type (A1, A2, A3, A4);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5);

-template<class R, class A1, class A2, class A3, class A4>
-struct callback_funtype_trait<R (A1, A2, A3, A4)> : callback_funtype_trait4<R, A1, A2, A3, A4>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<4, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback4<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5>
-class callback5
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;

-  typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5);
+protected:

-  klass *o;
-  R (klass::*m)(A1, A2, A3, A4, A5);
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2, A3, A4, A5)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3, a4, a5);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback5 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5))
+  template<class K, R (K::*method)(A1, A2, A3, A4, A5)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+  R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
   {
-    return (o->*m) (a1, a2, a3, a4, a5);
+    return func (self, a1, a2, a3, a4, a5);
   }

   R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
@@ -337,52 +315,45 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3, class A4, class A5>
-struct callback_funtype_trait5
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
+struct callback<R (A1, A2, A3, A4, A5, A6)>
 {
-  static const int arity = 5;
-  typedef R type (A1, A2, A3, A4, A5);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6);

-template<class R, class A1, class A2, class A3, class A4, class A5>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5)> : callback_funtype_trait5<R, A1, A2, A3, A4, A5>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<5, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback5<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
-class callback6
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;

-  typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6);
+protected:

-  klass *o;
-  R (klass::*m)(A1, A2, A3, A4, A5, A6);
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3, a4, a5, a6);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback6 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6))
+  template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+  R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
   {
-    return (o->*m) (a1, a2, a3, a4, a5, a6);
+    return func (self, a1, a2, a3, a4, a5, a6);
   }

   R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
@@ -391,52 +362,45 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
-struct callback_funtype_trait6
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7)>
 {
-  static const int arity = 6;
-  typedef R type (A1, A2, A3, A4, A5, A6);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7);

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6)> : callback_funtype_trait6<R, A1, A2, A3, A4, A5, A6>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<6, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback6<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
-class callback7
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;

-  typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7);
+protected:

-  klass *o;
-  R (klass::*m)(A1, A2, A3, A4, A5, A6, A7);
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3, a4, a5, a6, a7);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback7 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7))
+  template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+  R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
   {
-    return (o->*m) (a1, a2, a3, a4, a5, a6, a7);
+    return func (self, a1, a2, a3, a4, a5, a6, a7);
   }

   R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
@@ -445,52 +409,45 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
-struct callback_funtype_trait7
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7, A8)>
 {
-  static const int arity = 7;
-  typedef R type (A1, A2, A3, A4, A5, A6, A7);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8);

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7)> : callback_funtype_trait7<R, A1, A2, A3, A4, A5, A6, A7>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<7, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback7<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
-class callback8
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;
+
+protected:

-  typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8);
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };

-  klass *o;
-  R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8);
+  template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7, A8)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback8 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8))
+  template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7, A8)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7, A8)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+  R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
   {
-    return (o->*m) (a1, a2, a3, a4, a5, a6, a7, a8);
+    return func (self, a1, a2, a3, a4, a5, a6, a7, a8);
   }

   R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
@@ -499,52 +456,45 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
-struct callback_funtype_trait8
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7, A8, A9)>
 {
-  static const int arity = 8;
-  typedef R type (A1, A2, A3, A4, A5, A6, A7, A8);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type; typedef A8 arg8_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8, A9);

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7, A8)> : callback_funtype_trait8<R, A1, A2, A3, A4, A5, A6, A7, A8>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<8, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback8<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type, typename T::arg8_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
-class callback9
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;
+
+protected:

-  typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
+  template<typename method>
+  struct thunktype;

-  klass *o;
-  R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback9 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9))
+  template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
+  R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
   {
-    return (o->*m) (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+    return func (self, a1, a2, a3, a4, a5, a6, a7, a8, a9);
   }

   R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
@@ -553,52 +503,45 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
-struct callback_funtype_trait9
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
 {
-  static const int arity = 9;
-  typedef R type (A1, A2, A3, A4, A5, A6, A7, A8, A9);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type; typedef A8 arg8_type; typedef A9 arg9_type;
-};
+  typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7, A8, A9)> : callback_funtype_trait9<R, A1, A2, A3, A4, A5, A6, A7, A8, A9>
-{
-};
+private:

-template<class signature>
-struct callback_get_impl<9, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback9<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type, typename T::arg8_type, typename T::arg9_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
-class callback10
-{
-  struct klass; // it is vital that this is never defined
+  void *self;
+  ptr_type func;

-  typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
+protected:

-  klass *o;
-  R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
+  template<typename method>
+  struct thunktype;
+
+  template<class klass>
+  struct thunktype<R (klass::*)>
+  {
+    typedef klass K;
+  };
+
+  template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
+  static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
+  {
+    klass *obj = static_cast<klass *>(self);
+    return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+  }

 public:
-  template<class O1, class O2>
-  explicit callback10 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10))
+  template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
+  void set (K *object)
   {
-    o = reinterpret_cast<klass *>(object);
-    m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>(method);
+    self = object;
+    func = thunk<K, method>;
   }

-  // this works because a standards-compliant C++ compiler
-  // basically can't help it: it doesn't have the knowledge
-  // required to miscompile (klass is not defined anywhere
-  // and nothing is known about the constructor arguments) :)
-  R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
+  R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
   {
-    return (o->*m) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+    return func (self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
   }

   R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
@@ -607,38 +550,5 @@ public:
   }
 };

-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
-struct callback_funtype_trait10
-{
-  static const int arity = 10;
-  typedef R type (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
-  typedef R result_type;
-  typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type; typedef A8 arg8_type; typedef A9 arg9_type; typedef A10 arg10_type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : callback_funtype_trait10<R, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>
-{
-};
-
-template<class signature>
-struct callback_get_impl<10, signature>
-{
-  typedef callback_funtype_trait<signature> T;
-  typedef callback10<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type, typename T::arg8_type, typename T::arg9_type, typename T::arg10_type> type;
-};
-
-
-template<class signature>
-struct callback : callback_get_impl<callback_funtype_trait<signature>::arity, signature>::type
-{
-  typedef typename callback_get_impl<callback_funtype_trait<signature>::arity, signature>::type base_type;
-
-  template<class O, class M>
-  explicit callback (O object, M method)
-  : base_type (object, method)
-  {
-  }
-};

 #endif
diff --git a/src/main.C b/src/main.C

index da09f9bccd563fd9e706ad7053c69570b9218094..

index ..0d4c6a7f5a50858d4eec45591ba13af198c2da49 100644

--- a/src/main.C
+++ b/src/main.C
@@ -155,15 +155,9 @@ int rxvt_composite_vec::expand (unicode_t c, wchar_t *r)

 rxvt_term::rxvt_term ()
     :
-#if ENABLE_TRANSPARENCY || ENABLE_PERL
-    rootwin_ev (this, &rxvt_term::rootwin_cb),
-#endif
 #if HAVE_BG_PIXMAP
     update_background_ev(this, &rxvt_term::update_background_cb),
 #endif
-#ifdef HAVE_SCROLLBARS
-    scrollbar_ev (this, &rxvt_term::x_cb),
-#endif
 #ifdef CURSOR_BLINK
     cursor_blink_ev (this, &rxvt_term::cursor_blink_cb),
 #endif
@@ -182,14 +176,9 @@ rxvt_term::rxvt_term ()
 #ifdef POINTER_BLANK
     pointer_ev (this, &rxvt_term::pointer_cb),
 #endif
-#ifdef USE_XIM
-    im_ev      (this, &rxvt_term::im_cb),
-#endif
 #ifndef NO_BELL
     bell_ev    (this, &rxvt_term::bell_cb),
 #endif
-    termwin_ev (this, &rxvt_term::x_cb),
-    vt_ev      (this, &rxvt_term::x_cb),
     child_ev   (this, &rxvt_term::child_cb),
     prepare_ev (this, &rxvt_term::prepare_cb),
     flush_ev   (this, &rxvt_term::flush_cb),
@@ -197,6 +186,18 @@ rxvt_term::rxvt_term ()
     pty_ev     (this, &rxvt_term::pty_cb),
     incr_ev    (this, &rxvt_term::incr_cb)
 {
+#if ENABLE_TRANSPARENCY || ENABLE_PERL
+  callback_set (rootwin_ev  , this, rxvt_term, rootwin_cb);
+#endif
+#ifdef HAVE_SCROLLBARS
+  callback_set (scrollbar_ev, this, rxvt_term, x_cb);
+#endif
+#ifdef USE_XIM
+  callback_set (im_ev       , this, rxvt_term, im_cb);
+#endif
+  callback_set (termwin_ev  , this, rxvt_term, x_cb);
+  callback_set (vt_ev       , this, rxvt_term, x_cb);
+
   cmdbuf_ptr = cmdbuf_endp = cmdbuf_base;

   termlist.push_back (this);
diff --git a/src/rxvtd.C b/src/rxvtd.C

index 8f9de8aa703c7f40daa69230ea1131cd2e881e2b..

index ..09c5d3890e453ff22026dc6b6a93a630d47db87c 100644

--- a/src/rxvtd.C
+++ b/src/rxvtd.C
@@ -48,10 +48,10 @@ struct server : rxvt_connection {
   int getfd (int remote_fd);

   server (int fd)
-  : read_ev (this, &server::read_cb),
-    log_cb (this, &server::log_msg),
-    getfd_cb (this, &server::getfd)
+  : read_ev (this, &server::read_cb)
   {
+    callback_set (log_cb  , this, server, log_msg);
+    callback_set (getfd_cb, this, server, getfd);
     this->fd = fd;
     fcntl (fd, F_SETFD, FD_CLOEXEC);
     fcntl (fd, F_SETFL, 0);
diff --git a/src/rxvttoolkit.h b/src/rxvttoolkit.h

index cec0d379555bb127fb26c2fd65a3ce85725737d7..

index ..e64a9da217003536b2c8225be197fa36034b5822 100644

--- a/src/rxvttoolkit.h
+++ b/src/rxvttoolkit.h
@@ -258,11 +258,6 @@ struct rxvt_display : refcounted {

 #ifdef USE_XIM
 struct im_watcher : rxvt_watcher, callback<void (void)> {
-  template<class O, class M>
-  im_watcher (O object, M method)
-  : callback<void (void)> (object, method)
-  { }
-
   void start (rxvt_display *display)
   {
     display->reg (this);
@@ -278,11 +273,6 @@ struct im_watcher : rxvt_watcher, callback<void (void)> {
 struct xevent_watcher : rxvt_watcher, callback<void (XEvent &)> {
   Window window;

-  template<class O, class M>
-  xevent_watcher (O object, M method)
-  : callback<void (XEvent &)> (object, method)
-  { }
-
   void start (rxvt_display *display, Window window)
   {
     this->window = window;

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 10:35:21 2024