src/core/ptr.h
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 3767 b03ea30335a3
permissions -rw-r--r--
Added tag ns-3.5 for changeset c975274c9707
mathieu@223
     1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
mathieu@223
     2
/*
mathieu@223
     3
 * Copyright (c) 2005,2006 INRIA
mathieu@223
     4
 *
mathieu@223
     5
 * This program is free software; you can redistribute it and/or modify
mathieu@223
     6
 * it under the terms of the GNU General Public License version 2 as
mathieu@223
     7
 * published by the Free Software Foundation;
mathieu@223
     8
 *
mathieu@223
     9
 * This program is distributed in the hope that it will be useful,
mathieu@223
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
mathieu@223
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
mathieu@223
    12
 * GNU General Public License for more details.
mathieu@223
    13
 *
mathieu@223
    14
 * You should have received a copy of the GNU General Public License
mathieu@223
    15
 * along with this program; if not, write to the Free Software
mathieu@223
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
mathieu@223
    17
 *
mathieu@223
    18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
mathieu@223
    19
 */
mathieu@223
    20
mathieu@223
    21
#ifndef PTR_H
mathieu@223
    22
#define PTR_H
mathieu@223
    23
mathieu@970
    24
#include <iostream>
mathieu@223
    25
#include <stdint.h>
mathieu@286
    26
#include "assert.h"
mathieu@223
    27
mathieu@223
    28
namespace ns3 {
mathieu@223
    29
mathieu@223
    30
/**
tomh@3182
    31
 * \ingroup core
tomh@3182
    32
 * \defgroup ptr Smart Pointer
tomh@3182
    33
 */
tomh@3182
    34
/**
tomh@3182
    35
 * \ingroup ptr
tomh@3182
    36
 *
mathieu@573
    37
 * \brief smart pointer class similar to boost::intrusive_ptr
mathieu@223
    38
 *
mathieu@573
    39
 * This smart-pointer class assumes that the underlying
mathieu@573
    40
 * type provides a pair of Ref and Unref methods which are
mathieu@573
    41
 * expected to increment and decrement the internal refcount
mathieu@573
    42
 * of the object instance.
mathieu@573
    43
 *
mathieu@223
    44
 * This implementation allows you to manipulate the smart pointer
mathieu@223
    45
 * as if it was a normal pointer: you can compare it with zero,
mathieu@573
    46
 * compare it against other pointers, assign zero to it, etc.
mathieu@573
    47
 *
mathieu@573
    48
 * It is possible to extract the raw pointer from this
mathieu@573
    49
 * smart pointer with the GetPointer and PeekPointer methods.
mathieu@573
    50
 *
mathieu@573
    51
 * If you want to store a newed object into a smart pointer,
mathieu@732
    52
 * we recommend you to use the Create template functions
mathieu@573
    53
 * to create the object and store it in a smart pointer to avoid
mathieu@573
    54
 * memory leaks. These functions are really small conveniance
mathieu@573
    55
 * functions and their goal is just is save you a small
mathieu@573
    56
 * bit of typing.
mathieu@223
    57
 */
mathieu@223
    58
template <typename T>
mathieu@223
    59
class Ptr 
mathieu@223
    60
{
mathieu@223
    61
private:
mathieu@223
    62
  T *m_ptr;
mathieu@223
    63
  class Tester {
mathieu@223
    64
  private:
mathieu@223
    65
    void operator delete (void *);
mathieu@223
    66
  };
mathieu@225
    67
  friend class Ptr<const T>;
mathieu@573
    68
  template <typename U>
mathieu@573
    69
  friend U *GetPointer (const Ptr<U> &p);
mathieu@573
    70
  template <typename U>
mathieu@573
    71
  friend U *PeekPointer (const Ptr<U> &p);
mathieu@573
    72
mathieu@1013
    73
  inline void Acquire (void) const;
mathieu@223
    74
public:
mathieu@223
    75
  /**
mathieu@223
    76
   * Create an empty smart pointer
mathieu@223
    77
   */
mathieu@223
    78
  Ptr ();
mathieu@223
    79
  /**
mathieu@223
    80
   * \param ptr raw pointer to manage
mathieu@223
    81
   *
gjcarneiro@664
    82
   * Create a smart pointer which points to the object pointed to by
gjcarneiro@664
    83
   * the input raw pointer ptr. This method creates its own reference
gjcarneiro@664
    84
   * to the pointed object. The caller is responsible for Unref()'ing
gjcarneiro@664
    85
   * its own reference, and the smart pointer will eventually do the
gjcarneiro@664
    86
   * same, so that object is deleted if no more references to it
gjcarneiro@664
    87
   * remain.
mathieu@223
    88
   */
mathieu@1007
    89
  Ptr (T *ptr);  
mathieu@1007
    90
  /**
mathieu@1007
    91
   * \param ptr raw pointer to manage
mathieu@1007
    92
   * \param ref if set to true, this method calls Ref, otherwise,
mathieu@1007
    93
   *        it does not call Ref.
mathieu@1007
    94
   *    
mathieu@1007
    95
   * Create a smart pointer which points to the object pointed to by
mathieu@1007
    96
   * the input raw pointer ptr.
mathieu@1007
    97
   */
mathieu@1007
    98
  Ptr (T *ptr, bool ref);
mathieu@223
    99
  Ptr (Ptr const&o);
mathieu@223
   100
  // allow conversions from T to T const.
mathieu@223
   101
  template <typename U>
mathieu@223
   102
  Ptr (Ptr<U> const &o);
mathieu@223
   103
  ~Ptr () ;
mathieu@223
   104
  Ptr<T> &operator = (Ptr const& o);
mathieu@544
   105
mathieu@223
   106
  T *operator -> () const;
mathieu@223
   107
  T *operator -> ();
mathieu@1864
   108
  const T &operator * () const;
nbaldo@4329
   109
  T &operator * ();
mathieu@223
   110
  // allow if (!sp)
mathieu@223
   111
  bool operator! ();
mathieu@223
   112
  // allow if (sp)
mathieu@574
   113
  // disable delete sp
mathieu@223
   114
  operator Tester * () const;
mathieu@223
   115
};
mathieu@223
   116
mathieu@223
   117
template <typename T>
mathieu@732
   118
Ptr<T> Create (void);
mathieu@569
   119
mathieu@569
   120
template <typename T, typename T1>
mathieu@732
   121
Ptr<T> Create (T1 a1);
mathieu@569
   122
mathieu@569
   123
template <typename T, typename T1, typename T2>
mathieu@732
   124
Ptr<T> Create (T1 a1, T2 a2);
mathieu@569
   125
mathieu@569
   126
template <typename T, typename T1, typename T2, typename T3>
mathieu@732
   127
Ptr<T> Create (T1 a1, T2 a2, T3 a3);
mathieu@569
   128
mathieu@569
   129
template <typename T, typename T1, typename T2, typename T3, typename T4>
mathieu@732
   130
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4);
mathieu@569
   131
mathieu@569
   132
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
mathieu@732
   133
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
mathieu@569
   134
mathieu@570
   135
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
mathieu@732
   136
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
mathieu@570
   137
mathieu@570
   138
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
mathieu@732
   139
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
mathieu@570
   140
mathieu@573
   141
/**
mathieu@640
   142
 * \relates Ptr
mathieu@573
   143
 * \return the pointer managed by this smart pointer.
mathieu@573
   144
 *
mathieu@573
   145
 * The underlying refcount is not incremented prior
mathieu@573
   146
 * to returning to the caller so the caller is not
mathieu@573
   147
 * responsible for calling Unref himself.
mathieu@573
   148
 */
mathieu@573
   149
template <typename T>
mathieu@573
   150
T * PeekPointer (const Ptr<T> &p);
mathieu@573
   151
mathieu@573
   152
/**
mathieu@640
   153
 * \relates Ptr
mathieu@573
   154
 * \return the pointer managed by this smart pointer.
mathieu@573
   155
 *
mathieu@573
   156
 * The underlying refcount is incremented prior
mathieu@573
   157
 * to returning to the caller so the caller is
mathieu@573
   158
 * responsible for calling Unref himself.
mathieu@573
   159
 */
mathieu@573
   160
template <typename T>
mathieu@573
   161
T * GetPointer (const Ptr<T> &p);
mathieu@573
   162
mathieu@966
   163
template <typename T>
mathieu@966
   164
std::ostream &operator << (std::ostream &, const Ptr<T> &p);
mathieu@966
   165
mathieu@573
   166
mathieu@573
   167
// allow if (sp == 0)
mathieu@573
   168
template <typename T1, typename T2>
mathieu@573
   169
bool operator == (Ptr<T1> const &lhs, T2 const *rhs);
mathieu@573
   170
mathieu@573
   171
// allow if (0 == sp)
mathieu@573
   172
template <typename T1, typename T2>
mathieu@573
   173
bool operator == (T1 const *lhs, Ptr<T2> &rhs);
mathieu@573
   174
mathieu@573
   175
// allow if (sp != 0)
mathieu@573
   176
template <typename T1, typename T2>
mathieu@573
   177
bool operator != (Ptr<T1> const &lhs, T2 const *rhs);
mathieu@573
   178
mathieu@573
   179
// allow if (0 != sp)
mathieu@573
   180
template <typename T1, typename T2>
mathieu@573
   181
bool operator != (T1 const *lhs, Ptr<T2> &rhs);
mathieu@573
   182
mathieu@573
   183
// allow if (sp0 == sp1)
mathieu@573
   184
template <typename T1, typename T2>
mathieu@573
   185
bool operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
mathieu@573
   186
mathieu@573
   187
// allow if (sp0 != sp1)
mathieu@573
   188
template <typename T1, typename T2>
mathieu@573
   189
bool operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
mathieu@573
   190
mathieu@573
   191
template <typename T1, typename T2>
mathieu@573
   192
Ptr<T1> const_pointer_cast (Ptr<T2> const&p);
mathieu@573
   193
mathieu@685
   194
template <typename T>
mathieu@685
   195
struct CallbackTraits;
mathieu@685
   196
mathieu@685
   197
template <typename T>
mathieu@685
   198
struct CallbackTraits<Ptr<T> >
mathieu@685
   199
{
mathieu@685
   200
  static T & GetReference (Ptr<T> const p)
mathieu@685
   201
  {
mathieu@689
   202
    return *PeekPointer (p);
mathieu@685
   203
  }
mathieu@685
   204
};
mathieu@685
   205
mathieu@690
   206
template <typename T>
mathieu@946
   207
struct EventMemberImplObjTraits;
mathieu@690
   208
mathieu@690
   209
template <typename T>
mathieu@946
   210
struct EventMemberImplObjTraits<Ptr<T> >
mathieu@690
   211
{
mathieu@690
   212
  static T &GetReference (Ptr<T> p) {
mathieu@690
   213
    return *PeekPointer (p);
mathieu@690
   214
  }
mathieu@690
   215
};
mathieu@690
   216
mathieu@685
   217
mathieu@689
   218
mathieu@573
   219
} // namespace ns3
mathieu@573
   220
mathieu@573
   221
mathieu@573
   222
namespace ns3 {
mathieu@573
   223
mathieu@573
   224
  /*************************************************
mathieu@573
   225
   *  friend non-member function implementations
mathieu@573
   226
   ************************************************/
mathieu@569
   227
mathieu@569
   228
template <typename T>
mathieu@732
   229
Ptr<T> Create (void)
mathieu@569
   230
{
mathieu@1864
   231
  return Ptr<T> (new T (), false);
mathieu@569
   232
}
mathieu@569
   233
mathieu@569
   234
template <typename T, typename T1>
mathieu@732
   235
Ptr<T> Create (T1 a1)
mathieu@569
   236
{
mathieu@1864
   237
  return Ptr<T> (new T (a1), false);
mathieu@569
   238
}
mathieu@569
   239
mathieu@569
   240
template <typename T, typename T1, typename T2>
mathieu@732
   241
Ptr<T> Create (T1 a1, T2 a2)
mathieu@569
   242
{
mathieu@1864
   243
  return Ptr<T> (new T (a1, a2), false);
mathieu@569
   244
}
mathieu@569
   245
mathieu@569
   246
template <typename T, typename T1, typename T2, typename T3>
mathieu@732
   247
Ptr<T> Create (T1 a1, T2 a2, T3 a3)
mathieu@569
   248
{
mathieu@1864
   249
  return Ptr<T> (new T (a1, a2, a3), false);
mathieu@569
   250
}
mathieu@569
   251
mathieu@569
   252
template <typename T, typename T1, typename T2, typename T3, typename T4>
mathieu@732
   253
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4)
mathieu@569
   254
{
mathieu@1864
   255
  return Ptr<T> (new T (a1, a2, a3, a4), false);
mathieu@569
   256
}
mathieu@569
   257
mathieu@569
   258
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
mathieu@732
   259
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
mathieu@569
   260
{
mathieu@1864
   261
  return Ptr<T> (new T (a1, a2, a3, a4, a5), false);
mathieu@569
   262
}
mathieu@569
   263
mathieu@570
   264
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
mathieu@732
   265
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
mathieu@570
   266
{
mathieu@1864
   267
  return Ptr<T> (new T (a1, a2, a3, a4, a5, a6), false);
mathieu@570
   268
}
mathieu@570
   269
mathieu@570
   270
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
mathieu@732
   271
Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
mathieu@570
   272
{
mathieu@1864
   273
  return Ptr<T> (new T (a1, a2, a3, a4, a5, a6, a7), false);
mathieu@570
   274
}
mathieu@570
   275
mathieu@573
   276
template <typename T>
mathieu@573
   277
T * PeekPointer (const Ptr<T> &p)
mathieu@573
   278
{
mathieu@573
   279
  return p.m_ptr;
mathieu@573
   280
}
mathieu@573
   281
mathieu@573
   282
template <typename T>
mathieu@573
   283
T * GetPointer (const Ptr<T> &p)
mathieu@573
   284
{
mathieu@573
   285
  p.Acquire ();
mathieu@573
   286
  return p.m_ptr;
mathieu@573
   287
}
mathieu@573
   288
mathieu@966
   289
template <typename T>
mathieu@966
   290
std::ostream &operator << (std::ostream &os, const Ptr<T> &p)
mathieu@966
   291
{
mathieu@966
   292
  os << PeekPointer (p);
mathieu@966
   293
  return os;
mathieu@966
   294
}
mathieu@966
   295
mathieu@573
   296
template <typename T1, typename T2>
mathieu@573
   297
bool 
mathieu@573
   298
operator == (Ptr<T1> const &lhs, T2 const *rhs)
mathieu@573
   299
{
mathieu@573
   300
  return PeekPointer (lhs) == rhs;
mathieu@573
   301
}
mathieu@573
   302
mathieu@573
   303
template <typename T1, typename T2>
mathieu@573
   304
bool 
mathieu@573
   305
operator == (T1 const *lhs, Ptr<T2> &rhs)
mathieu@573
   306
{
mathieu@573
   307
  return lhs == PeekPointer (rhs);
mathieu@573
   308
}
mathieu@573
   309
mathieu@573
   310
template <typename T1, typename T2>
mathieu@573
   311
bool 
mathieu@573
   312
operator != (Ptr<T1> const &lhs, T2 const *rhs)
mathieu@573
   313
{
mathieu@573
   314
  return PeekPointer (lhs) != rhs;
mathieu@573
   315
}
mathieu@573
   316
mathieu@573
   317
template <typename T1, typename T2>
mathieu@573
   318
bool 
mathieu@573
   319
operator != (T1 const *lhs, Ptr<T2> &rhs)
mathieu@573
   320
{
mathieu@573
   321
  return lhs != PeekPointer (rhs);
mathieu@573
   322
}
mathieu@573
   323
mathieu@573
   324
template <typename T1, typename T2>
mathieu@573
   325
bool 
mathieu@573
   326
operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
mathieu@573
   327
{
mathieu@573
   328
  return PeekPointer (lhs) == PeekPointer (rhs);
mathieu@573
   329
}
mathieu@573
   330
mathieu@573
   331
template <typename T1, typename T2>
mathieu@573
   332
bool 
mathieu@573
   333
operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
mathieu@573
   334
{
mathieu@573
   335
  return PeekPointer (lhs) != PeekPointer (rhs);
mathieu@573
   336
}
mathieu@573
   337
gjc@1697
   338
template <typename T>
gjc@1698
   339
bool operator < (const Ptr<T> &lhs, const Ptr<T> &rhs)
gjc@1697
   340
{
gjc@1697
   341
  return PeekPointer<T> (lhs) < PeekPointer<T> (rhs);
gjc@1697
   342
}
mathieu@573
   343
mathieu@3748
   344
template <typename T>
mathieu@3748
   345
bool operator <= (const Ptr<T> &lhs, const Ptr<T> &rhs)
mathieu@3748
   346
{
mathieu@3748
   347
  return PeekPointer<T> (lhs) <= PeekPointer<T> (rhs);
mathieu@3748
   348
}
mathieu@3748
   349
mathieu@3748
   350
template <typename T>
mathieu@3748
   351
bool operator > (const Ptr<T> &lhs, const Ptr<T> &rhs)
mathieu@3748
   352
{
mathieu@3748
   353
  return PeekPointer<T> (lhs) > PeekPointer<T> (rhs);
mathieu@3748
   354
}
mathieu@3748
   355
mathieu@3748
   356
template <typename T>
mathieu@3748
   357
bool operator >= (const Ptr<T> &lhs, const Ptr<T> &rhs)
mathieu@3748
   358
{
mathieu@3748
   359
  return PeekPointer<T> (lhs) >= PeekPointer<T> (rhs);
mathieu@3748
   360
}
mathieu@3748
   361
mathieu@573
   362
template <typename T1, typename T2>
mathieu@573
   363
Ptr<T1>
mathieu@3767
   364
ConstCast (Ptr<T2> const&p)
mathieu@573
   365
{
mathieu@573
   366
  return Ptr<T1> (const_cast<T1 *> (PeekPointer (p)));
mathieu@573
   367
}
mathieu@573
   368
mathieu@3767
   369
template <typename T1, typename T2>
mathieu@3767
   370
Ptr<T1>
mathieu@3767
   371
DynamicCast (Ptr<T2> const&p)
mathieu@3767
   372
{
mathieu@3767
   373
  return Ptr<T1> (dynamic_cast<T1 *> (PeekPointer (p)));
mathieu@3767
   374
}
mathieu@3767
   375
mathieu@573
   376
mathieu@573
   377
/****************************************************
mathieu@573
   378
 *      Member method implementations.
mathieu@573
   379
 ***************************************************/
mathieu@569
   380
mathieu@569
   381
template <typename T>
mathieu@567
   382
void 
mathieu@567
   383
Ptr<T>::Acquire (void) const
mathieu@567
   384
{
mathieu@567
   385
  if (m_ptr != 0)
mathieu@567
   386
    {
mathieu@567
   387
      m_ptr->Ref ();
mathieu@567
   388
    }  
mathieu@567
   389
}
mathieu@567
   390
mathieu@567
   391
template <typename T>
mathieu@223
   392
Ptr<T>::Ptr ()
raj@542
   393
  : m_ptr (0)
mathieu@223
   394
{}
mathieu@223
   395
mathieu@223
   396
template <typename T>
mathieu@223
   397
Ptr<T>::Ptr (T *ptr) 
raj@542
   398
  : m_ptr (ptr)
mathieu@567
   399
{
mathieu@567
   400
  Acquire ();
mathieu@567
   401
}
mathieu@223
   402
mathieu@223
   403
template <typename T>
mathieu@1007
   404
Ptr<T>::Ptr (T *ptr, bool ref) 
mathieu@1007
   405
  : m_ptr (ptr)
mathieu@1007
   406
{
mathieu@1007
   407
  if (ref)
mathieu@1007
   408
    {
mathieu@1007
   409
      Acquire ();
mathieu@1007
   410
    }
mathieu@1007
   411
}
mathieu@1007
   412
mathieu@1007
   413
template <typename T>
mathieu@223
   414
Ptr<T>::Ptr (Ptr const&o) 
mathieu@573
   415
  : m_ptr (PeekPointer (o))
mathieu@223
   416
{
mathieu@567
   417
  Acquire ();
mathieu@223
   418
}
mathieu@223
   419
template <typename T>
mathieu@223
   420
template <typename U>
mathieu@223
   421
Ptr<T>::Ptr (Ptr<U> const &o)
mathieu@573
   422
  : m_ptr (PeekPointer (o))
mathieu@223
   423
{
mathieu@567
   424
  Acquire ();
mathieu@223
   425
}
mathieu@223
   426
mathieu@223
   427
template <typename T>
mathieu@223
   428
Ptr<T>::~Ptr () 
mathieu@223
   429
{
mathieu@223
   430
  if (m_ptr != 0) 
mathieu@223
   431
    {
raj@542
   432
      m_ptr->Unref();
mathieu@223
   433
    }
mathieu@223
   434
}
mathieu@223
   435
mathieu@223
   436
template <typename T>
mathieu@223
   437
Ptr<T> &
mathieu@223
   438
Ptr<T>::operator = (Ptr const& o) 
mathieu@223
   439
{
gjc@426
   440
  if (&o == this)
mathieu@567
   441
    {
mathieu@567
   442
      return *this;
mathieu@567
   443
    }
mathieu@223
   444
  if (m_ptr != 0) 
mathieu@223
   445
    {
raj@542
   446
      m_ptr->Unref();
mathieu@223
   447
    }
mathieu@223
   448
  m_ptr = o.m_ptr;
mathieu@567
   449
  Acquire ();
mathieu@223
   450
  return *this;
mathieu@223
   451
}
mathieu@223
   452
mathieu@223
   453
template <typename T>
mathieu@544
   454
T *
mathieu@223
   455
Ptr<T>::operator -> () 
mathieu@223
   456
{
mathieu@223
   457
  return m_ptr;
mathieu@223
   458
}
mathieu@223
   459
mathieu@223
   460
template <typename T>
mathieu@223
   461
T *
mathieu@223
   462
Ptr<T>::operator -> () const
mathieu@223
   463
{
mathieu@223
   464
  return m_ptr;
mathieu@223
   465
}
mathieu@223
   466
mathieu@223
   467
template <typename T>
mathieu@1864
   468
const T &
mathieu@1864
   469
Ptr<T>::operator * () const
mathieu@1864
   470
{
mathieu@1864
   471
  return *m_ptr;
mathieu@1864
   472
}
mathieu@1864
   473
mathieu@1864
   474
template <typename T>
nbaldo@4329
   475
T &
mathieu@1864
   476
Ptr<T>::operator * ()
mathieu@1864
   477
{
mathieu@1864
   478
  return *m_ptr;
mathieu@1864
   479
}
mathieu@1864
   480
mathieu@1864
   481
template <typename T>
mathieu@223
   482
bool 
mathieu@223
   483
Ptr<T>::operator! () 
mathieu@223
   484
{
mathieu@223
   485
  return m_ptr == 0;
mathieu@223
   486
}
mathieu@223
   487
mathieu@223
   488
template <typename T>
mathieu@223
   489
Ptr<T>::operator Tester * () const
mathieu@223
   490
{
mathieu@223
   491
  if (m_ptr == 0) 
mathieu@223
   492
    {
mathieu@223
   493
      return 0;
mathieu@223
   494
    }
mathieu@223
   495
  static Tester test;
mathieu@223
   496
  return &test;
mathieu@223
   497
}
mathieu@223
   498
mathieu@225
   499
mathieu@223
   500
}; // namespace ns3
mathieu@223
   501
mathieu@223
   502
#endif /* PTR_H */