src/core/callback.h
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sun, 02 Mar 2008 21:00:37 +0100
changeset 2531 b451b5fc8b57
parent 2514 9402a946ac3d
child 2630 17b545238ab3
permissions -rw-r--r--
implement context-based trace connection
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2005,2006 INRIA
     4  * All rights reserved.
     5  *
     6  * This program is free software; you can redistribute it and/or modify
     7  * it under the terms of the GNU General Public License version 2 as
     8  * published by the Free Software Foundation;
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program; if not, write to the Free Software
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18  *
    19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    20  */
    21 
    22 #ifndef CALLBACK_H
    23 #define CALLBACK_H
    24 
    25 #include "ptr.h"
    26 #include "fatal-error.h"
    27 #include "empty.h"
    28 #include "type-traits.h"
    29 #include "object-base.h"
    30 
    31 namespace ns3 {
    32 
    33 /***
    34  * \internal
    35  * This code was originally written based on the techniques 
    36  * described in http://www.codeproject.com/cpp/TTLFunction.asp
    37  * It was subsequently rewritten to follow the architecture
    38  * outlined in "Modern C++ Design" by Andrei Alexandrescu in 
    39  * chapter 5, "Generalized Functors".
    40  *
    41  * This code uses:
    42  *   - default template parameters to saves users from having to
    43  *     specify empty parameters when the number of parameters
    44  *     is smaller than the maximum supported number
    45  *   - the pimpl idiom: the Callback class is passed around by 
    46  *     value and delegates the crux of the work to its pimpl
    47  *     pointer.
    48  *   - two pimpl implementations which derive from CallbackImpl
    49  *     FunctorCallbackImpl can be used with any functor-type
    50  *     while MemPtrCallbackImpl can be used with pointers to
    51  *     member functions.
    52  *   - a reference list implementation to implement the Callback's
    53  *     value semantics.
    54  *
    55  * This code most notably departs from the alexandrescu 
    56  * implementation in that it does not use type lists to specify
    57  * and pass around the types of the callback arguments.
    58  * Of course, it also does not use copy-destruction semantics
    59  * and relies on a reference list rather than autoPtr to hold
    60  * the pointer.
    61  */
    62 template <typename T>
    63 struct CallbackTraits;
    64 
    65 template <typename T>
    66 struct CallbackTraits<T *>
    67 {
    68   static T & GetReference (T * const p)
    69   {
    70     return *p;
    71   }
    72 };
    73 
    74 class CallbackImplBase : public ObjectBase 
    75 {
    76 public:
    77   CallbackImplBase ()
    78     : m_count (1) {}
    79   virtual ~CallbackImplBase () {}
    80   void Ref (void) const {
    81     m_count++;
    82   }
    83   void Unref (void) const {
    84     m_count--;
    85     if (m_count == 0) {
    86       delete this;
    87     }
    88   }
    89   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const = 0;
    90 private:
    91   mutable uint32_t m_count;
    92 };
    93 
    94 // declare the CallbackImpl class
    95 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
    96 class CallbackImpl;
    97 // define CallbackImpl for 0 params
    98 template <typename R>
    99 class CallbackImpl<R,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
   100 public:
   101   virtual ~CallbackImpl () {}
   102   virtual R operator() (void) = 0;
   103 };
   104 // define CallbackImpl for 1 params
   105 template <typename R, typename T1>
   106 class CallbackImpl<R,T1,empty,empty,empty,empty,empty> : public CallbackImplBase {
   107 public:
   108   virtual ~CallbackImpl () {}
   109   virtual R operator() (T1) = 0;
   110 };
   111 // define CallbackImpl for 2 params
   112 template <typename R, typename T1, typename T2>
   113 class CallbackImpl<R,T1,T2,empty,empty,empty,empty> : public CallbackImplBase {
   114 public:
   115   virtual ~CallbackImpl () {}
   116   virtual R operator() (T1, T2) = 0;
   117 };
   118 // define CallbackImpl for 3 params
   119 template <typename R, typename T1, typename T2, typename T3>
   120 class CallbackImpl<R,T1,T2,T3,empty,empty,empty> : public CallbackImplBase {
   121 public:
   122   virtual ~CallbackImpl () {}
   123   virtual R operator() (T1, T2, T3) = 0;
   124 };
   125 // define CallbackImpl for 4 params
   126 template <typename R, typename T1, typename T2, typename T3, typename T4>
   127 class CallbackImpl<R,T1,T2,T3,T4,empty,empty> : public CallbackImplBase {
   128 public:
   129   virtual ~CallbackImpl () {}
   130   virtual R operator() (T1, T2, T3, T4) = 0;
   131 };
   132 // define CallbackImpl for 5 params
   133 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
   134 class CallbackImpl<R,T1,T2,T3,T4,T5,empty> : public CallbackImplBase {
   135 public:
   136   virtual ~CallbackImpl () {}
   137   virtual R operator() (T1, T2, T3, T4, T5) = 0;
   138 };
   139 // define CallbackImpl for 6 params
   140   template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
   141 class CallbackImpl : public CallbackImplBase {
   142 public:
   143   virtual ~CallbackImpl () {}
   144   virtual R operator() (T1, T2, T3, T4, T5, T6) = 0;
   145 };
   146 
   147 
   148 // an impl for Functors:
   149 template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
   150 class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6> {
   151 public:
   152   FunctorCallbackImpl (T const &functor)
   153     : m_functor (functor) {}
   154   virtual ~FunctorCallbackImpl () {}
   155   R operator() (void) {
   156       return m_functor ();
   157   }
   158   R operator() (T1 a1) {
   159       return m_functor (a1);
   160   }
   161   R operator() (T1 a1,T2 a2) {
   162       return m_functor (a1,a2);
   163   }
   164   R operator() (T1 a1,T2 a2,T3 a3) {
   165       return m_functor (a1,a2,a3);
   166   }
   167   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   168       return m_functor (a1,a2,a3,a4);
   169   }
   170   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   171       return m_functor (a1,a2,a3,a4,a5);
   172   }
   173   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
   174     return m_functor (a1,a2,a3,a4,a5,a6);
   175   }
   176   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
   177     FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6> const *otherDerived = 
   178       dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6> const *> (PeekPointer(other));
   179     if (otherDerived == 0)
   180       {
   181         return false;
   182       }
   183     else if (otherDerived->m_functor != m_functor)
   184       {
   185         return false;
   186       }
   187     return true;
   188   }
   189 private:
   190   T m_functor;
   191 };
   192 
   193 // an impl for pointer to member functions
   194 template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
   195 class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6> {
   196 public:
   197   MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
   198     : m_objPtr (objPtr), m_memPtr (mem_ptr) {}
   199   virtual ~MemPtrCallbackImpl () {}
   200   R operator() (void) {
   201     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) ();
   202   }
   203   R operator() (T1 a1) {
   204     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1);
   205   }
   206   R operator() (T1 a1,T2 a2) {
   207     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2);
   208   }
   209   R operator() (T1 a1,T2 a2,T3 a3) {
   210     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3);
   211   }
   212   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   213     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4);
   214   }
   215   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   216     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5);
   217   }
   218   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
   219     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5, a6);
   220   }
   221   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
   222     MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> const *otherDerived = 
   223       dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> const *> (PeekPointer (other));
   224     if (otherDerived == 0)
   225       {
   226         return false;
   227       }
   228     else if (otherDerived->m_objPtr != m_objPtr ||
   229              otherDerived->m_memPtr != m_memPtr)
   230       {
   231         return false;
   232       }
   233     return true;
   234   }
   235 private:
   236   OBJ_PTR const m_objPtr;
   237   MEM_PTR m_memPtr;
   238 };
   239 
   240 // an impl for Bound Functors:
   241 template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5>
   242 class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,empty> {
   243 public:
   244   template <typename FUNCTOR, typename ARG>
   245   BoundFunctorCallbackImpl (FUNCTOR functor, ARG a)
   246       : m_functor (functor), m_a (a) {}
   247   virtual ~BoundFunctorCallbackImpl () {}
   248   R operator() (void) {
   249       return m_functor (m_a);
   250   }
   251   R operator() (T1 a1) {
   252       return m_functor (m_a,a1);
   253   }
   254   R operator() (T1 a1,T2 a2) {
   255       return m_functor (m_a,a1,a2);
   256   }
   257   R operator() (T1 a1,T2 a2,T3 a3) {
   258       return m_functor (m_a,a1,a2,a3);
   259   }
   260   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   261       return m_functor (m_a,a1,a2,a3,a4);
   262   }
   263   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   264       return m_functor (m_a,a1,a2,a3,a4,a5);
   265   }
   266   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
   267     BoundFunctorCallbackImpl<T,R,TX,T1,T2,T3,T4,T5> const *otherDerived = 
   268       dynamic_cast<BoundFunctorCallbackImpl<T,R,TX,T1,T2,T3,T4,T5> const *> (PeekPointer (other));
   269     if (otherDerived == 0)
   270       {
   271         return false;
   272       }
   273     else if (otherDerived->m_functor != m_functor ||
   274              otherDerived->m_a != m_a)
   275       {
   276         return false;
   277       }
   278     return true;
   279   }
   280 private:
   281   T m_functor;
   282   typename TypeTraits<TX>::ReferencedType m_a;
   283 };
   284 
   285 
   286 class CallbackBase {
   287 public:
   288   CallbackBase () : m_impl () {}
   289   Ptr<CallbackImplBase> GetImpl (void) const {return m_impl;}
   290 protected:
   291   CallbackBase (Ptr<CallbackImplBase> impl) : m_impl (impl) {}
   292   Ptr<CallbackImplBase> m_impl;
   293 };
   294 
   295 /**
   296  * \brief Callback template class
   297  *
   298  * This class template implements the Functor Design Pattern.
   299  * It is used to declare the type of a Callback:
   300  *  - the first non-optional template argument represents
   301  *    the return type of the callback.
   302  *  - the second optional template argument represents
   303  *    the type of the first argument to the callback.
   304  *  - the third optional template argument represents
   305  *    the type of the second argument to the callback.
   306  *  - the fourth optional template argument represents
   307  *    the type of the third argument to the callback.
   308  *  - the fifth optional template argument represents
   309  *    the type of the fourth argument to the callback.
   310  *  - the sixth optional template argument represents
   311  *    the type of the fifth argument to the callback.
   312  *
   313  * Callback instances are built with the \ref MakeCallback
   314  * template functions. Callback instances have POD semantics:
   315  * the memory they allocate is managed automatically, without
   316  * user intervention which allows you to pass around Callback
   317  * instances by value.
   318  *
   319  * Sample code which shows how to use this class template 
   320  * as well as the function templates \ref MakeCallback :
   321  * \include samples/main-callback.cc
   322  */
   323 
   324 template<typename R, 
   325    typename T1 = empty, typename T2 = empty, 
   326    typename T3 = empty, typename T4 = empty,
   327    typename T5 = empty, typename T6 = empty>
   328 class Callback : public CallbackBase {
   329 public:
   330   Callback () {}
   331 
   332   // There are two dummy args below to ensure that this constructor is
   333   // always properly disambiguited by the c++ compiler
   334   template <typename FUNCTOR>
   335   Callback (FUNCTOR const &functor, bool, bool) 
   336     : CallbackBase (Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5,T6> > (functor))
   337   {}
   338 
   339   template <typename OBJ_PTR, typename MEM_PTR>
   340   Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
   341     : CallbackBase (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6> > (objPtr, mem_ptr))
   342   {}
   343 
   344   Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6> > const &impl)
   345     : CallbackBase (impl)
   346   {}
   347 
   348   template <typename T>
   349   Callback<R,T2,T3,T4,T5,T6> Bind (T a) {
   350     Ptr<CallbackImpl<R,T2,T3,T4,T5,T6,empty> > impl =
   351       Ptr<CallbackImpl<R,T2,T3,T4,T5,T6,empty> > (
   352                                             new BoundFunctorCallbackImpl<
   353                                             Callback<R,T1,T2,T3,T4,T5,T6>,
   354                                             R,T1,T2,T3,T4,T5,T6> (*this, a), false);
   355     return Callback<R,T2,T3,T4,T5,T6> (impl);
   356   }
   357 
   358   bool IsNull (void) const {
   359     return (DoPeekImpl () == 0)?true:false;
   360   }
   361   void Nullify (void) {
   362     m_impl = 0;
   363   }
   364 
   365   R operator() (void) const {
   366     return (*(DoPeekImpl ())) ();
   367   }
   368   R operator() (T1 a1) const {
   369     return (*(DoPeekImpl ())) (a1);
   370   }
   371   R operator() (T1 a1, T2 a2) const {
   372     return (*(DoPeekImpl ())) (a1,a2);
   373   }
   374   R operator() (T1 a1, T2 a2, T3 a3) const {
   375     return (*(DoPeekImpl ())) (a1,a2,a3);
   376   }
   377   R operator() (T1 a1, T2 a2, T3 a3, T4 a4) const {
   378     return (*(DoPeekImpl ())) (a1,a2,a3,a4);
   379   }
   380   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) const {
   381     return (*(DoPeekImpl ())) (a1,a2,a3,a4,a5);
   382   }
   383   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6) const {
   384     return (*(DoPeekImpl ())) (a1,a2,a3,a4,a5,a6);
   385   }
   386 
   387   bool IsEqual (const CallbackBase &other) const {
   388     return m_impl->IsEqual (other.GetImpl ());
   389   }
   390 
   391   bool CheckType (const CallbackBase & other) const {
   392     return DoCheckType (other.GetImpl ());
   393   }
   394   void Assign (const CallbackBase &other) {
   395     DoAssign (other.GetImpl ());
   396   }
   397 private:
   398   CallbackImpl<R,T1,T2,T3,T4,T5,T6> *DoPeekImpl (void) const {
   399     return static_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (m_impl));
   400   }
   401   bool DoCheckType (Ptr<const CallbackImplBase> other) const {
   402     if (dynamic_cast<const CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (other)) != 0)
   403       {
   404         return true;
   405       }
   406     else
   407       {
   408         return false;
   409       }
   410   }
   411   void DoAssign (Ptr<const CallbackImplBase> other) {
   412     if (!DoCheckType (other))
   413       {
   414         NS_FATAL_ERROR ("Incompatible types. (feed to \"c++filt -t\")"
   415                         " got=" << typeid (*other).name () << 
   416                         ", expected=" << typeid (CallbackImpl<R,T1,T2,T3,T4,T5,T6> *).name ());
   417       }
   418     m_impl = const_cast<CallbackImplBase *> (PeekPointer (other));
   419   }
   420 };
   421 
   422 
   423 template <typename R, typename T1, typename T2,
   424           typename T3, typename T4,
   425           typename T5, typename T6>
   426 bool operator != (Callback<R,T1,T2,T3,T4,T5,T6> a, Callback<R,T1,T2,T3,T4,T5,T6> b)
   427 {
   428   return !a.IsEqual (b);
   429 }
   430 
   431 /**
   432  * \ingroup core
   433  * \defgroup MakeCallback MakeCallback
   434  *
   435  */
   436 
   437 /**
   438  * \ingroup MakeCallback
   439  * \param memPtr class method member pointer
   440  * \param objPtr class instance
   441  * \return a wrapper Callback
   442  * Build Callbacks for class method members which takes no arguments
   443  * and potentially return a value.
   444  */
   445 template <typename T, typename OBJ, typename R>
   446 Callback<R> MakeCallback (R (T::*memPtr) (void), OBJ objPtr) {
   447   return Callback<R> (objPtr, memPtr);
   448 }
   449 template <typename T, typename OBJ, typename R>
   450 Callback<R> MakeCallback (R (T::*mem_ptr) () const, OBJ objPtr) {
   451   return Callback<R> (objPtr, mem_ptr);
   452 }
   453 /**
   454  * \ingroup MakeCallback
   455  * \param mem_ptr class method member pointer
   456  * \param objPtr class instance
   457  * \return a wrapper Callback
   458  * Build Callbacks for class method members which takes one argument
   459  * and potentially return a value.
   460  */
   461 template <typename T, typename OBJ, typename R, typename T1>
   462 Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1), OBJ objPtr) {
   463   return Callback<R,T1> (objPtr, mem_ptr);
   464 }
   465 template <typename T, typename OBJ, typename R, typename T1>
   466 Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1) const, OBJ objPtr) {
   467   return Callback<R,T1> (objPtr, mem_ptr);
   468 }
   469 /**
   470  * \ingroup MakeCallback
   471  * \param mem_ptr class method member pointer
   472  * \param objPtr class instance
   473  * \return a wrapper Callback
   474  * Build Callbacks for class method members which takes two arguments
   475  * and potentially return a value.
   476  */
   477 template <typename T, typename OBJ, typename R, typename T1, typename T2>
   478 Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2), OBJ objPtr) {
   479   return Callback<R,T1,T2> (objPtr, mem_ptr);
   480 }
   481 template <typename T, typename OBJ, typename R, typename T1, typename T2>
   482 Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2) const, OBJ objPtr) {
   483   return Callback<R,T1,T2> (objPtr, mem_ptr);
   484 }
   485 /**
   486  * \ingroup MakeCallback
   487  * \param mem_ptr class method member pointer
   488  * \param objPtr class instance
   489  * \return a wrapper Callback
   490  * Build Callbacks for class method members which takes three arguments
   491  * and potentially return a value.
   492  */
   493 template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
   494 Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3), OBJ objPtr) {
   495   return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
   496 }
   497 template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
   498 Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3) const, OBJ objPtr) {
   499   return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
   500 }
   501 /**
   502  * \ingroup MakeCallback
   503  * \param mem_ptr class method member pointer
   504  * \param objPtr class instance
   505  * \return a wrapper Callback
   506  * Build Callbacks for class method members which takes four arguments
   507  * and potentially return a value.
   508  */
   509 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
   510 Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4), OBJ objPtr) {
   511   return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
   512 }
   513 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
   514 Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4) const, OBJ objPtr) {
   515   return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
   516 }
   517 /**
   518  * \ingroup MakeCallback
   519  * \param mem_ptr class method member pointer
   520  * \param objPtr class instance
   521  * \return a wrapper Callback
   522  * Build Callbacks for class method members which takes five arguments
   523  * and potentially return a value.
   524  */
   525 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   526 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ objPtr) {
   527   return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
   528 }
   529 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   530 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ objPtr) {
   531   return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
   532 }
   533 /**
   534  * \ingroup MakeCallback
   535  * \param mem_ptr class method member pointer
   536  * \param objPtr class instance
   537  * \return a wrapper Callback
   538  * Build Callbacks for class method members which takes five arguments
   539  * and potentially return a value.
   540  */
   541 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5,typename T6>
   542 Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6), OBJ objPtr) {
   543   return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
   544 }
   545 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
   546 Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6) const, OBJ objPtr) {
   547   return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
   548 }
   549 
   550 /**
   551  * \ingroup MakeCallback
   552  * \param fnPtr function pointer
   553  * \return a wrapper Callback
   554  * Build Callbacks for functions which takes no arguments
   555  * and potentially return a value.
   556  */
   557 template <typename R>
   558 Callback<R> MakeCallback (R (*fnPtr) ()) {
   559   return Callback<R> (fnPtr, true, true);
   560 }
   561 /**
   562  * \ingroup MakeCallback
   563  * \param fnPtr function pointer
   564  * \return a wrapper Callback
   565  * Build Callbacks for functions which takes one argument
   566  * and potentially return a value.
   567  */
   568 template <typename R, typename T1>
   569 Callback<R,T1> MakeCallback (R (*fnPtr) (T1)) {
   570   return Callback<R,T1> (fnPtr, true, true);
   571 }
   572 /**
   573  * \ingroup MakeCallback
   574  * \param fnPtr function pointer
   575  * \return a wrapper Callback
   576  * Build Callbacks for functions which takes two arguments
   577  * and potentially return a value.
   578  */
   579 template <typename R, typename T1, typename T2>
   580 Callback<R,T1,T2> MakeCallback (R (*fnPtr) (T1,T2)) {
   581   return Callback<R,T1,T2> (fnPtr, true, true);
   582 }
   583 /**
   584  * \ingroup MakeCallback
   585  * \param fnPtr function pointer
   586  * \return a wrapper Callback
   587  * Build Callbacks for functions which takes three arguments
   588  * and potentially return a value.
   589  */
   590 template <typename R, typename T1, typename T2,typename T3>
   591 Callback<R,T1,T2,T3> MakeCallback (R (*fnPtr) (T1,T2,T3)) {
   592   return Callback<R,T1,T2,T3> (fnPtr, true, true);
   593 }
   594 /**
   595  * \ingroup MakeCallback
   596  * \param fnPtr function pointer
   597  * \return a wrapper Callback
   598  * Build Callbacks for functions which takes four arguments
   599  * and potentially return a value.
   600  */
   601 template <typename R, typename T1, typename T2,typename T3,typename T4>
   602 Callback<R,T1,T2,T3,T4> MakeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
   603   return Callback<R,T1,T2,T3,T4> (fnPtr, true, true);
   604 }
   605 /**
   606  * \ingroup MakeCallback
   607  * \param fnPtr function pointer
   608  * \return a wrapper Callback
   609  * Build Callbacks for functions which takes five arguments
   610  * and potentially return a value.
   611  */
   612 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   613 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
   614   return Callback<R,T1,T2,T3,T4,T5> (fnPtr, true, true);
   615 }
   616 /**
   617  * \ingroup MakeCallback
   618  * \param fnPtr function pointer
   619  * \return a wrapper Callback
   620  * Build Callbacks for functions which takes five arguments
   621  * and potentially return a value.
   622  */
   623 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
   624 Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5,T6)) {
   625   return Callback<R,T1,T2,T3,T4,T5,T6> (fnPtr, true, true);
   626 }
   627 
   628 
   629 
   630 /**
   631  * \ingroup MakeCallback
   632  * \return a wrapper Callback
   633  * Build a null callback which takes no arguments
   634  * and potentially return a value.
   635  */
   636 template <typename R>
   637 Callback<R> MakeNullCallback (void) {
   638   return Callback<R> ();
   639 }
   640 /**
   641  * \ingroup MakeCallback
   642  * \overload Callback<R> MakeNullCallback (void)
   643  * \return a wrapper Callback
   644  * Build a null callback which takes one argument
   645  * and potentially return a value.
   646  */
   647 template <typename R, typename T1>
   648 Callback<R,T1> MakeNullCallback (void) {
   649   return Callback<R,T1> ();
   650 }
   651 /**
   652  * \ingroup MakeCallback
   653  * \overload Callback<R> MakeNullCallback (void)
   654  * \return a wrapper Callback
   655  * Build a null callback which takes two arguments
   656  * and potentially return a value.
   657  */
   658 template <typename R, typename T1, typename T2>
   659 Callback<R,T1,T2> MakeNullCallback (void) {
   660   return Callback<R,T1,T2> ();
   661 }
   662 /**
   663  * \ingroup MakeCallback
   664  * \overload Callback<R> MakeNullCallback (void)
   665  * \return a wrapper Callback
   666  * Build a null callback which takes three arguments
   667  * and potentially return a value.
   668  */
   669 template <typename R, typename T1, typename T2,typename T3>
   670 Callback<R,T1,T2,T3> MakeNullCallback (void) {
   671   return Callback<R,T1,T2,T3> ();
   672 }
   673 /**
   674  * \ingroup MakeCallback
   675  * \overload Callback<R> MakeNullCallback (void)
   676  * \return a wrapper Callback
   677  * Build a null callback which takes four arguments
   678  * and potentially return a value.
   679  */
   680 template <typename R, typename T1, typename T2,typename T3,typename T4>
   681 Callback<R,T1,T2,T3,T4> MakeNullCallback (void) {
   682   return Callback<R,T1,T2,T3,T4> ();
   683 }
   684 /**
   685  * \ingroup MakeCallback
   686  * \overload Callback<R> MakeNullCallback (void)
   687  * \return a wrapper Callback
   688  * Build a null callback which takes five arguments
   689  * and potentially return a value.
   690  */
   691 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   692 Callback<R,T1,T2,T3,T4,T5> MakeNullCallback (void) {
   693   return Callback<R,T1,T2,T3,T4,T5> ();
   694 }
   695 /**
   696  * \ingroup MakeCallback
   697  * \overload Callback<R> MakeNullCallback (void)
   698  * \return a wrapper Callback
   699  * Build a null callback which takes five arguments
   700  * and potentially return a value.
   701  */
   702 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
   703 Callback<R,T1,T2,T3,T4,T5,T6> MakeNullCallback (void) {
   704   return Callback<R,T1,T2,T3,T4,T5,T6> ();
   705 }
   706 
   707 
   708 /*
   709  * The following is experimental code. It works but we have
   710  * not yet determined whether or not it is really useful and whether
   711  * or not we really want to use it.
   712  */
   713 
   714 template <typename R, typename TX, typename ARG>
   715 Callback<R> MakeBoundCallback (R (*fnPtr) (TX), ARG a) {
   716   Ptr<CallbackImpl<R,empty,empty,empty,empty,empty,empty> > impl =
   717     Create<BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> >(fnPtr, a);
   718   return Callback<R> (impl);
   719 }
   720 
   721 template <typename R, typename TX, typename ARG, 
   722           typename T1>
   723 Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), ARG a) {
   724   Ptr<CallbackImpl<R,T1,empty,empty,empty,empty,empty> > impl =
   725     Create<BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> > (fnPtr, a);
   726   return Callback<R,T1> (impl);
   727 }
   728 template <typename R, typename TX, typename ARG, 
   729           typename T1, typename T2>
   730 Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), ARG a) {
   731   Ptr<CallbackImpl<R,T1,T2,empty,empty,empty,empty> > impl =
   732     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> > (fnPtr, a);
   733   return Callback<R,T1,T2> (impl);
   734 }
   735 template <typename R, typename TX, typename ARG,
   736           typename T1, typename T2,typename T3>
   737 Callback<R,T1,T2,T3> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3), ARG a) {
   738   Ptr<CallbackImpl<R,T1,T2,T3,empty,empty,empty> > impl =
   739     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3),R,TX,T1,T2,T3,empty,empty> > (fnPtr, a);
   740   return Callback<R,T1,T2,T3> (impl);
   741 }
   742 template <typename R, typename TX, typename ARG,
   743           typename T1, typename T2,typename T3,typename T4>
   744 Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), ARG a) {
   745   Ptr<CallbackImpl<R,T1,T2,T3,T4,empty,empty> > impl =
   746     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> > (fnPtr, a);
   747   return Callback<R,T1,T2,T3,T4> (impl);
   748 }
   749 template <typename R, typename TX, typename ARG,
   750           typename T1, typename T2,typename T3,typename T4,typename T5>
   751 Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), ARG a) {
   752   Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,empty> > impl =
   753     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a);
   754   return Callback<R,T1,T2,T3,T4,T5> (impl);
   755 }
   756 
   757 
   758 }; // namespace ns3
   759 
   760 
   761 #endif /* CALLBACK_H */