src/core/callback.h
changeset 150 663120712cd9
parent 131 f4fb87e77034
child 219 4133c374ea0c
equal deleted inserted replaced
149:d5b12472c5e2 150:663120712cd9
     1 /* -*- Mode:NS3; -*- */
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     2 /*
     3  * Copyright (c) 2005,2006 INRIA
     3  * Copyright (c) 2005,2006 INRIA
     4  * All rights reserved.
     4  * All rights reserved.
     5  *
     5  *
     6  * This program is free software; you can redistribute it and/or modify
     6  * This program is free software; you can redistribute it and/or modify
    62 class CallbackImpl;
    62 class CallbackImpl;
    63 // define CallbackImpl for 0 params
    63 // define CallbackImpl for 0 params
    64 template <typename R>
    64 template <typename R>
    65 class CallbackImpl<R,empty,empty,empty,empty,empty> {
    65 class CallbackImpl<R,empty,empty,empty,empty,empty> {
    66 public:
    66 public:
    67     virtual ~CallbackImpl () {}
    67   virtual ~CallbackImpl () {}
    68     virtual R operator() (void) = 0;
    68   virtual R operator() (void) = 0;
    69 };
    69 };
    70 // define CallbackImpl for 1 params
    70 // define CallbackImpl for 1 params
    71 template <typename R, typename T1>
    71 template <typename R, typename T1>
    72 class CallbackImpl<R,T1,empty,empty,empty,empty> {
    72 class CallbackImpl<R,T1,empty,empty,empty,empty> {
    73 public:
    73 public:
    74     virtual ~CallbackImpl () {}
    74   virtual ~CallbackImpl () {}
    75     virtual R operator() (T1) = 0;
    75   virtual R operator() (T1) = 0;
    76 };
    76 };
    77 // define CallbackImpl for 2 params
    77 // define CallbackImpl for 2 params
    78 template <typename R, typename T1, typename T2>
    78 template <typename R, typename T1, typename T2>
    79 class CallbackImpl<R,T1,T2,empty,empty,empty> {
    79 class CallbackImpl<R,T1,T2,empty,empty,empty> {
    80 public:
    80 public:
    81     virtual ~CallbackImpl () {}
    81   virtual ~CallbackImpl () {}
    82     virtual R operator() (T1, T2) = 0;
    82   virtual R operator() (T1, T2) = 0;
    83 };
    83 };
    84 // define CallbackImpl for 3 params
    84 // define CallbackImpl for 3 params
    85 template <typename R, typename T1, typename T2, typename T3>
    85 template <typename R, typename T1, typename T2, typename T3>
    86 class CallbackImpl<R,T1,T2,T3,empty,empty> {
    86 class CallbackImpl<R,T1,T2,T3,empty,empty> {
    87 public:
    87 public:
    88     virtual ~CallbackImpl () {}
    88   virtual ~CallbackImpl () {}
    89     virtual R operator() (T1, T2, T3) = 0;
    89   virtual R operator() (T1, T2, T3) = 0;
    90 };
    90 };
    91 // define CallbackImpl for 4 params
    91 // define CallbackImpl for 4 params
    92 template <typename R, typename T1, typename T2, typename T3, typename T4>
    92 template <typename R, typename T1, typename T2, typename T3, typename T4>
    93 class CallbackImpl<R,T1,T2,T3,T4,empty> {
    93 class CallbackImpl<R,T1,T2,T3,T4,empty> {
    94 public:
    94 public:
    95     virtual ~CallbackImpl () {}
    95   virtual ~CallbackImpl () {}
    96     virtual R operator() (T1, T2, T3, T4) = 0;
    96   virtual R operator() (T1, T2, T3, T4) = 0;
    97 };
    97 };
    98 // define CallbackImpl for 5 params
    98 // define CallbackImpl for 5 params
    99 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
    99 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
   100 class CallbackImpl {
   100 class CallbackImpl {
   101 public:
   101 public:
   102     virtual ~CallbackImpl () {}
   102   virtual ~CallbackImpl () {}
   103     virtual R operator() (T1, T2, T3, T4, T5) = 0;
   103   virtual R operator() (T1, T2, T3, T4, T5) = 0;
   104 };
   104 };
   105 
   105 
   106 
   106 
   107 // an impl for Functors:
   107 // an impl for Functors:
   108 template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   108 template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   109 class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
   109 class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
   110 public:
   110 public:
   111     FunctorCallbackImpl (T const &functor)
   111   FunctorCallbackImpl (T const &functor)
   112         : m_functor (functor) {}
   112       : m_functor (functor) {}
   113     virtual ~FunctorCallbackImpl () {}
   113   virtual ~FunctorCallbackImpl () {}
   114     R operator() (void) {
   114   R operator() (void) {
   115         return m_functor ();
   115       return m_functor ();
   116     }
   116   }
   117     R operator() (T1 a1) {
   117   R operator() (T1 a1) {
   118         return m_functor (a1);
   118       return m_functor (a1);
   119     }
   119   }
   120     R operator() (T1 a1,T2 a2) {
   120   R operator() (T1 a1,T2 a2) {
   121         return m_functor (a1,a2);
   121       return m_functor (a1,a2);
   122     }
   122   }
   123     R operator() (T1 a1,T2 a2,T3 a3) {
   123   R operator() (T1 a1,T2 a2,T3 a3) {
   124         return m_functor (a1,a2,a3);
   124       return m_functor (a1,a2,a3);
   125     }
   125   }
   126     R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   126   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   127         return m_functor (a1,a2,a3,a4);
   127       return m_functor (a1,a2,a3,a4);
   128     }
   128   }
   129     R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   129   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   130         return m_functor (a1,a2,a3,a4,a5);
   130       return m_functor (a1,a2,a3,a4,a5);
   131     }
   131   }
   132 private:
   132 private:
   133     T m_functor;
   133   T m_functor;
   134 };
   134 };
   135 
   135 
   136 // an impl for pointer to member functions
   136 // an impl for pointer to member functions
   137 template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
   137 template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
   138 class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
   138 class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
   139 public:
   139 public:
   140     MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
   140   MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
   141         : m_objPtr (objPtr), m_memPtr (mem_ptr) {}
   141       : m_objPtr (objPtr), m_memPtr (mem_ptr) {}
   142     virtual ~MemPtrCallbackImpl () {}
   142   virtual ~MemPtrCallbackImpl () {}
   143     R operator() (void) {
   143   R operator() (void) {
   144         return ((*m_objPtr).*m_memPtr) ();
   144       return ((*m_objPtr).*m_memPtr) ();
   145     }
   145   }
   146     R operator() (T1 a1) {
   146   R operator() (T1 a1) {
   147         return ((*m_objPtr).*m_memPtr) (a1);
   147       return ((*m_objPtr).*m_memPtr) (a1);
   148     }
   148   }
   149     R operator() (T1 a1,T2 a2) {
   149   R operator() (T1 a1,T2 a2) {
   150         return ((*m_objPtr).*m_memPtr) (a1,a2);
   150       return ((*m_objPtr).*m_memPtr) (a1,a2);
   151     }
   151   }
   152     R operator() (T1 a1,T2 a2,T3 a3) {
   152   R operator() (T1 a1,T2 a2,T3 a3) {
   153         return ((*m_objPtr).*m_memPtr) (a1,a2,a3);
   153       return ((*m_objPtr).*m_memPtr) (a1,a2,a3);
   154     }
   154   }
   155     R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   155   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   156         return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4);
   156       return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4);
   157     }
   157   }
   158     R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   158   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   159         return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4,a5);
   159       return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4,a5);
   160     }
   160   }
   161 private:
   161 private:
   162     OBJ_PTR const m_objPtr;
   162   OBJ_PTR const m_objPtr;
   163     MEM_PTR m_memPtr;
   163   MEM_PTR m_memPtr;
   164 };
   164 };
   165 
   165 
   166 /**
   166 /**
   167  * \brief Callback template class
   167  * \brief Callback template class
   168  *
   168  *
   190  * Sample code which shows how to use this class template 
   190  * Sample code which shows how to use this class template 
   191  * as well as the function templates \ref MakeCallback :
   191  * as well as the function templates \ref MakeCallback :
   192  * \include samples/main-callback.cc
   192  * \include samples/main-callback.cc
   193  */
   193  */
   194 template<typename R, 
   194 template<typename R, 
   195      typename T1 = empty, typename T2 = empty, 
   195    typename T1 = empty, typename T2 = empty, 
   196      typename T3 = empty, typename T4 = empty,
   196    typename T3 = empty, typename T4 = empty,
   197      typename T5 = empty>
   197    typename T5 = empty>
   198 class Callback {
   198 class Callback {
   199 public:
   199 public:
   200     template <typename FUNCTOR>
   200   template <typename FUNCTOR>
   201     Callback (FUNCTOR const &functor) 
   201   Callback (FUNCTOR const &functor) 
   202         : m_impl (new FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> (functor))
   202       : m_impl (new FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> (functor))
   203     {}
   203   {}
   204 
   204 
   205     template <typename OBJ_PTR, typename MEM_PTR>
   205   template <typename OBJ_PTR, typename MEM_PTR>
   206     Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
   206   Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
   207         : m_impl (new MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> (objPtr, mem_ptr))
   207       : m_impl (new MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> (objPtr, mem_ptr))
   208     {}
   208   {}
   209 
   209 
   210     Callback (ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5> *> const &impl)
   210   Callback (ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5> *> const &impl)
   211         : m_impl (impl)
   211       : m_impl (impl)
   212     {}
   212   {}
   213 
   213 
   214     bool IsNull (void) {
   214   bool IsNull (void) {
   215         return (m_impl.Get () == 0)?true:false;
   215       return (m_impl.Get () == 0)?true:false;
   216     }
   216   }
   217 
   217 
   218     Callback () : m_impl () {}
   218   Callback () : m_impl () {}
   219     R operator() (void) {
   219   R operator() (void) {
   220         return (*(m_impl.Get ())) ();
   220       return (*(m_impl.Get ())) ();
   221     }
   221   }
   222     R operator() (T1 a1) {
   222   R operator() (T1 a1) {
   223         return (*(m_impl.Get ())) (a1);
   223       return (*(m_impl.Get ())) (a1);
   224     }
   224   }
   225     R operator() (T1 a1, T2 a2) {
   225   R operator() (T1 a1, T2 a2) {
   226         return (*(m_impl).Get ()) (a1,a2);
   226       return (*(m_impl).Get ()) (a1,a2);
   227     }
   227   }
   228     R operator() (T1 a1, T2 a2, T3 a3) {
   228   R operator() (T1 a1, T2 a2, T3 a3) {
   229         return (*(m_impl).Get ()) (a1,a2,a3);
   229       return (*(m_impl).Get ()) (a1,a2,a3);
   230     }
   230   }
   231     R operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
   231   R operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
   232         return (*(m_impl).Get ()) (a1,a2,a3,a4);
   232       return (*(m_impl).Get ()) (a1,a2,a3,a4);
   233     }
   233   }
   234     R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
   234   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
   235         return (*(m_impl).Get ()) (a1,a2,a3,a4,a5);
   235       return (*(m_impl).Get ()) (a1,a2,a3,a4,a5);
   236     }
   236   }
   237 private:
   237 private:
   238     ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> m_impl;
   238   ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> m_impl;
   239 };
   239 };
   240 
   240 
   241 /**
   241 /**
   242  * \defgroup MakeCallback MakeCallback
   242  * \defgroup MakeCallback MakeCallback
   243  *
   243  *
   251  * Build Callbacks for class method members which takes no arguments
   251  * Build Callbacks for class method members which takes no arguments
   252  * and potentially return a value.
   252  * and potentially return a value.
   253  */
   253  */
   254 template <typename OBJ, typename R>
   254 template <typename OBJ, typename R>
   255 Callback<R> MakeCallback (R (OBJ::*mem_ptr) (), OBJ *const objPtr) {
   255 Callback<R> MakeCallback (R (OBJ::*mem_ptr) (), OBJ *const objPtr) {
   256     return Callback<R> (objPtr, mem_ptr);
   256   return Callback<R> (objPtr, mem_ptr);
   257 }
   257 }
   258 /**
   258 /**
   259  * \ingroup MakeCallback
   259  * \ingroup MakeCallback
   260  * \param mem_ptr class method member pointer
   260  * \param mem_ptr class method member pointer
   261  * \param objPtr class instance
   261  * \param objPtr class instance
   263  * Build Callbacks for class method members which takes one argument
   263  * Build Callbacks for class method members which takes one argument
   264  * and potentially return a value.
   264  * and potentially return a value.
   265  */
   265  */
   266 template <typename OBJ, typename R, typename T1>
   266 template <typename OBJ, typename R, typename T1>
   267 Callback<R,T1> MakeCallback (R (OBJ::*mem_ptr) (T1), OBJ *const objPtr) {
   267 Callback<R,T1> MakeCallback (R (OBJ::*mem_ptr) (T1), OBJ *const objPtr) {
   268     return Callback<R,T1> (objPtr, mem_ptr);
   268   return Callback<R,T1> (objPtr, mem_ptr);
   269 }
   269 }
   270 /**
   270 /**
   271  * \ingroup MakeCallback
   271  * \ingroup MakeCallback
   272  * \param mem_ptr class method member pointer
   272  * \param mem_ptr class method member pointer
   273  * \param objPtr class instance
   273  * \param objPtr class instance
   275  * Build Callbacks for class method members which takes two arguments
   275  * Build Callbacks for class method members which takes two arguments
   276  * and potentially return a value.
   276  * and potentially return a value.
   277  */
   277  */
   278 template <typename OBJ, typename R, typename T1, typename T2>
   278 template <typename OBJ, typename R, typename T1, typename T2>
   279 Callback<R,T1,T2> MakeCallback (R (OBJ::*mem_ptr) (T1,T2), OBJ *const objPtr) {
   279 Callback<R,T1,T2> MakeCallback (R (OBJ::*mem_ptr) (T1,T2), OBJ *const objPtr) {
   280     return Callback<R,T1,T2> (objPtr, mem_ptr);
   280   return Callback<R,T1,T2> (objPtr, mem_ptr);
   281 }
   281 }
   282 /**
   282 /**
   283  * \ingroup MakeCallback
   283  * \ingroup MakeCallback
   284  * \param mem_ptr class method member pointer
   284  * \param mem_ptr class method member pointer
   285  * \param objPtr class instance
   285  * \param objPtr class instance
   287  * Build Callbacks for class method members which takes three arguments
   287  * Build Callbacks for class method members which takes three arguments
   288  * and potentially return a value.
   288  * and potentially return a value.
   289  */
   289  */
   290 template <typename OBJ, typename R, typename T1,typename T2, typename T3>
   290 template <typename OBJ, typename R, typename T1,typename T2, typename T3>
   291 Callback<R,T1,T2,T3> MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3), OBJ *const objPtr) {
   291 Callback<R,T1,T2,T3> MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3), OBJ *const objPtr) {
   292     return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
   292   return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
   293 }
   293 }
   294 /**
   294 /**
   295  * \ingroup MakeCallback
   295  * \ingroup MakeCallback
   296  * \param mem_ptr class method member pointer
   296  * \param mem_ptr class method member pointer
   297  * \param objPtr class instance
   297  * \param objPtr class instance
   299  * Build Callbacks for class method members which takes four arguments
   299  * Build Callbacks for class method members which takes four arguments
   300  * and potentially return a value.
   300  * and potentially return a value.
   301  */
   301  */
   302 template <typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
   302 template <typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
   303 Callback<R,T1,T2,T3,T4> MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4), OBJ *const objPtr) {
   303 Callback<R,T1,T2,T3,T4> MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4), OBJ *const objPtr) {
   304     return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
   304   return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
   305 }
   305 }
   306 /**
   306 /**
   307  * \ingroup MakeCallback
   307  * \ingroup MakeCallback
   308  * \param mem_ptr class method member pointer
   308  * \param mem_ptr class method member pointer
   309  * \param objPtr class instance
   309  * \param objPtr class instance
   311  * Build Callbacks for class method members which takes five arguments
   311  * Build Callbacks for class method members which takes five arguments
   312  * and potentially return a value.
   312  * and potentially return a value.
   313  */
   313  */
   314 template <typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   314 template <typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   315 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4,T5), OBJ *const objPtr) {
   315 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4,T5), OBJ *const objPtr) {
   316     return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
   316   return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
   317 }
   317 }
   318 
   318 
   319 /**
   319 /**
   320  * \ingroup MakeCallback
   320  * \ingroup MakeCallback
   321  * \param fnPtr function pointer
   321  * \param fnPtr function pointer
   323  * Build Callbacks for functions which takes no arguments
   323  * Build Callbacks for functions which takes no arguments
   324  * and potentially return a value.
   324  * and potentially return a value.
   325  */
   325  */
   326 template <typename R>
   326 template <typename R>
   327 Callback<R> MakeCallback (R (*fnPtr) ()) {
   327 Callback<R> MakeCallback (R (*fnPtr) ()) {
   328     return Callback<R> (fnPtr);
   328   return Callback<R> (fnPtr);
   329 }
   329 }
   330 /**
   330 /**
   331  * \ingroup MakeCallback
   331  * \ingroup MakeCallback
   332  * \param fnPtr function pointer
   332  * \param fnPtr function pointer
   333  * \return a wrapper Callback
   333  * \return a wrapper Callback
   334  * Build Callbacks for functions which takes one argument
   334  * Build Callbacks for functions which takes one argument
   335  * and potentially return a value.
   335  * and potentially return a value.
   336  */
   336  */
   337 template <typename R, typename T1>
   337 template <typename R, typename T1>
   338 Callback<R,T1> MakeCallback (R (*fnPtr) (T1)) {
   338 Callback<R,T1> MakeCallback (R (*fnPtr) (T1)) {
   339     return Callback<R,T1> (fnPtr);
   339   return Callback<R,T1> (fnPtr);
   340 }
   340 }
   341 /**
   341 /**
   342  * \ingroup MakeCallback
   342  * \ingroup MakeCallback
   343  * \param fnPtr function pointer
   343  * \param fnPtr function pointer
   344  * \return a wrapper Callback
   344  * \return a wrapper Callback
   345  * Build Callbacks for functions which takes two arguments
   345  * Build Callbacks for functions which takes two arguments
   346  * and potentially return a value.
   346  * and potentially return a value.
   347  */
   347  */
   348 template <typename R, typename T1, typename T2>
   348 template <typename R, typename T1, typename T2>
   349 Callback<R,T1,T2> MakeCallback (R (*fnPtr) (T1,T2)) {
   349 Callback<R,T1,T2> MakeCallback (R (*fnPtr) (T1,T2)) {
   350     return Callback<R,T1,T2> (fnPtr);
   350   return Callback<R,T1,T2> (fnPtr);
   351 }
   351 }
   352 /**
   352 /**
   353  * \ingroup MakeCallback
   353  * \ingroup MakeCallback
   354  * \param fnPtr function pointer
   354  * \param fnPtr function pointer
   355  * \return a wrapper Callback
   355  * \return a wrapper Callback
   356  * Build Callbacks for functions which takes three arguments
   356  * Build Callbacks for functions which takes three arguments
   357  * and potentially return a value.
   357  * and potentially return a value.
   358  */
   358  */
   359 template <typename R, typename T1, typename T2,typename T3>
   359 template <typename R, typename T1, typename T2,typename T3>
   360 Callback<R,T1,T2,T3> MakeCallback (R (*fnPtr) (T1,T2,T3)) {
   360 Callback<R,T1,T2,T3> MakeCallback (R (*fnPtr) (T1,T2,T3)) {
   361     return Callback<R,T1,T2,T3> (fnPtr);
   361   return Callback<R,T1,T2,T3> (fnPtr);
   362 }
   362 }
   363 /**
   363 /**
   364  * \ingroup MakeCallback
   364  * \ingroup MakeCallback
   365  * \param fnPtr function pointer
   365  * \param fnPtr function pointer
   366  * \return a wrapper Callback
   366  * \return a wrapper Callback
   367  * Build Callbacks for functions which takes four arguments
   367  * Build Callbacks for functions which takes four arguments
   368  * and potentially return a value.
   368  * and potentially return a value.
   369  */
   369  */
   370 template <typename R, typename T1, typename T2,typename T3,typename T4>
   370 template <typename R, typename T1, typename T2,typename T3,typename T4>
   371 Callback<R,T1,T2,T3,T4> MakeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
   371 Callback<R,T1,T2,T3,T4> MakeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
   372     return Callback<R,T1,T2,T3,T4> (fnPtr);
   372   return Callback<R,T1,T2,T3,T4> (fnPtr);
   373 }
   373 }
   374 /**
   374 /**
   375  * \ingroup MakeCallback
   375  * \ingroup MakeCallback
   376  * \param fnPtr function pointer
   376  * \param fnPtr function pointer
   377  * \return a wrapper Callback
   377  * \return a wrapper Callback
   378  * Build Callbacks for functions which takes five arguments
   378  * Build Callbacks for functions which takes five arguments
   379  * and potentially return a value.
   379  * and potentially return a value.
   380  */
   380  */
   381 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   381 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   382 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
   382 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
   383     return Callback<R,T1,T2,T3,T4,T5> (fnPtr);
   383   return Callback<R,T1,T2,T3,T4,T5> (fnPtr);
   384 }
   384 }
   385 
   385 
   386 
   386 
   387 
   387 
   388 /**
   388 /**
   391  * Build a null callback which takes no arguments
   391  * Build a null callback which takes no arguments
   392  * and potentially return a value.
   392  * and potentially return a value.
   393  */
   393  */
   394 template <typename R>
   394 template <typename R>
   395 Callback<R> MakeNullCallback (void) {
   395 Callback<R> MakeNullCallback (void) {
   396     return Callback<R> ();
   396   return Callback<R> ();
   397 }
   397 }
   398 /**
   398 /**
   399  * \ingroup MakeCallback
   399  * \ingroup MakeCallback
   400  * \return a wrapper Callback
   400  * \return a wrapper Callback
   401  * Build a null callback which takes one argument
   401  * Build a null callback which takes one argument
   402  * and potentially return a value.
   402  * and potentially return a value.
   403  */
   403  */
   404 template <typename R, typename T1>
   404 template <typename R, typename T1>
   405 Callback<R,T1> MakeNullCallback (void) {
   405 Callback<R,T1> MakeNullCallback (void) {
   406     return Callback<R,T1> ();
   406   return Callback<R,T1> ();
   407 }
   407 }
   408 /**
   408 /**
   409  * \ingroup MakeCallback
   409  * \ingroup MakeCallback
   410  * \return a wrapper Callback
   410  * \return a wrapper Callback
   411  * Build a null callback which takes two arguments
   411  * Build a null callback which takes two arguments
   412  * and potentially return a value.
   412  * and potentially return a value.
   413  */
   413  */
   414 template <typename R, typename T1, typename T2>
   414 template <typename R, typename T1, typename T2>
   415 Callback<R,T1,T2> MakeNullCallback (void) {
   415 Callback<R,T1,T2> MakeNullCallback (void) {
   416     return Callback<R,T1,T2> ();
   416   return Callback<R,T1,T2> ();
   417 }
   417 }
   418 /**
   418 /**
   419  * \ingroup MakeCallback
   419  * \ingroup MakeCallback
   420  * \return a wrapper Callback
   420  * \return a wrapper Callback
   421  * Build a null callback which takes three arguments
   421  * Build a null callback which takes three arguments
   422  * and potentially return a value.
   422  * and potentially return a value.
   423  */
   423  */
   424 template <typename R, typename T1, typename T2,typename T3>
   424 template <typename R, typename T1, typename T2,typename T3>
   425 Callback<R,T1,T2,T3> MakeNullCallback (void) {
   425 Callback<R,T1,T2,T3> MakeNullCallback (void) {
   426     return Callback<R,T1,T2,T3> ();
   426   return Callback<R,T1,T2,T3> ();
   427 }
   427 }
   428 /**
   428 /**
   429  * \ingroup MakeCallback
   429  * \ingroup MakeCallback
   430  * \return a wrapper Callback
   430  * \return a wrapper Callback
   431  * Build a null callback which takes four arguments
   431  * Build a null callback which takes four arguments
   432  * and potentially return a value.
   432  * and potentially return a value.
   433  */
   433  */
   434 template <typename R, typename T1, typename T2,typename T3,typename T4>
   434 template <typename R, typename T1, typename T2,typename T3,typename T4>
   435 Callback<R,T1,T2,T3,T4> MakeNullCallback (void) {
   435 Callback<R,T1,T2,T3,T4> MakeNullCallback (void) {
   436     return Callback<R,T1,T2,T3,T4> ();
   436   return Callback<R,T1,T2,T3,T4> ();
   437 }
   437 }
   438 /**
   438 /**
   439  * \ingroup MakeCallback
   439  * \ingroup MakeCallback
   440  * \return a wrapper Callback
   440  * \return a wrapper Callback
   441  * Build a null callback which takes five arguments
   441  * Build a null callback which takes five arguments
   442  * and potentially return a value.
   442  * and potentially return a value.
   443  */
   443  */
   444 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   444 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   445 Callback<R,T1,T2,T3,T4,T5> MakeNullCallback (void) {
   445 Callback<R,T1,T2,T3,T4,T5> MakeNullCallback (void) {
   446     return Callback<R,T1,T2,T3,T4,T5> ();
   446   return Callback<R,T1,T2,T3,T4,T5> ();
   447 }
   447 }
   448 
   448 
   449 
   449 
   450 /**
   450 /**
   451  * The following is experimental code. It works but we have
   451  * The following is experimental code. It works but we have
   454  */
   454  */
   455 // an impl for Bound Functors:
   455 // an impl for Bound Functors:
   456 template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5>
   456 template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5>
   457 class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
   457 class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5> {
   458 public:
   458 public:
   459     BoundFunctorCallbackImpl (T const &functor, TX a)
   459   BoundFunctorCallbackImpl (T const &functor, TX a)
   460         : m_functor (functor), m_a (a) {}
   460       : m_functor (functor), m_a (a) {}
   461     virtual ~BoundFunctorCallbackImpl () {}
   461   virtual ~BoundFunctorCallbackImpl () {}
   462     R operator() (void) {
   462   R operator() (void) {
   463         return m_functor (m_a);
   463       return m_functor (m_a);
   464     }
   464   }
   465     R operator() (T1 a1) {
   465   R operator() (T1 a1) {
   466         return m_functor (m_a,a1);
   466       return m_functor (m_a,a1);
   467     }
   467   }
   468     R operator() (T1 a1,T2 a2) {
   468   R operator() (T1 a1,T2 a2) {
   469         return m_functor (m_a,a1,a2);
   469       return m_functor (m_a,a1,a2);
   470     }
   470   }
   471     R operator() (T1 a1,T2 a2,T3 a3) {
   471   R operator() (T1 a1,T2 a2,T3 a3) {
   472         return m_functor (m_a,a1,a2,a3);
   472       return m_functor (m_a,a1,a2,a3);
   473     }
   473   }
   474     R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   474   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   475         return m_functor (m_a,a1,a2,a3,a4);
   475       return m_functor (m_a,a1,a2,a3,a4);
   476     }
   476   }
   477     R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   477   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   478         return m_functor (m_a,a1,a2,a3,a4,a5);
   478       return m_functor (m_a,a1,a2,a3,a4,a5);
   479     }
   479   }
   480 private:
   480 private:
   481     T m_functor;
   481   T m_functor;
   482     TX m_a;
   482   TX m_a;
   483 };
   483 };
   484 
   484 
   485 template <typename R, typename TX, typename T1>
   485 template <typename R, typename TX, typename T1>
   486 Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), TX a) {
   486 Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), TX a) {
   487     ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> impl =
   487   ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> impl =
   488     ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> (
   488   ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> (
   489     new BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> (fnPtr, a)
   489   new BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> (fnPtr, a)
   490     );
   490   );
   491     return Callback<R,T1> (impl);
   491   return Callback<R,T1> (impl);
   492 }
   492 }
   493 template <typename R, typename TX, typename T1, typename T2>
   493 template <typename R, typename TX, typename T1, typename T2>
   494 Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), TX a) {
   494 Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), TX a) {
   495     ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> impl =
   495   ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> impl =
   496     ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> (
   496   ReferenceList<CallbackImpl<R,T1,T2,empty,empty,empty>*> (
   497     new BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> (fnPtr, a)
   497   new BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> (fnPtr, a)
   498     );
   498   );
   499     return Callback<R,T1,T2> (impl);
   499   return Callback<R,T1,T2> (impl);
   500 }
   500 }
   501 template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4>
   501 template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4>
   502 Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), TX a) {
   502 Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), TX a) {
   503     ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> impl =
   503   ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> impl =
   504     ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> (
   504   ReferenceList<CallbackImpl<R,T1,T2,T3,T4,empty>*> (
   505     new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> (fnPtr, a)
   505   new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> (fnPtr, a)
   506     );
   506   );
   507     return Callback<R,T1,T2,T3,T4> (impl);
   507   return Callback<R,T1,T2,T3,T4> (impl);
   508 }
   508 }
   509 
   509 
   510 template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4,typename T5>
   510 template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4,typename T5>
   511 Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), TX a) {
   511 Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), TX a) {
   512     ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> impl =
   512   ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> impl =
   513     ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> (
   513   ReferenceList<CallbackImpl<R,T1,T2,T3,T4,T5>*> (
   514     new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> (fnPtr, a)
   514   new BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> (fnPtr, a)
   515     );
   515   );
   516     return Callback<R,T1,T2,T3,T4,T5> (impl);
   516   return Callback<R,T1,T2,T3,T4,T5> (impl);
   517 }
   517 }
   518 
   518 
   519 
   519 
   520 }; // namespace ns3
   520 }; // namespace ns3
   521 
   521