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