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