diff --git a/src/core/callback.h b/src/core/callback.h index 9904a9818..eb5d9b44b 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -58,6 +58,18 @@ namespace ns3 { */ class empty {}; +template +struct CallbackTraits; + +template +struct CallbackTraits +{ + static T & GetReference (T * const p) + { + return *p; + } +}; + class CallbackImplBase { public: virtual ~CallbackImplBase () {} @@ -161,22 +173,22 @@ public: : m_objPtr (objPtr), m_memPtr (mem_ptr) {} virtual ~MemPtrCallbackImpl () {} R operator() (void) { - return ((*m_objPtr).*m_memPtr) (); + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr) (); } R operator() (T1 a1) { - return ((*m_objPtr).*m_memPtr) (a1); + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr) (a1); } R operator() (T1 a1,T2 a2) { - return ((*m_objPtr).*m_memPtr) (a1,a2); + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr) (a1, a2); } R operator() (T1 a1,T2 a2,T3 a3) { - return ((*m_objPtr).*m_memPtr) (a1,a2,a3); + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3); } R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { - return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4); + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4); } R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { - return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4,a5); + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5); } virtual bool IsEqual (CallbackImplBase const *other) const { MemPtrCallbackImpl const *otherDerived = @@ -323,12 +335,12 @@ private: * Build Callbacks for class method members which takes no arguments * and potentially return a value. */ -template -Callback MakeCallback (R (OBJ::*mem_ptr) (), OBJ *const objPtr) { - return Callback (objPtr, mem_ptr); +template +Callback MakeCallback (R (T::*memPtr) (void), OBJ objPtr) { + return Callback (objPtr, memPtr); } -template -Callback MakeCallback (R (OBJ::*mem_ptr) () const, OBJ const *const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) () const, OBJ const objPtr) { return Callback (objPtr, mem_ptr); } /** @@ -339,12 +351,12 @@ Callback MakeCallback (R (OBJ::*mem_ptr) () const, OBJ const *const objPtr) { * Build Callbacks for class method members which takes one argument * and potentially return a value. */ -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1), OBJ *const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1), OBJ *const objPtr) { return Callback (objPtr, mem_ptr); } -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1) const, OBJ const *const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1) const, OBJ const *const objPtr) { return Callback (objPtr, mem_ptr); } /** @@ -355,12 +367,12 @@ Callback MakeCallback (R (OBJ::*mem_ptr) (T1) const, OBJ const *const objP * Build Callbacks for class method members which takes two arguments * and potentially return a value. */ -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2), OBJ *const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2), OBJ *const objPtr) { return Callback (objPtr, mem_ptr); } -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2) const, OBJ const*const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2) const, OBJ const*const objPtr) { return Callback (objPtr, mem_ptr); } /** @@ -371,12 +383,12 @@ Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2) const, OBJ const*const * Build Callbacks for class method members which takes three arguments * and potentially return a value. */ -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3), OBJ *const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2,T3), OBJ *const objPtr) { return Callback (objPtr, mem_ptr); } -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3) const, OBJ const*const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2,T3) const, OBJ const*const objPtr) { return Callback (objPtr, mem_ptr); } /** @@ -387,12 +399,12 @@ Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3) const, OBJ const * Build Callbacks for class method members which takes four arguments * and potentially return a value. */ -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4), OBJ *const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4), OBJ *const objPtr) { return Callback (objPtr, mem_ptr); } -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4) const, OBJ const*const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4) const, OBJ const*const objPtr) { return Callback (objPtr, mem_ptr); } /** @@ -403,12 +415,12 @@ Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4) const, OBJ * Build Callbacks for class method members which takes five arguments * and potentially return a value. */ -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4,T5), OBJ *const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ *const objPtr) { return Callback (objPtr, mem_ptr); } -template -Callback MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ const*const objPtr) { +template +Callback MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ const*const objPtr) { return Callback (objPtr, mem_ptr); } diff --git a/src/core/ptr.cc b/src/core/ptr.cc index 77b19fcd9..81a608b80 100644 --- a/src/core/ptr.cc +++ b/src/core/ptr.cc @@ -33,7 +33,7 @@ class NoCount : public Object public: NoCount (Callback cb); ~NoCount (); - void Nothing () const; + void Nothing (void) const; private: Callback m_cb; }; @@ -280,6 +280,23 @@ PtrTest::RunTests (void) ok = false; } } + + { + Ptr p = MakeNewObject (cb); + Callback callback = MakeCallback (&NoCount::Nothing, p); + } + { + Ptr p = MakeNewObject (cb); + Callback callback = MakeCallback (&NoCount::Nothing, p); + } + +#if 0 + // as expected, fails compilation. + { + Ptr p = MakeNewObject (cb); + Callback callback = MakeCallback (&NoCount::Nothing, p); + } +#endif return ok; diff --git a/src/core/ptr.h b/src/core/ptr.h index ef29af706..18ba47228 100644 --- a/src/core/ptr.h +++ b/src/core/ptr.h @@ -171,6 +171,19 @@ bool operator != (Ptr const &lhs, Ptr const &rhs); template Ptr const_pointer_cast (Ptr const&p); +template +struct CallbackTraits; + +template +struct CallbackTraits > +{ + static T & GetReference (Ptr const p) + { + return *GetPointer (p); + } +}; + + } // namespace ns3