fix bug 24
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 24 May 2007 16:08:03 +0200
changeset 690 48cf425136d6
parent 689 49bccd847179
child 691 44b24b908750
fix bug 24
src/core/ptr.h
src/simulator/simulator.cc
src/simulator/simulator.h
--- a/src/core/ptr.h	Thu May 24 15:37:00 2007 +0200
+++ b/src/core/ptr.h	Thu May 24 16:08:03 2007 +0200
@@ -183,6 +183,17 @@
   }
 };
 
+template <typename T>
+struct EventMemberImplTraits;
+
+template <typename T>
+struct EventMemberImplTraits<Ptr<T> >
+{
+  static T &GetReference (Ptr<T> p) {
+    return *PeekPointer (p);
+  }
+};
+
 
 
 } // namespace ns3
--- a/src/simulator/simulator.cc	Thu May 24 15:37:00 2007 +0200
+++ b/src/simulator/simulator.cc	Thu May 24 16:08:03 2007 +0200
@@ -454,6 +454,7 @@
 #ifdef RUN_SELF_TESTS
 
 #include "ns3/test.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -474,6 +475,9 @@
 class SimulatorTests : public Test {
 public:
   SimulatorTests ();
+  // only here for testing of Ptr<>
+  void Ref (void);
+  void Unref (void);
   virtual ~SimulatorTests ();
   virtual bool RunTests (void);
 private:
@@ -502,6 +506,12 @@
 {}
 SimulatorTests::~SimulatorTests ()
 {}
+void 
+SimulatorTests::Ref (void)
+{}
+void 
+SimulatorTests::Unref (void)
+{}
 uint64_t
 SimulatorTests::NowUs (void)
 {
@@ -634,6 +644,12 @@
   Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar3, this, 0, 0, 0);
   Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar4, this, 0, 0, 0, 0);
   Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar5, this, 0, 0, 0, 0, 0);
+  Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar0, Ptr<SimulatorTests> (this));
+  Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar1, Ptr<SimulatorTests> (this), 0);
+  Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar2, Ptr<SimulatorTests> (this), 0, 0);
+  Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar3, Ptr<SimulatorTests> (this), 0, 0, 0);
+  Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar4, Ptr<SimulatorTests> (this), 0, 0, 0, 0);
+  Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar5, Ptr<SimulatorTests> (this), 0, 0, 0, 0, 0);
   Simulator::ScheduleNow (&foo0);
   Simulator::ScheduleNow (&foo1, 0);
   Simulator::ScheduleNow (&foo2, 0, 0);
@@ -646,6 +662,12 @@
   Simulator::ScheduleNow (&SimulatorTests::bar3, this, 0, 0, 0);
   Simulator::ScheduleNow (&SimulatorTests::bar4, this, 0, 0, 0, 0);
   Simulator::ScheduleNow (&SimulatorTests::bar5, this, 0, 0, 0, 0, 0);
+  Simulator::ScheduleNow (&SimulatorTests::bar0, Ptr<SimulatorTests> (this));
+  Simulator::ScheduleNow (&SimulatorTests::bar1, Ptr<SimulatorTests> (this), 0);
+  Simulator::ScheduleNow (&SimulatorTests::bar2, Ptr<SimulatorTests> (this), 0, 0);
+  Simulator::ScheduleNow (&SimulatorTests::bar3, Ptr<SimulatorTests> (this), 0, 0, 0);
+  Simulator::ScheduleNow (&SimulatorTests::bar4, Ptr<SimulatorTests> (this), 0, 0, 0, 0);
+  Simulator::ScheduleNow (&SimulatorTests::bar5, Ptr<SimulatorTests> (this), 0, 0, 0, 0, 0);
   Simulator::ScheduleDestroy (&foo0);
   Simulator::ScheduleDestroy (&foo1, 0);
   Simulator::ScheduleDestroy (&foo2, 0, 0);
@@ -658,6 +680,12 @@
   Simulator::ScheduleDestroy (&SimulatorTests::bar3, this, 0, 0, 0);
   Simulator::ScheduleDestroy (&SimulatorTests::bar4, this, 0, 0, 0, 0);
   Simulator::ScheduleDestroy (&SimulatorTests::bar5, this, 0, 0, 0, 0, 0);
+  Simulator::ScheduleDestroy (&SimulatorTests::bar0, Ptr<SimulatorTests> (this));
+  Simulator::ScheduleDestroy (&SimulatorTests::bar1, Ptr<SimulatorTests> (this), 0);
+  Simulator::ScheduleDestroy (&SimulatorTests::bar2, Ptr<SimulatorTests> (this), 0, 0);
+  Simulator::ScheduleDestroy (&SimulatorTests::bar3, Ptr<SimulatorTests> (this), 0, 0, 0);
+  Simulator::ScheduleDestroy (&SimulatorTests::bar4, Ptr<SimulatorTests> (this), 0, 0, 0, 0);
+  Simulator::ScheduleDestroy (&SimulatorTests::bar5, Ptr<SimulatorTests> (this), 0, 0, 0, 0, 0);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/src/simulator/simulator.h	Thu May 24 15:37:00 2007 +0200
+++ b/src/simulator/simulator.h	Thu May 24 16:08:03 2007 +0200
@@ -162,8 +162,8 @@
    * @param obj the object on which to invoke the member method
    * @returns an id for the scheduled event.
    */
-  template <typename T>
-  static EventId Schedule (Time const &time, void (T::*mem_ptr) (void), T *obj);
+  template <typename T, typename OBJ>
+  static EventId Schedule (Time const &time, void (T::*mem_ptr) (void), OBJ obj);
   /**
    * @param time the relative expiration time of the event.
    * @param mem_ptr member method pointer to invoke
@@ -171,8 +171,8 @@
    * @param a1 the first argument to pass to the invoked method
    * @returns an id for the scheduled event.
    */
-  template <typename T, typename T1>
-  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1), T* obj, T1 a1);
+  template <typename T, typename OBJ, typename T1>
+  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1), OBJ obj, T1 a1);
   /**
    * @param time the relative expiration time of the event.
    * @param mem_ptr member method pointer to invoke
@@ -181,8 +181,8 @@
    * @param a2 the second argument to pass to the invoked method
    * @returns an id for the scheduled event.
    */
-  template <typename T, typename T1, typename T2>
-  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2);
+  template <typename T, typename OBJ, typename T1, typename T2>
+  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2);
   /**
    * @param time the relative expiration time of the event.
    * @param mem_ptr member method pointer to invoke
@@ -192,8 +192,8 @@
    * @param a3 the third argument to pass to the invoked method
    * @returns an id for the scheduled event.
    */
-  template <typename T, typename T1, typename T2, typename T3>
-  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3>
+  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3);
   /**
    * @param time the relative expiration time of the event.
    * @param mem_ptr member method pointer to invoke
@@ -204,8 +204,8 @@
    * @param a4 the fourth argument to pass to the invoked method
    * @returns an id for the scheduled event.
    */
-  template <typename T, typename T1, typename T2, typename T3, typename T4>
-  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, T1 a1, T2 a2, T3 a3, T4 a4);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
+  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
   /**
    * @param time the relative expiration time of the event.
    * @param mem_ptr member method pointer to invoke
@@ -217,9 +217,9 @@
    * @param a5 the fifth argument to pass to the invoked method
    * @returns an id for the scheduled event.
    */
-  template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
-  						 T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
+  static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
+                           T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
   /**
    * @param time the relative expiration time of the event.
    * @param f the function to invoke
@@ -286,23 +286,23 @@
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
    */
-  template <typename T>
-  static void ScheduleNow (void (T::*mem_ptr) (void), T *obj);
+  template <typename T, typename OBJ>
+  static void ScheduleNow (void (T::*mem_ptr) (void), OBJ obj);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
    * @param a1 the first argument to pass to the invoked method
    */
-  template <typename T, typename T1>
-  static void ScheduleNow (void (T::*mem_ptr) (T1), T* obj, T1 a1);
+  template <typename T, typename OBJ, typename T1>
+  static void ScheduleNow (void (T::*mem_ptr) (T1), OBJ obj, T1 a1);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
    * @param a1 the first argument to pass to the invoked method
    * @param a2 the second argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2>
-  static void ScheduleNow (void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2);
+  template <typename T, typename OBJ, typename T1, typename T2>
+  static void ScheduleNow (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -310,8 +310,8 @@
    * @param a2 the second argument to pass to the invoked method
    * @param a3 the third argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2, typename T3>
-  static void ScheduleNow (void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3>
+  static void ScheduleNow (void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -320,8 +320,8 @@
    * @param a3 the third argument to pass to the invoked method
    * @param a4 the fourth argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2, typename T3, typename T4>
-  static void ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, 
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
+  static void ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, 
                            T1 a1, T2 a2, T3 a3, T4 a4);
   /**
    * @param mem_ptr member method pointer to invoke
@@ -332,8 +332,8 @@
    * @param a4 the fourth argument to pass to the invoked method
    * @param a5 the fifth argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-  static void ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
+  static void ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
                            T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
   /**
    * @param f the function to invoke
@@ -390,23 +390,23 @@
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
    */
-  template <typename T>
-  static void ScheduleDestroy (void (T::*mem_ptr) (void), T *obj);
+  template <typename T, typename OBJ>
+  static void ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
    * @param a1 the first argument to pass to the invoked method
    */
-  template <typename T, typename T1>
-  static void ScheduleDestroy (void (T::*mem_ptr) (T1), T* obj, T1 a1);
+  template <typename T, typename OBJ, typename T1>
+  static void ScheduleDestroy (void (T::*mem_ptr) (T1), OBJ obj, T1 a1);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
    * @param a1 the first argument to pass to the invoked method
    * @param a2 the second argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2>
-  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2);
+  template <typename T, typename OBJ, typename T1, typename T2>
+  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -414,8 +414,8 @@
    * @param a2 the second argument to pass to the invoked method
    * @param a3 the third argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2, typename T3>
-  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3>
+  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -424,9 +424,9 @@
    * @param a3 the third argument to pass to the invoked method
    * @param a4 the fourth argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2, typename T3, typename T4>
-  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, 
-                           T1 a1, T2 a2, T3 a3, T4 a4);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
+  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, 
+                               T1 a1, T2 a2, T3 a3, T4 a4);
   /**
    * @param mem_ptr member method pointer to invoke
    * @param obj the object on which to invoke the member method
@@ -436,9 +436,9 @@
    * @param a4 the fourth argument to pass to the invoked method
    * @param a5 the fifth argument to pass to the invoked method
    */
-  template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
-                           T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
+  static void ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
+                               T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
   /**
    * @param f the function to invoke
    */
@@ -529,19 +529,19 @@
 private:
   Simulator ();
   ~Simulator ();
-  template <typename T>
-  static EventImpl *MakeEvent (void (T::*mem_ptr) (void), T *obj);
-  template <typename T, typename T1>
-  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1), T* obj, T1 a1);
-  template <typename T, typename T1, typename T2>
-  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2);
-  template <typename T, typename T1, typename T2, typename T3>
-  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3);
-  template <typename T, typename T1, typename T2, typename T3, typename T4>
-  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, T1 a1, T2 a2, T3 a3, T4 a4);
-  template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
-                        T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+  template <typename T, typename OBJ>
+  static EventImpl *MakeEvent (void (T::*mem_ptr) (void), OBJ obj);
+  template <typename T, typename OBJ, typename T1>
+  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1), OBJ obj, T1 a1);
+  template <typename T, typename OBJ, typename T1, typename T2>
+  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3>
+  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
+  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
+  template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
+  static EventImpl *MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
+                               T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
   static EventImpl *MakeEvent (void (*f) (void));
   template <typename T1>
   static EventImpl *MakeEvent (void (*f) (T1), T1 a1);
@@ -584,174 +584,185 @@
 namespace ns3 {
 
 template <typename T>
-EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (void), T *obj) 
+struct EventMemberImplTraits;
+
+template <typename T>
+struct EventMemberImplTraits<T *>
+{
+  static T &GetReference (T *p) {
+    return *p;
+  }
+};
+
+template <typename T, typename OBJ>
+EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (void), OBJ obj) 
 {
   // zero argument version
   class EventMemberImpl0 : public EventImpl {
   public:
-  	typedef void (T::*F)(void);
-  	EventMemberImpl0 (T *obj, F function) 
-  		: m_obj (obj), 
-  		  m_function (function)
-  	{}
-  	virtual ~EventMemberImpl0 () {}
+    typedef void (T::*F)(void);
+    EventMemberImpl0 (OBJ obj, F function) 
+      : m_obj (obj), 
+        m_function (function)
+    {}
+    virtual ~EventMemberImpl0 () {}
   private:
-  	virtual void Notify (void) { 
-  		(m_obj->*m_function) (); 
-  	}
-  	T* m_obj;
-  	F m_function;
+    virtual void Notify (void) { 
+      (EventMemberImplTraits<OBJ>::GetReference (m_obj).*m_function) (); 
+    }
+    OBJ m_obj;
+    F m_function;
   } *ev = new EventMemberImpl0 (obj, mem_ptr);
   return ev;
 }
 
 
-template <typename T, typename T1>
-EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1), T* obj, T1 a1) 
+template <typename T, typename OBJ, typename T1>
+EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1), OBJ obj, T1 a1) 
 {
   // one argument version
   class EventMemberImpl1 : public EventImpl {
   public:
-  	typedef void (T::*F)(T1);
-  	EventMemberImpl1 (T *obj, F function, T1 a1) 
-  		: m_obj (obj), 
-  		  m_function (function),
-  		  m_a1 (a1)
-  	{}
+    typedef void (T::*F)(T1);
+    EventMemberImpl1 (OBJ obj, F function, T1 a1) 
+      : m_obj (obj), 
+        m_function (function),
+        m_a1 (a1)
+    {}
   protected:
-  	virtual ~EventMemberImpl1 () {}
+    virtual ~EventMemberImpl1 () {}
   private:
-  	virtual void Notify (void) { 
-  		(m_obj->*m_function) (m_a1);
-  	}
-  	T* m_obj;
-  	F m_function;
-  	T1 m_a1;
+    virtual void Notify (void) { 
+      (EventMemberImplTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1);
+    }
+    OBJ m_obj;
+    F m_function;
+    T1 m_a1;
   } *ev = new EventMemberImpl1 (obj, mem_ptr, a1);
   return ev;
 }
 
-template <typename T, typename T1, typename T2>
-EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2) 
+template <typename T, typename OBJ, typename T1, typename T2>
+EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2) 
 {
   // two argument version
   class EventMemberImpl2 : public EventImpl {
   public:
-  	typedef void (T::*F)(T1, T2);
+    typedef void (T::*F)(T1, T2);
       
-  	EventMemberImpl2 (T *obj, F function, T1 a1, T2 a2) 
-  		: m_obj (obj), 
-  		  m_function (function),
-  		  m_a1 (a1),
-  		  m_a2 (a2)
-  	{ }
+    EventMemberImpl2 (OBJ obj, F function, T1 a1, T2 a2) 
+      : m_obj (obj), 
+        m_function (function),
+        m_a1 (a1),
+        m_a2 (a2)
+    { }
   protected:
-  	virtual ~EventMemberImpl2 () {}
+    virtual ~EventMemberImpl2 () {}
   private:
-  	virtual void Notify (void) { 
-  		(m_obj->*m_function) (m_a1, m_a2);
-  	}
-  	T* m_obj;
-  	F m_function;
-  	T1 m_a1;
-  	T2 m_a2;
+    virtual void Notify (void) { 
+      (EventMemberImplTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2);
+    }
+    OBJ m_obj;
+    F m_function;
+    T1 m_a1;
+    T2 m_a2;
   } *ev = new EventMemberImpl2 (obj, mem_ptr, a1, a2);
   return ev;
 }
 
-template <typename T, typename T1, typename T2, typename T3>
-EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3) 
+template <typename T, typename OBJ, typename T1, typename T2, typename T3>
+EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3) 
 {
   // three argument version
   class EventMemberImpl3 : public EventImpl {
   public:
-  	typedef void (T::*F)(T1, T2, T3);
+    typedef void (T::*F)(T1, T2, T3);
       
-  	EventMemberImpl3 (T *obj, F function, T1 a1, T2 a2, T3 a3) 
-  		: m_obj (obj), 
-  		  m_function (function),
-  		  m_a1 (a1),
-  		  m_a2 (a2),
-  		  m_a3 (a3)
-  	{ }
+    EventMemberImpl3 (OBJ obj, F function, T1 a1, T2 a2, T3 a3) 
+      : m_obj (obj), 
+        m_function (function),
+        m_a1 (a1),
+        m_a2 (a2),
+        m_a3 (a3)
+    { }
   protected:
-  	virtual ~EventMemberImpl3 () {}
+    virtual ~EventMemberImpl3 () {}
   private:
-  	virtual void Notify (void) { 
-  		(m_obj->*m_function) (m_a1, m_a2, m_a3);
-  	}
-  	T* m_obj;
-  	F m_function;
-  	T1 m_a1;
-  	T2 m_a2;
-  	T3 m_a3;
+    virtual void Notify (void) { 
+      (EventMemberImplTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3);
+    }
+    OBJ m_obj;
+    F m_function;
+    T1 m_a1;
+    T2 m_a2;
+    T3 m_a3;
   } *ev = new EventMemberImpl3 (obj, mem_ptr, a1, a2, a3);
   return ev;
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4>
-EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, T1 a1, T2 a2, T3 a3, T4 a4) 
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
+EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) 
 {
   // four argument version
   class EventMemberImpl4 : public EventImpl {
   public:
-  	typedef void (T::*F)(T1, T2, T3, T4);
+    typedef void (T::*F)(T1, T2, T3, T4);
           
-  	EventMemberImpl4 (T *obj, F function, T1 a1, T2 a2, T3 a3, T4 a4) 
-  		: m_obj (obj), 
-  		  m_function (function),
-  		  m_a1 (a1),
-  		  m_a2 (a2),
-  		  m_a3 (a3),
-  		  m_a4 (a4)
-  	{ }
+    EventMemberImpl4 (OBJ obj, F function, T1 a1, T2 a2, T3 a3, T4 a4) 
+      : m_obj (obj), 
+        m_function (function),
+        m_a1 (a1),
+        m_a2 (a2),
+        m_a3 (a3),
+        m_a4 (a4)
+    { }
   protected:
-  	virtual ~EventMemberImpl4 () {}
+    virtual ~EventMemberImpl4 () {}
   private:
-  	virtual void Notify (void) { 
-  		(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4);
-  	}
-  	T* m_obj;
-  	F m_function;
-  	T1 m_a1;
-  	T2 m_a2;
-  	T3 m_a3;
-  	T4 m_a4;
+    virtual void Notify (void) { 
+      (EventMemberImplTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4);
+    }
+    OBJ m_obj;
+    F m_function;
+    T1 m_a1;
+    T2 m_a2;
+    T3 m_a3;
+    T4 m_a4;
   } *ev = new EventMemberImpl4 (obj, mem_ptr, a1, a2, a3, a4);
   return ev;
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
-  						 T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
+EventImpl *Simulator::MakeEvent (void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
+                                 T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
   // five argument version
   class EventMemberImpl5 : public EventImpl {
   public:
-  	typedef void (T::*F)(T1, T2, T3, T4, T5);
+    typedef void (T::*F)(T1, T2, T3, T4, T5);
       
-  	EventMemberImpl5 (T *obj, F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
-  		: m_obj (obj), 
-  		  m_function (function),
-  		  m_a1 (a1),
-  		  m_a2 (a2),
-  		  m_a3 (a3),
-  		  m_a4 (a4),
-  		  m_a5 (a5)
-  	{ }
+    EventMemberImpl5 (OBJ obj, F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
+      : m_obj (obj), 
+        m_function (function),
+        m_a1 (a1),
+        m_a2 (a2),
+        m_a3 (a3),
+        m_a4 (a4),
+        m_a5 (a5)
+    { }
   protected:
-  	virtual ~EventMemberImpl5 () {}
+    virtual ~EventMemberImpl5 () {}
   private:
-  	virtual void Notify (void) { 
-  		(m_obj->*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
-  	}
-  	T* m_obj;
-  	F m_function;
-  	T1 m_a1;
-  	T2 m_a2;
-  	T3 m_a3;
-  	T4 m_a4;
-  	T5 m_a5;
+    virtual void Notify (void) { 
+      (EventMemberImplTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
+    }
+    OBJ m_obj;
+    F m_function;
+    T1 m_a1;
+    T2 m_a2;
+    T3 m_a3;
+    T4 m_a4;
+    T5 m_a5;
   } *ev = new EventMemberImpl5 (obj, mem_ptr, a1, a2, a3, a4, a5);
   return ev;
 }
@@ -896,39 +907,39 @@
   return ev; 
 }
 
-template <typename T>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (void), T *obj) 
+template <typename T, typename OBJ>
+EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (void), OBJ obj) 
 {
   return Schedule (time, MakeEvent (mem_ptr, obj));
 }
 
 
-template <typename T, typename T1>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1), T* obj, T1 a1) 
+template <typename T, typename OBJ, typename T1>
+EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1), OBJ obj, T1 a1) 
 {
   return Schedule (time, MakeEvent (mem_ptr, obj, a1));
 }
 
-template <typename T, typename T1, typename T2>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2) 
+template <typename T, typename OBJ, typename T1, typename T2>
+EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2) 
 {
   return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2));
 }
 
-template <typename T, typename T1, typename T2, typename T3>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3) 
+template <typename T, typename OBJ, typename T1, typename T2, typename T3>
+EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3) 
 {
   return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3));
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, T1 a1, T2 a2, T3 a3, T4 a4) 
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
+EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) 
 {
   return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
+EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
   						 T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
   return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
@@ -967,46 +978,46 @@
 
 
 
-template <typename T>
+template <typename T, typename OBJ>
 void
-Simulator::ScheduleNow (void (T::*mem_ptr) (void), T *obj) 
+Simulator::ScheduleNow (void (T::*mem_ptr) (void), OBJ obj) 
 {
   ScheduleNow (MakeEvent (mem_ptr, obj));
 }
 
 
-template <typename T, typename T1>
+template <typename T, typename OBJ, typename T1>
 void
-Simulator::ScheduleNow (void (T::*mem_ptr) (T1), T* obj, T1 a1) 
+Simulator::ScheduleNow (void (T::*mem_ptr) (T1), OBJ obj, T1 a1) 
 {
   ScheduleNow (MakeEvent (mem_ptr, obj, a1));
 }
 
-template <typename T, typename T1, typename T2>
+template <typename T, typename OBJ, typename T1, typename T2>
 void
-Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2) 
+Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2) 
 {
   ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2));
 }
 
-template <typename T, typename T1, typename T2, typename T3>
+template <typename T, typename OBJ, typename T1, typename T2, typename T3>
 void
-Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3) 
+Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3) 
 {
   ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3));
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4>
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
 void
-Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, T1 a1, T2 a2, T3 a3, T4 a4) 
+Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) 
 {
   ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
 void
-Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
-  						 T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
+Simulator::ScheduleNow (void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
+                        T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
   ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
 }
@@ -1048,46 +1059,46 @@
 
 
 
-template <typename T>
+template <typename T, typename OBJ>
 void
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (void), T *obj) 
+Simulator::ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj) 
 {
   ScheduleDestroy (MakeEvent (mem_ptr, obj));
 }
 
 
-template <typename T, typename T1>
+template <typename T, typename OBJ, typename T1>
 void
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1), T* obj, T1 a1) 
+Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1), OBJ obj, T1 a1) 
 {
   ScheduleDestroy (MakeEvent (mem_ptr, obj, a1));
 }
 
-template <typename T, typename T1, typename T2>
+template <typename T, typename OBJ, typename T1, typename T2>
 void
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2) 
+Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2), OBJ obj, T1 a1, T2 a2) 
 {
   ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2));
 }
 
-template <typename T, typename T1, typename T2, typename T3>
+template <typename T, typename OBJ, typename T1, typename T2, typename T3>
 void
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3) 
+Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3), OBJ obj, T1 a1, T2 a2, T3 a3) 
 {
   ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3));
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4>
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4>
 void
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, T1 a1, T2 a2, T3 a3, T4 a4) 
+Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4) 
 {
   ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
 }
 
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+template <typename T, typename OBJ, typename T1, typename T2, typename T3, typename T4, typename T5>
 void
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj, 
-  						 T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
+Simulator::ScheduleDestroy (void (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ obj, 
+                            T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) 
 {
   ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
 }