src/core/callback.h
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 4072 5d226c752e85
permissions -rw-r--r--
Added tag ns-3.5 for changeset c975274c9707
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2005,2006 INRIA
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    19  */
    20 
    21 #ifndef CALLBACK_H
    22 #define CALLBACK_H
    23 
    24 #include "ptr.h"
    25 #include "fatal-error.h"
    26 #include "empty.h"
    27 #include "type-traits.h"
    28 #include "attribute.h"
    29 #include "attribute-helper.h"
    30 #include <typeinfo>
    31 
    32 namespace ns3 {
    33 
    34 /***
    35  * \internal
    36  * This code was originally written based on the techniques 
    37  * described in http://www.codeproject.com/cpp/TTLFunction.asp
    38  * It was subsequently rewritten to follow the architecture
    39  * outlined in "Modern C++ Design" by Andrei Alexandrescu in 
    40  * chapter 5, "Generalized Functors".
    41  *
    42  * This code uses:
    43  *   - default template parameters to saves users from having to
    44  *     specify empty parameters when the number of parameters
    45  *     is smaller than the maximum supported number
    46  *   - the pimpl idiom: the Callback class is passed around by 
    47  *     value and delegates the crux of the work to its pimpl
    48  *     pointer.
    49  *   - two pimpl implementations which derive from CallbackImpl
    50  *     FunctorCallbackImpl can be used with any functor-type
    51  *     while MemPtrCallbackImpl can be used with pointers to
    52  *     member functions.
    53  *   - a reference list implementation to implement the Callback's
    54  *     value semantics.
    55  *
    56  * This code most notably departs from the alexandrescu 
    57  * implementation in that it does not use type lists to specify
    58  * and pass around the types of the callback arguments.
    59  * Of course, it also does not use copy-destruction semantics
    60  * and relies on a reference list rather than autoPtr to hold
    61  * the pointer.
    62  */
    63 template <typename T>
    64 struct CallbackTraits;
    65 
    66 template <typename T>
    67 struct CallbackTraits<T *>
    68 {
    69   static T & GetReference (T * const p)
    70   {
    71     return *p;
    72   }
    73 };
    74 
    75 class CallbackImplBase
    76 {
    77 public:
    78   CallbackImplBase ()
    79     : m_count (1) {}
    80   virtual ~CallbackImplBase () {}
    81   void Ref (void) const {
    82     m_count++;
    83   }
    84   void Unref (void) const {
    85     m_count--;
    86     if (m_count == 0) {
    87       delete this;
    88     }
    89   }
    90   uint32_t GetReferenceCount (void) const { return m_count; }
    91   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const = 0;
    92 private:
    93   mutable uint32_t m_count;
    94 };
    95 
    96 // declare the CallbackImpl class
    97 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
    98 class CallbackImpl;
    99 // define CallbackImpl for 0 params
   100 template <typename R>
   101 class CallbackImpl<R,empty,empty,empty,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
   102 public:
   103   virtual ~CallbackImpl () {}
   104   virtual R operator() (void) = 0;
   105 };
   106 // define CallbackImpl for 1 params
   107 template <typename R, typename T1>
   108 class CallbackImpl<R,T1,empty,empty,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
   109 public:
   110   virtual ~CallbackImpl () {}
   111   virtual R operator() (T1) = 0;
   112 };
   113 // define CallbackImpl for 2 params
   114 template <typename R, typename T1, typename T2>
   115 class CallbackImpl<R,T1,T2,empty,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
   116 public:
   117   virtual ~CallbackImpl () {}
   118   virtual R operator() (T1, T2) = 0;
   119 };
   120 // define CallbackImpl for 3 params
   121 template <typename R, typename T1, typename T2, typename T3>
   122 class CallbackImpl<R,T1,T2,T3,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
   123 public:
   124   virtual ~CallbackImpl () {}
   125   virtual R operator() (T1, T2, T3) = 0;
   126 };
   127 // define CallbackImpl for 4 params
   128 template <typename R, typename T1, typename T2, typename T3, typename T4>
   129 class CallbackImpl<R,T1,T2,T3,T4,empty,empty,empty,empty,empty> : public CallbackImplBase {
   130 public:
   131   virtual ~CallbackImpl () {}
   132   virtual R operator() (T1, T2, T3, T4) = 0;
   133 };
   134 // define CallbackImpl for 5 params
   135 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
   136 class CallbackImpl<R,T1,T2,T3,T4,T5,empty,empty,empty,empty> : public CallbackImplBase {
   137 public:
   138   virtual ~CallbackImpl () {}
   139   virtual R operator() (T1, T2, T3, T4, T5) = 0;
   140 };
   141 // define CallbackImpl for 6 params
   142 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
   143 class CallbackImpl<R,T1,T2,T3,T4,T5,T6,empty,empty,empty> : public CallbackImplBase {
   144 public:
   145   virtual ~CallbackImpl () {}
   146   virtual R operator() (T1, T2, T3, T4, T5, T6) = 0;
   147 };
   148 // define CallbackImpl for 7 params
   149 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
   150 class CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,empty,empty> : public CallbackImplBase {
   151 public:
   152   virtual ~CallbackImpl () {}
   153   virtual R operator() (T1, T2, T3, T4, T5, T6, T7) = 0;
   154 };
   155 // define CallbackImpl for 8 params
   156 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
   157 class CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,empty> : public CallbackImplBase {
   158 public:
   159   virtual ~CallbackImpl () {}
   160   virtual R operator() (T1, T2, T3, T4, T5, T6, T7, T8) = 0;
   161 };
   162 // define CallbackImpl for 9 params
   163 template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
   164 class CallbackImpl : public CallbackImplBase {
   165 public:
   166   virtual ~CallbackImpl () {}
   167   virtual R operator() (T1, T2, T3, T4, T5, T6, T7, T8, T9) = 0;
   168 };
   169 
   170 
   171 // an impl for Functors:
   172 template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7, typename T8, typename T9>
   173 class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> {
   174 public:
   175   FunctorCallbackImpl (T const &functor)
   176     : m_functor (functor) {}
   177   virtual ~FunctorCallbackImpl () {}
   178   R operator() (void) {
   179     return m_functor ();
   180   }
   181   R operator() (T1 a1) {
   182     return m_functor (a1);
   183   }
   184   R operator() (T1 a1,T2 a2) {
   185     return m_functor (a1,a2);
   186   }
   187   R operator() (T1 a1,T2 a2,T3 a3) {
   188     return m_functor (a1,a2,a3);
   189   }
   190   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   191     return m_functor (a1,a2,a3,a4);
   192   }
   193   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   194     return m_functor (a1,a2,a3,a4,a5);
   195   }
   196   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
   197     return m_functor (a1,a2,a3,a4,a5,a6);
   198   }
   199   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) {
   200     return m_functor (a1,a2,a3,a4,a5,a6,a7);
   201   }
   202   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) {
   203     return m_functor (a1,a2,a3,a4,a5,a6,a7,a8);
   204   }
   205   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9) {
   206     return m_functor (a1,a2,a3,a4,a5,a6,a7,a8,a9);
   207   }
   208   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
   209     FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> const *otherDerived = 
   210       dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> const *> (PeekPointer(other));
   211     if (otherDerived == 0)
   212       {
   213         return false;
   214       }
   215     else if (otherDerived->m_functor != m_functor)
   216       {
   217         return false;
   218       }
   219     return true;
   220   }
   221 private:
   222   T m_functor;
   223 };
   224 
   225 // an impl for pointer to member functions
   226 template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
   227 class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> {
   228 public:
   229   MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR mem_ptr)
   230     : m_objPtr (objPtr), m_memPtr (mem_ptr) {}
   231   virtual ~MemPtrCallbackImpl () {}
   232   R operator() (void) {
   233     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) ();
   234   }
   235   R operator() (T1 a1) {
   236     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1);
   237   }
   238   R operator() (T1 a1,T2 a2) {
   239     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2);
   240   }
   241   R operator() (T1 a1,T2 a2,T3 a3) {
   242     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3);
   243   }
   244   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   245     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4);
   246   }
   247   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   248     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5);
   249   }
   250   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
   251     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5, a6);
   252   }
   253   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) {
   254     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5, a6, a7);
   255   }
   256   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) {
   257     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5, a6, a7, a8);
   258   }
   259   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, T9 a9) {
   260     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr) (a1, a2, a3, a4, a5, a6, a7, a8, a9);
   261   }
   262   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
   263     MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> const *otherDerived = 
   264       dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> const *> (PeekPointer (other));
   265     if (otherDerived == 0)
   266       {
   267         return false;
   268       }
   269     else if (otherDerived->m_objPtr != m_objPtr ||
   270              otherDerived->m_memPtr != m_memPtr)
   271       {
   272         return false;
   273       }
   274     return true;
   275   }
   276 private:
   277   OBJ_PTR const m_objPtr;
   278   MEM_PTR m_memPtr;
   279 };
   280 
   281 // an impl for Bound Functors:
   282 template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7, typename T8>
   283 class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,empty> {
   284 public:
   285   template <typename FUNCTOR, typename ARG>
   286   BoundFunctorCallbackImpl (FUNCTOR functor, ARG a)
   287     : m_functor (functor), m_a (a) {}
   288   virtual ~BoundFunctorCallbackImpl () {}
   289   R operator() (void) {
   290     return m_functor (m_a);
   291   }
   292   R operator() (T1 a1) {
   293     return m_functor (m_a,a1);
   294   }
   295   R operator() (T1 a1,T2 a2) {
   296     return m_functor (m_a,a1,a2);
   297   }
   298   R operator() (T1 a1,T2 a2,T3 a3) {
   299     return m_functor (m_a,a1,a2,a3);
   300   }
   301   R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
   302     return m_functor (m_a,a1,a2,a3,a4);
   303   }
   304   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
   305     return m_functor (m_a,a1,a2,a3,a4,a5);
   306   }
   307   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
   308     return m_functor (m_a,a1,a2,a3,a4,a5,a6);
   309   }
   310   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) {
   311     return m_functor (m_a,a1,a2,a3,a4,a5,a6,a7);
   312   }
   313   R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) {
   314     return m_functor (m_a,a1,a2,a3,a4,a5,a6,a7,a8);
   315   }
   316   virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
   317     BoundFunctorCallbackImpl<T,R,TX,T1,T2,T3,T4,T5,T6,T7,T8> const *otherDerived = 
   318       dynamic_cast<BoundFunctorCallbackImpl<T,R,TX,T1,T2,T3,T4,T5,T6,T7,T8> const *> (PeekPointer (other));
   319     if (otherDerived == 0)
   320       {
   321         return false;
   322       }
   323     else if (otherDerived->m_functor != m_functor ||
   324              otherDerived->m_a != m_a)
   325       {
   326         return false;
   327       }
   328     return true;
   329   }
   330 private:
   331   T m_functor;
   332   typename TypeTraits<TX>::ReferencedType m_a;
   333 };
   334 
   335 
   336 class CallbackBase {
   337 public:
   338   CallbackBase () : m_impl () {}
   339   Ptr<CallbackImplBase> GetImpl (void) const {return m_impl;}
   340 protected:
   341   CallbackBase (Ptr<CallbackImplBase> impl) : m_impl (impl) {}
   342   Ptr<CallbackImplBase> m_impl;
   343 
   344   static std::string Demangle(const std::string& mangled);
   345 };
   346 
   347 /**
   348  * \brief Callback template class
   349  *
   350  * This class template implements the Functor Design Pattern.
   351  * It is used to declare the type of a Callback:
   352  *  - the first non-optional template argument represents
   353  *    the return type of the callback.
   354  *  - the second optional template argument represents
   355  *    the type of the first argument to the callback.
   356  *  - the third optional template argument represents
   357  *    the type of the second argument to the callback.
   358  *  - the fourth optional template argument represents
   359  *    the type of the third argument to the callback.
   360  *  - the fifth optional template argument represents
   361  *    the type of the fourth argument to the callback.
   362  *  - the sixth optional template argument represents
   363  *    the type of the fifth argument to the callback.
   364  *
   365  * Callback instances are built with the \ref MakeCallback
   366  * template functions. Callback instances have POD semantics:
   367  * the memory they allocate is managed automatically, without
   368  * user intervention which allows you to pass around Callback
   369  * instances by value.
   370  *
   371  * Sample code which shows how to use this class template 
   372  * as well as the function templates \ref MakeCallback :
   373  * \include samples/main-callback.cc
   374  */
   375 
   376 template<typename R, 
   377          typename T1 = empty, typename T2 = empty, 
   378          typename T3 = empty, typename T4 = empty,
   379          typename T5 = empty, typename T6 = empty,
   380          typename T7 = empty, typename T8 = empty,
   381          typename T9 = empty>
   382 class Callback : public CallbackBase {
   383 public:
   384   Callback () {}
   385 
   386   // There are two dummy args below to ensure that this constructor is
   387   // always properly disambiguited by the c++ compiler
   388   template <typename FUNCTOR>
   389   Callback (FUNCTOR const &functor, bool, bool) 
   390     : CallbackBase (Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> > (functor))
   391   {}
   392 
   393   template <typename OBJ_PTR, typename MEM_PTR>
   394   Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
   395     : CallbackBase (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> > (objPtr, mem_ptr))
   396   {}
   397 
   398   Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> > const &impl)
   399     : CallbackBase (impl)
   400   {}
   401 
   402   template <typename T>
   403   Callback<R,T2,T3,T4,T5,T6,T7,T8,T9> Bind (T a) {
   404     Ptr<CallbackImpl<R,T2,T3,T4,T5,T6,T7,T8,T9,empty> > impl =
   405       Ptr<CallbackImpl<R,T2,T3,T4,T5,T6,T7,T8,T9,empty> > (
   406                                                   new BoundFunctorCallbackImpl<
   407                                                   Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9>,
   408                                                   R,T1,T2,T3,T4,T5,T6,T7,T8,T9> (*this, a), false);
   409     return Callback<R,T2,T3,T4,T5,T6,T7,T8,T9> (impl);
   410   }
   411 
   412   bool IsNull (void) const {
   413     return (DoPeekImpl () == 0)?true:false;
   414   }
   415   void Nullify (void) {
   416     m_impl = 0;
   417   }
   418 
   419   R operator() (void) const {
   420     return (*(DoPeekImpl ())) ();
   421   }
   422   R operator() (T1 a1) const {
   423     return (*(DoPeekImpl ())) (a1);
   424   }
   425   R operator() (T1 a1, T2 a2) const {
   426     return (*(DoPeekImpl ())) (a1,a2);
   427   }
   428   R operator() (T1 a1, T2 a2, T3 a3) const {
   429     return (*(DoPeekImpl ())) (a1,a2,a3);
   430   }
   431   R operator() (T1 a1, T2 a2, T3 a3, T4 a4) const {
   432     return (*(DoPeekImpl ())) (a1,a2,a3,a4);
   433   }
   434   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) const {
   435     return (*(DoPeekImpl ())) (a1,a2,a3,a4,a5);
   436   }
   437   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6) const {
   438     return (*(DoPeekImpl ())) (a1,a2,a3,a4,a5,a6);
   439   }
   440   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6,T7 a7) const {
   441     return (*(DoPeekImpl ())) (a1,a2,a3,a4,a5,a6,a7);
   442   }
   443   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6,T7 a7,T8 a8) const {
   444     return (*(DoPeekImpl ())) (a1,a2,a3,a4,a5,a6,a7,a8);
   445   }
   446   R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, T9 a9) const {
   447     return (*(DoPeekImpl ())) (a1,a2,a3,a4,a5,a6,a7,a8,a9);
   448   }
   449 
   450   bool IsEqual (const CallbackBase &other) const {
   451     return m_impl->IsEqual (other.GetImpl ());
   452   }
   453 
   454   bool CheckType (const CallbackBase & other) const {
   455     return DoCheckType (other.GetImpl ());
   456   }
   457   void Assign (const CallbackBase &other) {
   458     DoAssign (other.GetImpl ());
   459   }
   460 private:
   461   CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *DoPeekImpl (void) const {
   462     return static_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *> (PeekPointer (m_impl));
   463   }
   464   bool DoCheckType (Ptr<const CallbackImplBase> other) const {
   465     if (other != 0 && dynamic_cast<const CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *> (PeekPointer (other)) != 0)
   466       {
   467         return true;
   468       }
   469     else if (other == 0)
   470       {
   471         return true;
   472       }
   473     else
   474       {
   475         return false;
   476       }
   477   }
   478   void DoAssign (Ptr<const CallbackImplBase> other) {
   479     if (!DoCheckType (other))
   480       {
   481         NS_FATAL_ERROR ("Incompatible types. (feed to \"c++filt -t\" if needed)" << std::endl <<
   482                         "got=" << Demangle ( typeid (*other).name () ) << std::endl <<
   483                         "expected=" << Demangle ( typeid (CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *).name () ));
   484       }
   485     m_impl = const_cast<CallbackImplBase *> (PeekPointer (other));
   486   }
   487 };
   488 
   489 
   490 template <typename R, typename T1, typename T2,
   491           typename T3, typename T4,
   492           typename T5, typename T6,
   493           typename T7, typename T8,
   494           typename T9>
   495 bool operator != (Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> a, Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> b)
   496 {
   497   return !a.IsEqual (b);
   498 }
   499 
   500 /**
   501  * \ingroup core
   502  * \defgroup MakeCallback MakeCallback
   503  *
   504  */
   505 
   506 /**
   507  * \ingroup MakeCallback
   508  * \param memPtr class method member pointer
   509  * \param objPtr class instance
   510  * \return a wrapper Callback
   511  * Build Callbacks for class method members which takes no arguments
   512  * and potentially return a value.
   513  */
   514 template <typename T, typename OBJ, typename R>
   515 Callback<R> MakeCallback (R (T::*memPtr) (void), OBJ objPtr) {
   516   return Callback<R> (objPtr, memPtr);
   517 }
   518 template <typename T, typename OBJ, typename R>
   519 Callback<R> MakeCallback (R (T::*mem_ptr) () const, OBJ objPtr) {
   520   return Callback<R> (objPtr, mem_ptr);
   521 }
   522 /**
   523  * \ingroup MakeCallback
   524  * \param mem_ptr class method member pointer
   525  * \param objPtr class instance
   526  * \return a wrapper Callback
   527  * Build Callbacks for class method members which takes one argument
   528  * and potentially return a value.
   529  */
   530 template <typename T, typename OBJ, typename R, typename T1>
   531 Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1), OBJ objPtr) {
   532   return Callback<R,T1> (objPtr, mem_ptr);
   533 }
   534 template <typename T, typename OBJ, typename R, typename T1>
   535 Callback<R,T1> MakeCallback (R (T::*mem_ptr) (T1) const, OBJ objPtr) {
   536   return Callback<R,T1> (objPtr, mem_ptr);
   537 }
   538 /**
   539  * \ingroup MakeCallback
   540  * \param mem_ptr class method member pointer
   541  * \param objPtr class instance
   542  * \return a wrapper Callback
   543  * Build Callbacks for class method members which takes two arguments
   544  * and potentially return a value.
   545  */
   546 template <typename T, typename OBJ, typename R, typename T1, typename T2>
   547 Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2), OBJ objPtr) {
   548   return Callback<R,T1,T2> (objPtr, mem_ptr);
   549 }
   550 template <typename T, typename OBJ, typename R, typename T1, typename T2>
   551 Callback<R,T1,T2> MakeCallback (R (T::*mem_ptr) (T1,T2) const, OBJ objPtr) {
   552   return Callback<R,T1,T2> (objPtr, mem_ptr);
   553 }
   554 /**
   555  * \ingroup MakeCallback
   556  * \param mem_ptr class method member pointer
   557  * \param objPtr class instance
   558  * \return a wrapper Callback
   559  * Build Callbacks for class method members which takes three arguments
   560  * and potentially return a value.
   561  */
   562 template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
   563 Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3), OBJ objPtr) {
   564   return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
   565 }
   566 template <typename T, typename OBJ, typename R, typename T1,typename T2, typename T3>
   567 Callback<R,T1,T2,T3> MakeCallback (R (T::*mem_ptr) (T1,T2,T3) const, OBJ objPtr) {
   568   return Callback<R,T1,T2,T3> (objPtr, mem_ptr);
   569 }
   570 /**
   571  * \ingroup MakeCallback
   572  * \param mem_ptr class method member pointer
   573  * \param objPtr class instance
   574  * \return a wrapper Callback
   575  * Build Callbacks for class method members which takes four arguments
   576  * and potentially return a value.
   577  */
   578 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
   579 Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4), OBJ objPtr) {
   580   return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
   581 }
   582 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4>
   583 Callback<R,T1,T2,T3,T4> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4) const, OBJ objPtr) {
   584   return Callback<R,T1,T2,T3,T4> (objPtr, mem_ptr);
   585 }
   586 /**
   587  * \ingroup MakeCallback
   588  * \param mem_ptr class method member pointer
   589  * \param objPtr class instance
   590  * \return a wrapper Callback
   591  * Build Callbacks for class method members which takes five arguments
   592  * and potentially return a value.
   593  */
   594 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   595 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5), OBJ objPtr) {
   596   return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
   597 }
   598 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5>
   599 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5) const, OBJ objPtr) {
   600   return Callback<R,T1,T2,T3,T4,T5> (objPtr, mem_ptr);
   601 }
   602 /**
   603  * \ingroup MakeCallback
   604  * \param mem_ptr class method member pointer
   605  * \param objPtr class instance
   606  * \return a wrapper Callback
   607  * Build Callbacks for class method members which takes six arguments
   608  * and potentially return a value.
   609  */
   610 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5,typename T6>
   611 Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6), OBJ objPtr) {
   612   return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
   613 }
   614 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
   615 Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6) const, OBJ objPtr) {
   616   return Callback<R,T1,T2,T3,T4,T5,T6> (objPtr, mem_ptr);
   617 }
   618 
   619 /**
   620  * \ingroup MakeCallback
   621  * \param mem_ptr class method member pointer
   622  * \param objPtr class instance
   623  * \return a wrapper Callback
   624  * Build Callbacks for class method members which takes seven arguments
   625  * and potentially return a value.
   626  */
   627 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5,typename T6, typename T7>
   628 Callback<R,T1,T2,T3,T4,T5,T6,T7> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6,T7), OBJ objPtr) {
   629   return Callback<R,T1,T2,T3,T4,T5,T6,T7> (objPtr, mem_ptr);
   630 }
   631 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7>
   632 Callback<R,T1,T2,T3,T4,T5,T6,T7> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6,T7) const, OBJ objPtr) {
   633   return Callback<R,T1,T2,T3,T4,T5,T6,T7> (objPtr, mem_ptr);
   634 }
   635 
   636 
   637 /**
   638  * \ingroup MakeCallback
   639  * \param mem_ptr class method member pointer
   640  * \param objPtr class instance
   641  * \return a wrapper Callback
   642  * Build Callbacks for class method members which takes eight arguments
   643  * and potentially return a value.
   644  */
   645 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5,typename T6, typename T7, typename T8>
   646 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6,T7,T8), OBJ objPtr) {
   647   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> (objPtr, mem_ptr);
   648 }
   649 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7, typename T8>
   650 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6,T7,T8) const, OBJ objPtr) {
   651   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> (objPtr, mem_ptr);
   652 }
   653 
   654 /**
   655  * \ingroup MakeCallback
   656  * \param mem_ptr class method member pointer
   657  * \param objPtr class instance
   658  * \return a wrapper Callback
   659  * Build Callbacks for class method members which takes nine arguments
   660  * and potentially return a value.
   661  */
   662 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5,typename T6, typename T7, typename T8, typename T9>
   663 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6,T7,T8,T9), OBJ objPtr) {
   664   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> (objPtr, mem_ptr);
   665 }
   666 template <typename T, typename OBJ, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7, typename T8, typename T9>
   667 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> MakeCallback (R (T::*mem_ptr) (T1,T2,T3,T4,T5,T6,T7,T8,T9) const, OBJ objPtr) {
   668   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> (objPtr, mem_ptr);
   669 }
   670 
   671 /**
   672  * \ingroup MakeCallback
   673  * \param fnPtr function pointer
   674  * \return a wrapper Callback
   675  * Build Callbacks for functions which takes no arguments
   676  * and potentially return a value.
   677  */
   678 template <typename R>
   679 Callback<R> MakeCallback (R (*fnPtr) ()) {
   680   return Callback<R> (fnPtr, true, true);
   681 }
   682 /**
   683  * \ingroup MakeCallback
   684  * \param fnPtr function pointer
   685  * \return a wrapper Callback
   686  * Build Callbacks for functions which takes one argument
   687  * and potentially return a value.
   688  */
   689 template <typename R, typename T1>
   690 Callback<R,T1> MakeCallback (R (*fnPtr) (T1)) {
   691   return Callback<R,T1> (fnPtr, true, true);
   692 }
   693 /**
   694  * \ingroup MakeCallback
   695  * \param fnPtr function pointer
   696  * \return a wrapper Callback
   697  * Build Callbacks for functions which takes two arguments
   698  * and potentially return a value.
   699  */
   700 template <typename R, typename T1, typename T2>
   701 Callback<R,T1,T2> MakeCallback (R (*fnPtr) (T1,T2)) {
   702   return Callback<R,T1,T2> (fnPtr, true, true);
   703 }
   704 /**
   705  * \ingroup MakeCallback
   706  * \param fnPtr function pointer
   707  * \return a wrapper Callback
   708  * Build Callbacks for functions which takes three arguments
   709  * and potentially return a value.
   710  */
   711 template <typename R, typename T1, typename T2,typename T3>
   712 Callback<R,T1,T2,T3> MakeCallback (R (*fnPtr) (T1,T2,T3)) {
   713   return Callback<R,T1,T2,T3> (fnPtr, true, true);
   714 }
   715 /**
   716  * \ingroup MakeCallback
   717  * \param fnPtr function pointer
   718  * \return a wrapper Callback
   719  * Build Callbacks for functions which takes four arguments
   720  * and potentially return a value.
   721  */
   722 template <typename R, typename T1, typename T2,typename T3,typename T4>
   723 Callback<R,T1,T2,T3,T4> MakeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
   724   return Callback<R,T1,T2,T3,T4> (fnPtr, true, true);
   725 }
   726 /**
   727  * \ingroup MakeCallback
   728  * \param fnPtr function pointer
   729  * \return a wrapper Callback
   730  * Build Callbacks for functions which takes five arguments
   731  * and potentially return a value.
   732  */
   733 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   734 Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
   735   return Callback<R,T1,T2,T3,T4,T5> (fnPtr, true, true);
   736 }
   737 /**
   738  * \ingroup MakeCallback
   739  * \param fnPtr function pointer
   740  * \return a wrapper Callback
   741  * Build Callbacks for functions which takes six arguments
   742  * and potentially return a value.
   743  */
   744 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
   745 Callback<R,T1,T2,T3,T4,T5,T6> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5,T6)) {
   746   return Callback<R,T1,T2,T3,T4,T5,T6> (fnPtr, true, true);
   747 }
   748 
   749 /**
   750  * \ingroup MakeCallback
   751  * \param fnPtr function pointer
   752  * \return a wrapper Callback
   753  * Build Callbacks for functions which takes seven arguments
   754  * and potentially return a value.
   755  */
   756 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6, typename T7>
   757 Callback<R,T1,T2,T3,T4,T5,T6,T7> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5,T6,T7)) {
   758   return Callback<R,T1,T2,T3,T4,T5,T6,T7> (fnPtr, true, true);
   759 }
   760 
   761 /**
   762  * \ingroup MakeCallback
   763  * \param fnPtr function pointer
   764  * \return a wrapper Callback
   765  * Build Callbacks for functions which takes eight arguments
   766  * and potentially return a value.
   767  */
   768 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6, typename T7, typename T8>
   769 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5,T6,T7,T8)) {
   770   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> (fnPtr, true, true);
   771 }
   772 
   773 /**
   774  * \ingroup MakeCallback
   775  * \param fnPtr function pointer
   776  * \return a wrapper Callback
   777  * Build Callbacks for functions which takes nine arguments
   778  * and potentially return a value.
   779  */
   780 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6, typename T7, typename T8, typename T9>
   781 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5,T6,T7,T8,T9)) {
   782   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> (fnPtr, true, true);
   783 }
   784 
   785 
   786 
   787 /**
   788  * \ingroup MakeCallback
   789  * \return a wrapper Callback
   790  * Build a null callback which takes no arguments
   791  * and potentially return a value.
   792  */
   793 template <typename R>
   794 Callback<R> MakeNullCallback (void) {
   795   return Callback<R> ();
   796 }
   797 /**
   798  * \ingroup MakeCallback
   799  * \overload Callback<R> MakeNullCallback (void)
   800  * \return a wrapper Callback
   801  * Build a null callback which takes one argument
   802  * and potentially return a value.
   803  */
   804 template <typename R, typename T1>
   805 Callback<R,T1> MakeNullCallback (void) {
   806   return Callback<R,T1> ();
   807 }
   808 /**
   809  * \ingroup MakeCallback
   810  * \overload Callback<R> MakeNullCallback (void)
   811  * \return a wrapper Callback
   812  * Build a null callback which takes two arguments
   813  * and potentially return a value.
   814  */
   815 template <typename R, typename T1, typename T2>
   816 Callback<R,T1,T2> MakeNullCallback (void) {
   817   return Callback<R,T1,T2> ();
   818 }
   819 /**
   820  * \ingroup MakeCallback
   821  * \overload Callback<R> MakeNullCallback (void)
   822  * \return a wrapper Callback
   823  * Build a null callback which takes three arguments
   824  * and potentially return a value.
   825  */
   826 template <typename R, typename T1, typename T2,typename T3>
   827 Callback<R,T1,T2,T3> MakeNullCallback (void) {
   828   return Callback<R,T1,T2,T3> ();
   829 }
   830 /**
   831  * \ingroup MakeCallback
   832  * \overload Callback<R> MakeNullCallback (void)
   833  * \return a wrapper Callback
   834  * Build a null callback which takes four arguments
   835  * and potentially return a value.
   836  */
   837 template <typename R, typename T1, typename T2,typename T3,typename T4>
   838 Callback<R,T1,T2,T3,T4> MakeNullCallback (void) {
   839   return Callback<R,T1,T2,T3,T4> ();
   840 }
   841 /**
   842  * \ingroup MakeCallback
   843  * \overload Callback<R> MakeNullCallback (void)
   844  * \return a wrapper Callback
   845  * Build a null callback which takes five arguments
   846  * and potentially return a value.
   847  */
   848 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
   849 Callback<R,T1,T2,T3,T4,T5> MakeNullCallback (void) {
   850   return Callback<R,T1,T2,T3,T4,T5> ();
   851 }
   852 /**
   853  * \ingroup MakeCallback
   854  * \overload Callback<R> MakeNullCallback (void)
   855  * \return a wrapper Callback
   856  * Build a null callback which takes six arguments
   857  * and potentially return a value.
   858  */
   859 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6>
   860 Callback<R,T1,T2,T3,T4,T5,T6> MakeNullCallback (void) {
   861   return Callback<R,T1,T2,T3,T4,T5,T6> ();
   862 }
   863 
   864 /**
   865  * \ingroup MakeCallback
   866  * \overload Callback<R> MakeNullCallback (void)
   867  * \return a wrapper Callback
   868  * Build a null callback which takes seven arguments
   869  * and potentially return a value.
   870  */
   871 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6, typename T7>
   872 Callback<R,T1,T2,T3,T4,T5,T6,T7> MakeNullCallback (void) {
   873   return Callback<R,T1,T2,T3,T4,T5,T6,T7> ();
   874 }
   875 
   876 /**
   877  * \ingroup MakeCallback
   878  * \overload Callback<R> MakeNullCallback (void)
   879  * \return a wrapper Callback
   880  * Build a null callback which takes eight arguments
   881  * and potentially return a value.
   882  */
   883 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6, typename T7, typename T8>
   884 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> MakeNullCallback (void) {
   885   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> ();
   886 }
   887 
   888 /**
   889  * \ingroup MakeCallback
   890  * \overload Callback<R> MakeNullCallback (void)
   891  * \return a wrapper Callback
   892  * Build a null callback which takes nine arguments
   893  * and potentially return a value.
   894  */
   895 template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5,typename T6, typename T7, typename T8, typename T9>
   896 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> MakeNullCallback (void) {
   897   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> ();
   898 }
   899 
   900 
   901 /*
   902  * The following is experimental code. It works but we have
   903  * not yet determined whether or not it is really useful and whether
   904  * or not we really want to use it.
   905  */
   906 
   907 template <typename R, typename TX, typename ARG>
   908 Callback<R> MakeBoundCallback (R (*fnPtr) (TX), ARG a) {
   909   Ptr<CallbackImpl<R,empty,empty,empty,empty,empty,empty,empty,empty,empty> > impl =
   910     Create<BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty,empty,empty,empty> >(fnPtr, a);
   911   return Callback<R> (impl);
   912 }
   913 
   914 template <typename R, typename TX, typename ARG, 
   915           typename T1>
   916 Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), ARG a) {
   917   Ptr<CallbackImpl<R,T1,empty,empty,empty,empty,empty,empty,empty,empty> > impl =
   918     Create<BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty,empty,empty,empty> > (fnPtr, a);
   919   return Callback<R,T1> (impl);
   920 }
   921 template <typename R, typename TX, typename ARG, 
   922           typename T1, typename T2>
   923 Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), ARG a) {
   924   Ptr<CallbackImpl<R,T1,T2,empty,empty,empty,empty,empty,empty,empty> > impl =
   925     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty,empty,empty,empty> > (fnPtr, a);
   926   return Callback<R,T1,T2> (impl);
   927 }
   928 template <typename R, typename TX, typename ARG,
   929           typename T1, typename T2,typename T3>
   930 Callback<R,T1,T2,T3> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3), ARG a) {
   931   Ptr<CallbackImpl<R,T1,T2,T3,empty,empty,empty,empty,empty,empty> > impl =
   932     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3),R,TX,T1,T2,T3,empty,empty,empty,empty,empty> > (fnPtr, a);
   933   return Callback<R,T1,T2,T3> (impl);
   934 }
   935 template <typename R, typename TX, typename ARG,
   936           typename T1, typename T2,typename T3,typename T4>
   937 Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), ARG a) {
   938   Ptr<CallbackImpl<R,T1,T2,T3,T4,empty,empty,empty,empty,empty> > impl =
   939     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty,empty,empty,empty> > (fnPtr, a);
   940   return Callback<R,T1,T2,T3,T4> (impl);
   941 }
   942 template <typename R, typename TX, typename ARG,
   943           typename T1, typename T2,typename T3,typename T4,typename T5>
   944 Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), ARG a) {
   945   Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,empty,empty,empty,empty> > impl =
   946     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5,empty,empty,empty> > (fnPtr, a);
   947   return Callback<R,T1,T2,T3,T4,T5> (impl);
   948 }
   949 template <typename R, typename TX, typename ARG,
   950           typename T1, typename T2,typename T3,typename T4,typename T5, typename T6>
   951 Callback<R,T1,T2,T3,T4,T5,T6> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5,T6), ARG a) {
   952   Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,empty,empty,empty> > impl =
   953     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5,T6),R,TX,T1,T2,T3,T4,T5,T6,empty,empty> > (fnPtr, a);
   954   return Callback<R,T1,T2,T3,T4,T5,T6> (impl);
   955 }
   956 template <typename R, typename TX, typename ARG,
   957           typename T1, typename T2,typename T3,typename T4,typename T5, typename T6, typename T7>
   958 Callback<R,T1,T2,T3,T4,T5,T6,T7> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5,T6,T7), ARG a) {
   959   Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,empty,empty> > impl =
   960     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5,T6,T7),R,TX,T1,T2,T3,T4,T5,T6,T7,empty> > (fnPtr, a);
   961   return Callback<R,T1,T2,T3,T4,T5,T6,T7> (impl);
   962 }
   963 template <typename R, typename TX, typename ARG,
   964           typename T1, typename T2,typename T3,typename T4,typename T5, typename T6, typename T7, typename T8>
   965 Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5,T6,T7,T8), ARG a) {
   966   Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,empty> > impl =
   967     Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5,T6,T7,T8),R,TX,T1,T2,T3,T4,T5,T6,T7,T8> > (fnPtr, a);
   968   return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> (impl);
   969 }
   970 } // namespace ns3
   971 
   972 namespace ns3 {
   973 
   974 class CallbackValue : public AttributeValue
   975 {
   976 public:
   977   CallbackValue ();
   978   CallbackValue (const CallbackBase &base);
   979   virtual ~CallbackValue ();
   980   void Set (CallbackBase base);
   981   template <typename T>
   982   bool GetAccessor (T &value) const;
   983   virtual Ptr<AttributeValue> Copy (void) const;
   984   virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
   985   virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
   986 private:
   987   CallbackBase m_value;
   988 };
   989 
   990 ATTRIBUTE_ACCESSOR_DEFINE(Callback);
   991 ATTRIBUTE_CHECKER_DEFINE (Callback);
   992 
   993 } // namespace ns3
   994 
   995 namespace ns3 {
   996 
   997 template <typename T>
   998 bool CallbackValue::GetAccessor (T &value) const
   999 {
  1000   if (value.CheckType (m_value))
  1001     {
  1002       value.Assign (m_value);
  1003       return true;
  1004     }
  1005   return false;
  1006 }
  1007 
  1008 } // namespace ns3
  1009 
  1010 
  1011 #endif /* CALLBACK_H */