diff --git a/src/core/model/callback.cc b/src/core/model/callback.cc index 3c46de791..0381e4902 100644 --- a/src/core/model/callback.cc +++ b/src/core/model/callback.cc @@ -46,6 +46,7 @@ CallbackValue::DeserializeFromString (std::string value, Ptr +struct CallbackTraits; + +/** + * Trait class to convert a pointer into a reference, + * used by MemPtrCallBackImpl + */ +template +struct CallbackTraits +{ + /** + * \param p object pointer + * \return a reference to the object pointed to by p + */ + static T & GetReference (T * const p) + { + return *p; + } +}; +/**@}*/ + +/** + * \ingroup callback + * \defgroup callbackimpl CallbackImpl + * CallbackImpl classes + */ +/** + * \ingroup callbackimpl + * Abstract base class for CallbackImpl + * Provides reference counting and equality test. + */ +class CallbackImplBase : public SimpleRefCount +{ +public: + /** Virtual destructor */ + virtual ~CallbackImplBase () {} + /** + * Equality test + * + * \param other Callback Ptr + * \return true if we are equal + */ + virtual bool IsEqual (Ptr other) const = 0; +}; + +/** + * \ingroup callbackimpl + * The unqualified CallbackImpl class + */ +template +class CallbackImpl; + +/** + * \ingroup callbackimpl + * CallbackImpl classes with varying numbers of argument types + */ +/**@{*/ +/** CallbackImpl class with no arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (void) = 0; //!< Abstract operator +}; +/** CallbackImpl class with one argument. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1) = 0; //!< Abstract operator +}; +/** CallbackImpl class with two arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2) = 0; //!< Abstract operator +}; +/** CallbackImpl class with three arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2, T3) = 0; //!< Abstract operator +}; +/** CallbackImpl class with four arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2, T3, T4) = 0; //!< Abstract operator +}; +/** CallbackImpl class with five arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2, T3, T4, T5) = 0; //!< Abstract operator +}; +/** CallbackImpl class with six arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2, T3, T4, T5, T6) = 0; //!< Abstract operator +}; +/** CallbackImpl class with seven arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2, T3, T4, T5, T6, T7) = 0; //!< Abstract operator +}; +/** CallbackImpl class with eight arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2, T3, T4, T5, T6, T7, T8) = 0; //!< Abstract operator +}; +/** CallbackImpl class with nine arguments. */ +template +class CallbackImpl : public CallbackImplBase { +public: + virtual ~CallbackImpl () {} + virtual R operator() (T1, T2, T3, T4, T5, T6, T7, T8, T9) = 0; //!< Abstract operator +}; +/**@}*/ + + +/** + * \ingroup callback + * CallbackImpl with functors + */ +template +class FunctorCallbackImpl : public CallbackImpl { +public: + /** + * Construct from a functor + * + * \param functor the functor + */ + FunctorCallbackImpl (T const &functor) + : m_functor (functor) {} + virtual ~FunctorCallbackImpl () {} + /** + * Functor with varying numbers of arguments + * @{ + */ + /** \return Callback value */ + R operator() (void) { + return m_functor (); + } + /** + * \param a1 first argument + * \return Callback value + */ + R operator() (T1 a1) { + return m_functor (a1); + } + /** + * \param a1 first argument + * \param a2 second argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2) { + return m_functor (a1,a2); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3) { + return m_functor (a1,a2,a3); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { + return m_functor (a1,a2,a3,a4); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { + return m_functor (a1,a2,a3,a4,a5); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { + return m_functor (a1,a2,a3,a4,a5,a6); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { + return m_functor (a1,a2,a3,a4,a5,a6,a7); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \param a8 eighth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) { + return m_functor (a1,a2,a3,a4,a5,a6,a7,a8); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \param a8 eighth argument + * \param a9 ninth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9) { + return m_functor (a1,a2,a3,a4,a5,a6,a7,a8,a9); + } + /**@}*/ + /** + * Equality test. + * + * \param other CallbackImpl Ptr + * \return true if this and other have the same functor + */ + virtual bool IsEqual (Ptr other) const { + FunctorCallbackImpl const *otherDerived = + dynamic_cast const *> (PeekPointer (other)); + if (otherDerived == 0) + { + return false; + } + else if (otherDerived->m_functor != m_functor) + { + return false; + } + return true; + } +private: + T m_functor; //!< the functor +}; + +/** + * \ingroup callback + * CallbackImpl for pointer to member functions + */ +template +class MemPtrCallbackImpl : public CallbackImpl { +public: + /** + * Construct from an object pointer and member function pointer + * + * \param objPtr the object pointer + * \param memPtr the object class member function + */ + MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR memPtr) + : m_objPtr (objPtr), m_memPtr (memPtr) {} + virtual ~MemPtrCallbackImpl () {} + /** + * Functor with varying numbers of arguments + * @{ + */ + /** \return Callback value */ + R operator() (void) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(); + } + /** + * \param a1 first argument + * \return Callback value + */ + R operator() (T1 a1) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1); + } + /** + * \param a1 first argument + * \param a2 second argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6, a7); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \param a8 eighth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6, a7, a8); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \param a8 eighth argument + * \param a9 ninth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, T9 a9) { + return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6, a7, a8, a9); + } + /**@}*/ + /** + * Equality test. + * + * \param other Callback Ptr + * \return true if we have the same object and member function + */ + virtual bool IsEqual (Ptr other) const { + MemPtrCallbackImpl const *otherDerived = + dynamic_cast const *> (PeekPointer (other)); + if (otherDerived == 0) + { + return false; + } + else if (otherDerived->m_objPtr != m_objPtr || + otherDerived->m_memPtr != m_memPtr) + { + return false; + } + return true; + } +private: + OBJ_PTR const m_objPtr; //!< the object pointer + MEM_PTR m_memPtr; //!< the member function pointer +}; + +/** + * \ingroup callback + * CallbackImpl for functors with first argument bound at construction + */ +template +class BoundFunctorCallbackImpl : public CallbackImpl { +public: + /** + * Construct from functor and a bound argument + * \param functor the functor + * \param a the argument to bind + */ + template + BoundFunctorCallbackImpl (FUNCTOR functor, ARG a) + : m_functor (functor), m_a (a) {} + virtual ~BoundFunctorCallbackImpl () {} + /** + * Functor with varying numbers of arguments + * @{ + */ + /** \return Callback value */ + R operator() (void) { + return m_functor (m_a); + } + /** + * \param a1 first argument + * \return Callback value + */ + R operator() (T1 a1) { + return m_functor (m_a,a1); + } + /** + * \param a1 first argument + * \param a2 second argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2) { + return m_functor (m_a,a1,a2); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3) { + return m_functor (m_a,a1,a2,a3); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { + return m_functor (m_a,a1,a2,a3,a4); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { + return m_functor (m_a,a1,a2,a3,a4,a5); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { + return m_functor (m_a,a1,a2,a3,a4,a5,a6); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { + return m_functor (m_a,a1,a2,a3,a4,a5,a6,a7); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \param a8 eighth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) { + return m_functor (m_a,a1,a2,a3,a4,a5,a6,a7,a8); + } + /**@}*/ + /** + * Equality test. + * + * \param other Callback Ptr + * \return true if we have the same functor and bound arguments + */ + virtual bool IsEqual (Ptr other) const { + BoundFunctorCallbackImpl const *otherDerived = + dynamic_cast const *> (PeekPointer (other)); + if (otherDerived == 0) + { + return false; + } + else if (otherDerived->m_functor != m_functor || + otherDerived->m_a != m_a) + { + return false; + } + return true; + } +private: + T m_functor; //!< The functor + typename TypeTraits::ReferencedType m_a; //!< the bound argument +}; + +/** + * \ingroup callback + * CallbackImpl for functors with first two arguments bound at construction + */ +template +class TwoBoundFunctorCallbackImpl : public CallbackImpl { +public: + /** + * Construct from functor and two arguments + * \param functor the functor + * \param arg1 the first argument to bind + * \param arg2 the second argument to bind + */ + template + TwoBoundFunctorCallbackImpl (FUNCTOR functor, ARG1 arg1, ARG2 arg2) + : m_functor (functor), m_a1 (arg1), m_a2 (arg2) {} + virtual ~TwoBoundFunctorCallbackImpl () {} + /** + * Functor with varying numbers of arguments + * @{ + */ + /** \return Callback value */ + R operator() (void) { + return m_functor (m_a1,m_a2); + } + /** + * \param a1 first argument + * \return Callback value + */ + R operator() (T1 a1) { + return m_functor (m_a1,m_a2,a1); + } + /** + * \param a1 first argument + * \param a2 second argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2) { + return m_functor (m_a1,m_a2,a1,a2); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3) { + return m_functor (m_a1,m_a2,a1,a2,a3); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { + return m_functor (m_a1,m_a2,a1,a2,a3,a4); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { + return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { + return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5,a6); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { + return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5,a6,a7); + } + /**@}*/ + /** + * Equality test. + * + * \param other Callback Ptr + * \return true if we have the same functor and bound arguments + */ + virtual bool IsEqual (Ptr other) const { + TwoBoundFunctorCallbackImpl const *otherDerived = + dynamic_cast const *> (PeekPointer (other)); + if (otherDerived == 0) + { + return false; + } + else if (otherDerived->m_functor != m_functor || + otherDerived->m_a1 != m_a1 || otherDerived->m_a2 != m_a2) + { + return false; + } + return true; + } +private: + T m_functor; //!< The functor + typename TypeTraits::ReferencedType m_a1; //!< first bound argument + typename TypeTraits::ReferencedType m_a2; //!< second bound argument +}; + +/** + * \ingroup callback + * CallbackImpl for functors with first three arguments bound at construction + */ +template +class ThreeBoundFunctorCallbackImpl : public CallbackImpl { +public: + /** + * Construct from functor and three arguments + * \param functor the functor + * \param arg1 the first argument to bind + * \param arg2 the second argument to bind + * \param arg3 the third argument to bind + */ + template + ThreeBoundFunctorCallbackImpl (FUNCTOR functor, ARG1 arg1, ARG2 arg2, ARG3 arg3) + : m_functor (functor), m_a1 (arg1), m_a2 (arg2), m_a3 (arg3) {} + virtual ~ThreeBoundFunctorCallbackImpl () {} + /** + * Functor with varying numbers of arguments + * @{ + */ + /** \return Callback value */ + R operator() (void) { + return m_functor (m_a1,m_a2,m_a3); + } + /** + * \param a1 first argument + * \return Callback value + */ + R operator() (T1 a1) { + return m_functor (m_a1,m_a2,m_a3,a1); + } + /** + * \param a1 first argument + * \param a2 second argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2) { + return m_functor (m_a1,m_a2,m_a3,a1,a2); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3) { + return m_functor (m_a1,m_a2,m_a3,a1,a2,a3); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { + return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { + return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4,a5); + } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \return Callback value + */ + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { + return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4,a5,a6); + } + /**@}*/ + /** + * Equality test. + * + * \param other Callback Ptr + * \return true if we have the same functor and bound arguments + */ + virtual bool IsEqual (Ptr other) const { + ThreeBoundFunctorCallbackImpl const *otherDerived = + dynamic_cast const *> (PeekPointer (other)); + if (otherDerived == 0) + { + return false; + } + else if (otherDerived->m_functor != m_functor || + otherDerived->m_a1 != m_a1 || otherDerived->m_a2 != m_a2 || otherDerived->m_a3 != m_a3) + { + return false; + } + return true; + } +private: + T m_functor; //!< The functor + typename TypeTraits::ReferencedType m_a1; //!< first bound argument + typename TypeTraits::ReferencedType m_a2; //!< second bound argument + typename TypeTraits::ReferencedType m_a3; //!< third bound argument +}; + +/** + * \ingroup callback + * Base class for Callback class. + * Provides pimpl abstraction. + */ +class CallbackBase { +public: + CallbackBase () : m_impl () {} + /** \return the impl pointer */ + Ptr GetImpl (void) const { return m_impl; } +protected: + /** + * Construct from a pimpl + * \param impl the CallbackImplBase Ptr + */ + CallbackBase (Ptr impl) : m_impl (impl) {} + Ptr m_impl; //!< the pimpl + + /** + * \param mangled the mangled string + * \return the demangled form of mangled + */ + static std::string Demangle (const std::string& mangled); +}; + +/** + * \ingroup callback + * \brief Callback template class + * + * This class template implements the Functor Design Pattern. + * It is used to declare the type of a Callback: + * - the first non-optional template argument represents + * the return type of the callback. + * - the remaining (optional) template arguments represent + * the type of the subsequent arguments to the callback. + * - up to nine arguments are supported. + * + * Callback instances are built with the \ref MakeCallback + * template functions. Callback instances have POD semantics: + * the memory they allocate is managed automatically, without + * user intervention which allows you to pass around Callback + * instances by value. + * + * Sample code which shows how to use this class template + * as well as the function templates \ref MakeCallback : + * \include src/core/examples/main-callback.cc + * + * \intern * This code was originally written based on the techniques * described in http://www.codeproject.com/cpp/TTLFunction.asp * It was subsequently rewritten to follow the architecture @@ -61,404 +911,6 @@ namespace ns3 { * and relies on a reference list rather than autoPtr to hold * the pointer. */ -template -struct CallbackTraits; - -template -struct CallbackTraits -{ - static T & GetReference (T * const p) - { - return *p; - } -}; - -class CallbackImplBase : public SimpleRefCount -{ -public: - virtual ~CallbackImplBase () {} - virtual bool IsEqual (Ptr other) const = 0; -}; - -// declare the CallbackImpl class -template -class CallbackImpl; -// define CallbackImpl for 0 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (void) = 0; -}; -// define CallbackImpl for 1 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1) = 0; -}; -// define CallbackImpl for 2 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2) = 0; -}; -// define CallbackImpl for 3 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2, T3) = 0; -}; -// define CallbackImpl for 4 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2, T3, T4) = 0; -}; -// define CallbackImpl for 5 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2, T3, T4, T5) = 0; -}; -// define CallbackImpl for 6 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2, T3, T4, T5, T6) = 0; -}; -// define CallbackImpl for 7 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2, T3, T4, T5, T6, T7) = 0; -}; -// define CallbackImpl for 8 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2, T3, T4, T5, T6, T7, T8) = 0; -}; -// define CallbackImpl for 9 params -template -class CallbackImpl : public CallbackImplBase { -public: - virtual ~CallbackImpl () {} - virtual R operator() (T1, T2, T3, T4, T5, T6, T7, T8, T9) = 0; -}; - - -// an impl for Functors: -template -class FunctorCallbackImpl : public CallbackImpl { -public: - FunctorCallbackImpl (T const &functor) - : m_functor (functor) {} - virtual ~FunctorCallbackImpl () {} - R operator() (void) { - return m_functor (); - } - R operator() (T1 a1) { - return m_functor (a1); - } - R operator() (T1 a1,T2 a2) { - return m_functor (a1,a2); - } - R operator() (T1 a1,T2 a2,T3 a3) { - return m_functor (a1,a2,a3); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { - return m_functor (a1,a2,a3,a4); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { - return m_functor (a1,a2,a3,a4,a5); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { - return m_functor (a1,a2,a3,a4,a5,a6); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { - return m_functor (a1,a2,a3,a4,a5,a6,a7); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) { - return m_functor (a1,a2,a3,a4,a5,a6,a7,a8); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9) { - return m_functor (a1,a2,a3,a4,a5,a6,a7,a8,a9); - } - virtual bool IsEqual (Ptr other) const { - FunctorCallbackImpl const *otherDerived = - dynamic_cast const *> (PeekPointer (other)); - if (otherDerived == 0) - { - return false; - } - else if (otherDerived->m_functor != m_functor) - { - return false; - } - return true; - } -private: - T m_functor; -}; - -// an impl for pointer to member functions -template -class MemPtrCallbackImpl : public CallbackImpl { -public: - MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr) - : m_objPtr (objPtr), m_memPtr (mem_ptr) {} - virtual ~MemPtrCallbackImpl () {} - R operator() (void) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(); - } - R operator() (T1 a1) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1); - } - R operator() (T1 a1,T2 a2) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2); - } - R operator() (T1 a1,T2 a2,T3 a3) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 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 ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6, a7); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6, a7, a8); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, T9 a9) { - return ((CallbackTraits::GetReference (m_objPtr)).*m_memPtr)(a1, a2, a3, a4, a5, a6, a7, a8, a9); - } - virtual bool IsEqual (Ptr other) const { - MemPtrCallbackImpl const *otherDerived = - dynamic_cast const *> (PeekPointer (other)); - if (otherDerived == 0) - { - return false; - } - else if (otherDerived->m_objPtr != m_objPtr || - otherDerived->m_memPtr != m_memPtr) - { - return false; - } - return true; - } -private: - OBJ_PTR const m_objPtr; - MEM_PTR m_memPtr; -}; - -// an impl for Bound Functors: -template -class BoundFunctorCallbackImpl : public CallbackImpl { -public: - template - BoundFunctorCallbackImpl (FUNCTOR functor, ARG a) - : m_functor (functor), m_a (a) {} - virtual ~BoundFunctorCallbackImpl () {} - R operator() (void) { - return m_functor (m_a); - } - R operator() (T1 a1) { - return m_functor (m_a,a1); - } - R operator() (T1 a1,T2 a2) { - return m_functor (m_a,a1,a2); - } - R operator() (T1 a1,T2 a2,T3 a3) { - return m_functor (m_a,a1,a2,a3); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { - return m_functor (m_a,a1,a2,a3,a4); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { - return m_functor (m_a,a1,a2,a3,a4,a5); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { - return m_functor (m_a,a1,a2,a3,a4,a5,a6); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { - return m_functor (m_a,a1,a2,a3,a4,a5,a6,a7); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) { - return m_functor (m_a,a1,a2,a3,a4,a5,a6,a7,a8); - } - virtual bool IsEqual (Ptr other) const { - BoundFunctorCallbackImpl const *otherDerived = - dynamic_cast const *> (PeekPointer (other)); - if (otherDerived == 0) - { - return false; - } - else if (otherDerived->m_functor != m_functor || - otherDerived->m_a != m_a) - { - return false; - } - return true; - } -private: - T m_functor; - typename TypeTraits::ReferencedType m_a; -}; - -template -class TwoBoundFunctorCallbackImpl : public CallbackImpl { -public: - template - TwoBoundFunctorCallbackImpl (FUNCTOR functor, ARG1 arg1, ARG2 arg2) - : m_functor (functor), m_a1 (arg1), m_a2 (arg2) {} - virtual ~TwoBoundFunctorCallbackImpl () {} - R operator() (void) { - return m_functor (m_a1,m_a2); - } - R operator() (T1 a1) { - return m_functor (m_a1,m_a2,a1); - } - R operator() (T1 a1,T2 a2) { - return m_functor (m_a1,m_a2,a1,a2); - } - R operator() (T1 a1,T2 a2,T3 a3) { - return m_functor (m_a1,m_a2,a1,a2,a3); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { - return m_functor (m_a1,m_a2,a1,a2,a3,a4); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { - return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { - return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5,a6); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) { - return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5,a6,a7); - } - virtual bool IsEqual (Ptr other) const { - TwoBoundFunctorCallbackImpl const *otherDerived = - dynamic_cast const *> (PeekPointer (other)); - if (otherDerived == 0) - { - return false; - } - else if (otherDerived->m_functor != m_functor || - otherDerived->m_a1 != m_a1 || otherDerived->m_a2 != m_a2) - { - return false; - } - return true; - } -private: - T m_functor; - typename TypeTraits::ReferencedType m_a1; - typename TypeTraits::ReferencedType m_a2; -}; - -template -class ThreeBoundFunctorCallbackImpl : public CallbackImpl { -public: - template - ThreeBoundFunctorCallbackImpl (FUNCTOR functor, ARG1 arg1, ARG2 arg2, ARG3 arg3) - : m_functor (functor), m_a1 (arg1), m_a2 (arg2), m_a3 (arg3) {} - virtual ~ThreeBoundFunctorCallbackImpl () {} - R operator() (void) { - return m_functor (m_a1,m_a2,m_a3); - } - R operator() (T1 a1) { - return m_functor (m_a1,m_a2,m_a3,a1); - } - R operator() (T1 a1,T2 a2) { - return m_functor (m_a1,m_a2,m_a3,a1,a2); - } - R operator() (T1 a1,T2 a2,T3 a3) { - return m_functor (m_a1,m_a2,m_a3,a1,a2,a3); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { - return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { - return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4,a5); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) { - return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4,a5,a6); - } - virtual bool IsEqual (Ptr other) const { - ThreeBoundFunctorCallbackImpl const *otherDerived = - dynamic_cast const *> (PeekPointer (other)); - if (otherDerived == 0) - { - return false; - } - else if (otherDerived->m_functor != m_functor || - otherDerived->m_a1 != m_a1 || otherDerived->m_a2 != m_a2 || otherDerived->m_a3 != m_a3) - { - return false; - } - return true; - } -private: - T m_functor; - typename TypeTraits::ReferencedType m_a1; - typename TypeTraits::ReferencedType m_a2; - typename TypeTraits::ReferencedType m_a3; -}; - -class CallbackBase { -public: - CallbackBase () : m_impl () {} - Ptr GetImpl (void) const { return m_impl; } -protected: - CallbackBase (Ptr impl) : m_impl (impl) {} - Ptr m_impl; - - static std::string Demangle (const std::string& mangled); -}; - -/** - * \brief Callback template class - * - * This class template implements the Functor Design Pattern. - * It is used to declare the type of a Callback: - * - the first non-optional template argument represents - * the return type of the callback. - * - the second optional template argument represents - * the type of the first argument to the callback. - * - the third optional template argument represents - * the type of the second argument to the callback. - * - the fourth optional template argument represents - * the type of the third argument to the callback. - * - the fifth optional template argument represents - * the type of the fourth argument to the callback. - * - the sixth optional template argument represents - * the type of the fifth argument to the callback. - * - * Callback instances are built with the \ref MakeCallback - * template functions. Callback instances have POD semantics: - * the memory they allocate is managed automatically, without - * user intervention which allows you to pass around Callback - * instances by value. - * - * Sample code which shows how to use this class template - * as well as the function templates \ref MakeCallback : - * \include src/core/examples/main-callback.cc - */ - template Callback (FUNCTOR const &functor, bool, bool) : CallbackBase (Create > (functor)) {} + /** + * Construct a member function pointer call back. + * + * \param objPtr pointer to the object + * \param memPtr pointer to the member function + */ template - Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr) - : CallbackBase (Create > (objPtr, mem_ptr)) + Callback (OBJ_PTR const &objPtr, MEM_PTR memPtr) + : CallbackBase (Create > (objPtr, memPtr)) {} + /** + * Construct from a CallbackImpl pointer + * + * \param impl the CallbackImpl Ptr + */ Callback (Ptr > const &impl) : CallbackBase (impl) {} + /** + * Bind the first arguments + * + * \param a argument to bind + * \return the bound callback + */ template Callback Bind (T a) { Ptr > impl = @@ -495,6 +971,13 @@ public: return Callback (impl); } + /** + * Bind the first two arguments + * + * \param a1 first argument to bind + * \param a2 second argument to bind + * \return the bound callback + */ template Callback TwoBind (TX1 a1, TX2 a2) { Ptr > impl = @@ -505,6 +988,14 @@ public: return Callback (impl); } + /** + * Bind the first three arguments + * + * \param a1 first argument to bind + * \param a2 second argument to bind + * \param a3 third argument to bind + * \return the bound callback + */ template Callback ThreeBind (TX1 a1, TX2 a2, TX3 a3) { Ptr > impl = @@ -515,58 +1006,166 @@ public: return Callback (impl); } + /** + * Check for null implementation + * + * \return true if I don't have an implementation + */ bool IsNull (void) const { return (DoPeekImpl () == 0) ? true : false; } + /** Discard the implementation, set it to null */ void Nullify (void) { m_impl = 0; } + /** + * Functor with varying numbers of arguments + * @{ + */ + /** \return Callback value */ R operator() (void) const { return (*(DoPeekImpl ()))(); } + /** + * \param a1 first argument + * \return Callback value + */ R operator() (T1 a1) const { return (*(DoPeekImpl ()))(a1); } + /** + * \param a1 first argument + * \param a2 second argument + * \return Callback value + */ R operator() (T1 a1, T2 a2) const { return (*(DoPeekImpl ()))(a1,a2); } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \return Callback value + */ R operator() (T1 a1, T2 a2, T3 a3) const { return (*(DoPeekImpl ()))(a1,a2,a3); } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \return Callback value + */ R operator() (T1 a1, T2 a2, T3 a3, T4 a4) const { return (*(DoPeekImpl ()))(a1,a2,a3,a4); } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \return Callback value + */ R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) const { return (*(DoPeekImpl ()))(a1,a2,a3,a4,a5); } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \return Callback value + */ R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6) const { return (*(DoPeekImpl ()))(a1,a2,a3,a4,a5,a6); } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \return Callback value + */ R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6,T7 a7) const { return (*(DoPeekImpl ()))(a1,a2,a3,a4,a5,a6,a7); } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \param a8 seventh argument + * \return Callback value + */ R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) const { return (*(DoPeekImpl ()))(a1,a2,a3,a4,a5,a6,a7,a8); } + /** + * \param a1 first argument + * \param a2 second argument + * \param a3 third argument + * \param a4 fourth argument + * \param a5 fifth argument + * \param a6 sixth argument + * \param a7 seventh argument + * \param a8 eighth argument + * \param a9 ninth argument + * \return Callback value + */ R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, T9 a9) const { return (*(DoPeekImpl ()))(a1,a2,a3,a4,a5,a6,a7,a8,a9); } + /**@}*/ + /** + * Equality test. + * + * \param other Callback + * \return true if we are equal + */ bool IsEqual (const CallbackBase &other) const { return m_impl->IsEqual (other.GetImpl ()); } + /** + * Check for compatible types + * + * \param other Callback Ptr + * \return true if other can be dynamic_cast to my type + */ bool CheckType (const CallbackBase & other) const { return DoCheckType (other.GetImpl ()); } + /** + * Adopt the other's implementation, if type compatible + * + * \param other Callback + */ void Assign (const CallbackBase &other) { DoAssign (other.GetImpl ()); } private: + /** \return the pimpl pointer */ CallbackImpl *DoPeekImpl (void) const { return static_cast *> (PeekPointer (m_impl)); } + /** + * Check for compatible types + * + * \param other Callback Ptr + * \return true if other can be dynamic_cast to my type + */ bool DoCheckType (Ptr other) const { if (other != 0 && dynamic_cast *> (PeekPointer (other)) != 0) { @@ -581,6 +1180,11 @@ private: return false; } } + /** + * Adopt the other's implementation, if type compatible + * + * \param other Callback Ptr to adopt from + */ void DoAssign (Ptr other) { if (!DoCheckType (other)) { @@ -593,6 +1197,14 @@ private: }; +/** + * Inequality test. + * + * \param a Callback + * \param b Callback + * + * \return true if the Callbacks are not equal + */ template a, Callback Callback MakeCallback (R (T::*memPtr)(void), OBJ objPtr) { return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)() const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); -} -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes one argument - * and potentially return a value. - */ -template -Callback MakeCallback (R (T::*mem_ptr)(T1), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)() const, OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1), OBJ objPtr) { + return Callback (objPtr, memPtr); } -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes two arguments - * and potentially return a value. - */ -template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +template +Callback MakeCallback (R (T::*memPtr)(T1) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2), OBJ objPtr) { + return Callback (objPtr, memPtr); } -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes three arguments - * and potentially return a value. - */ -template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +template +Callback MakeCallback (R (T::*memPtr)(T1,T2) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3), OBJ objPtr) { + return Callback (objPtr, memPtr); } -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes four arguments - * and potentially return a value. - */ -template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +template +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4), OBJ objPtr) { + return Callback (objPtr, memPtr); } -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes five arguments - * and potentially return a value. - */ -template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +template +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5), OBJ objPtr) { + return Callback (objPtr, memPtr); +} +template +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes six arguments - * and potentially return a value. - */ template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6), OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } - -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes seven arguments - * and potentially return a value. - */ template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6,T7), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6,T7), OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6,T7) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6,T7) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } - - -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes eight arguments - * and potentially return a value. - */ template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6,T7,T8), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6,T7,T8), OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6,T7,T8) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6,T7,T8) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } - -/** - * \ingroup MakeCallback - * \param mem_ptr class method member pointer - * \param objPtr class instance - * \return a wrapper Callback - * Build Callbacks for class method members which takes nine arguments - * and potentially return a value. - */ template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9), OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6,T7,T8,T9), OBJ objPtr) { + return Callback (objPtr, memPtr); } template -Callback MakeCallback (R (T::*mem_ptr)(T1,T2,T3,T4,T5,T6,T7,T8,T9) const, OBJ objPtr) { - return Callback (objPtr, mem_ptr); +Callback MakeCallback (R (T::*memPtr)(T1,T2,T3,T4,T5,T6,T7,T8,T9) const, OBJ objPtr) { + return Callback (objPtr, memPtr); } +/**@}*/ /** - * \ingroup MakeCallback + * \ingroup callback + * \defgroup makecallbackfnptr MakeCallback from function pointers + * + * Build Callbacks for functions which take varying numbers of arguments + * and potentially returning a value. + */ +/** + * \ingroup makecallbackfnptr + * @{ + */ +/** * \param fnPtr function pointer * \return a wrapper Callback - * Build Callbacks for functions which takes no arguments - * and potentially return a value. + * + * Build Callbacks for functions which take varying numbers of arguments + * and potentially returning a value. */ template Callback MakeCallback (R (*fnPtr)()) { return Callback (fnPtr, true, true); } -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes one argument - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1)) { return Callback (fnPtr, true, true); } -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes two arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2)) { return Callback (fnPtr, true, true); } -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes three arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2,T3)) { return Callback (fnPtr, true, true); } -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes four arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2,T3,T4)) { return Callback (fnPtr, true, true); } -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes five arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2,T3,T4,T5)) { return Callback (fnPtr, true, true); } -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes six arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2,T3,T4,T5,T6)) { return Callback (fnPtr, true, true); } - -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes seven arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2,T3,T4,T5,T6,T7)) { return Callback (fnPtr, true, true); } - -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes eight arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2,T3,T4,T5,T6,T7,T8)) { return Callback (fnPtr, true, true); } - -/** - * \ingroup MakeCallback - * \param fnPtr function pointer - * \return a wrapper Callback - * Build Callbacks for functions which takes nine arguments - * and potentially return a value. - */ template Callback MakeCallback (R (*fnPtr)(T1,T2,T3,T4,T5,T6,T7,T8,T9)) { return Callback (fnPtr, true, true); } - - +/**@}*/ /** - * \ingroup MakeCallback - * \return a wrapper Callback - * Build a null callback which takes no arguments - * and potentially return a value. + * \ingroup callback + * \defgroup makenullcallback MakeCallbacks with no arguments */ +/** + * \ingroup makenullcallback + * @{ + */ +/** + * \return a wrapper Callback + * + * Build null Callbacks which take no arguments, + * for varying number of template arguments, + * and potentially returning a value. + */ template Callback MakeNullCallback (void) { return Callback (); } -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes one argument - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes two arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes three arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes four arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes five arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes six arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } - -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes seven arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } - -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes eight arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } - -/** - * \ingroup MakeCallback - * \overload Callback MakeNullCallback (void) - * \return a wrapper Callback - * Build a null callback which takes nine arguments - * and potentially return a value. - */ template Callback MakeNullCallback (void) { return Callback (); } +/**@}*/ -/* +/** + * \ingroup callback + * \defgroup makeboundcallback MakeBoundCallback from functions bound with up to three arguments. + */ + +/** + * \ingroup makeboundcallback + * + * Build bound Callbacks which take varying numbers of arguments, + * and potentially returning a value. + * + * \intern + * * The following is experimental code. It works but we have * not yet determined whether or not it is really useful and whether * or not we really want to use it. + * + * @{ */ - +/** + * @{ + * \param fnPtr function pointer + * \param a1 first bound argument + * \return a bound Callback + */ template -Callback MakeBoundCallback (R (*fnPtr)(TX), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX), ARG a1) { Ptr > impl = - Create >(fnPtr, a); + Create >(fnPtr, a1); return Callback (impl); } - template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5,T6), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5,T6), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5,T6,T7), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5,T6,T7), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } template -Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5,T6,T7,T8), ARG a) { +Callback MakeBoundCallback (R (*fnPtr)(TX,T1,T2,T3,T4,T5,T6,T7,T8), ARG a1) { Ptr > impl = - Create > (fnPtr, a); + Create > (fnPtr, a1); return Callback (impl); } +/**@}*/ +/** + * \param fnPtr function pointer + * \param a1 first bound argument + * \param a2 second bound argument + * \return a bound Callback + * @{ + */ template Callback MakeBoundCallback (R (*fnPtr)(TX1,TX2), ARG1 a1, ARG2 a2) { Ptr > impl = Create >(fnPtr, a1, a2); return Callback (impl); } - template Callback MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1), ARG1 a1, ARG2 a2) { @@ -1130,14 +1585,22 @@ Callback MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1,T2,T3, Create > (fnPtr, a1, a2); return Callback (impl); } +/**@}*/ +/** + * \param a1 first bound argument + * \param a2 second bound argument + * \param a3 third bound argument + * \param fnPtr function pointer + * \return a bound Callback + * @{ + */ template Callback MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3), ARG1 a1, ARG2 a2, ARG3 a3) { Ptr > impl = Create >(fnPtr, a1, a2, a3); return Callback (impl); } - template Callback MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1), ARG1 a1, ARG2 a2, ARG3 a3) { @@ -1180,29 +1643,62 @@ Callback MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1,T2,T3 Create > (fnPtr, a1, a2, a3); return Callback (impl); } +/**@}*/ + +/**@}*/ } // namespace ns3 namespace ns3 { +/** + * \ingroup callback + * AttributeValue form of a Callback + */ class CallbackValue : public AttributeValue { public: CallbackValue (); - CallbackValue (const CallbackBase &base); + /** + * Copy constructor + * \param base Callback to copy + */ + CallbackValue (const CallbackBase &base); virtual ~CallbackValue (); + /** \param base the Callbackbase to use */ void Set (CallbackBase base); + /** + * Give value my callback, if type compatible + * + * \param value destination callback + * \returns true if successful + */ template bool GetAccessor (T &value) const; + /** \return a copy of this CallBack */ virtual Ptr Copy (void) const; + /** + * Serialize to string + * \param checker the checker to validate with + * \return serialize this pimpl + */ virtual std::string SerializeToString (Ptr checker) const; + /** + * Deserialize from string (not implemented) + * + * \param value source string + * \param checker checker to validate with + * \return true if successful + */ virtual bool DeserializeFromString (std::string value, Ptr checker); private: - CallbackBase m_value; + CallbackBase m_value; //!< the CallbackBase }; +/** Attribute helpers @{ */ ATTRIBUTE_ACCESSOR_DEFINE (Callback); ATTRIBUTE_CHECKER_DEFINE (Callback); +/**@}*/ } // namespace ns3