src/core/ptr.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 2834 1aab57845b07
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
#include "ptr.h"
mathieu@223
    21
mathieu@223
    22
#ifdef RUN_SELF_TESTS
mathieu@223
    23
mathieu@223
    24
#include "test.h"
mathieu@223
    25
mathieu@223
    26
namespace ns3 {
mathieu@223
    27
mathieu@2229
    28
class NoCount;
mathieu@2229
    29
mathieu@1007
    30
template <typename T>
mathieu@1007
    31
void Foo (void) {}
mathieu@1007
    32
mathieu@223
    33
class PtrTest : Test
mathieu@223
    34
{
mathieu@223
    35
public:
mathieu@223
    36
  PtrTest ();
mathieu@223
    37
  virtual ~PtrTest ();
mathieu@223
    38
  virtual bool RunTests (void);
mathieu@2229
    39
  void DestroyNotify (void);
mathieu@223
    40
private:
mathieu@224
    41
  Ptr<NoCount> CallTest (Ptr<NoCount> p);
mathieu@225
    42
  Ptr<NoCount> const CallTestConst (Ptr<NoCount> const p);
mathieu@224
    43
  uint32_t m_nDestroyed;
mathieu@223
    44
};
mathieu@223
    45
mathieu@2229
    46
mathieu@2630
    47
class Base
mathieu@2229
    48
{
mathieu@2229
    49
public:
mathieu@2229
    50
  Base ();
mathieu@2229
    51
  virtual ~Base ();
mathieu@2229
    52
  void Ref (void) const;
mathieu@2229
    53
  void Unref (void) const;
mathieu@2229
    54
private:
mathieu@2229
    55
  mutable uint32_t m_count;
mathieu@2229
    56
};
mathieu@2229
    57
mathieu@2229
    58
class NoCount : public Base
mathieu@2229
    59
{
mathieu@2229
    60
public:
mathieu@2229
    61
  NoCount (PtrTest *test);
mathieu@2229
    62
  ~NoCount ();
mathieu@2229
    63
  void Nothing (void) const;
mathieu@2229
    64
private:
mathieu@2229
    65
  PtrTest *m_test;
mathieu@2229
    66
};
mathieu@2229
    67
mathieu@2229
    68
Base::Base ()
mathieu@2229
    69
  : m_count (1)
mathieu@2229
    70
{}
mathieu@2229
    71
Base::~Base ()
mathieu@2229
    72
{}
mathieu@2229
    73
void 
mathieu@2229
    74
Base::Ref (void) const
mathieu@2229
    75
{
mathieu@2229
    76
  m_count++;
mathieu@2229
    77
}
mathieu@2229
    78
void 
mathieu@2229
    79
Base::Unref (void) const
mathieu@2229
    80
{
mathieu@2229
    81
  m_count--;
mathieu@2229
    82
  if (m_count == 0)
mathieu@2229
    83
    {
mathieu@2229
    84
      delete this;
mathieu@2229
    85
    }
mathieu@2229
    86
}
mathieu@2229
    87
mathieu@2229
    88
NoCount::NoCount (PtrTest *test)
mathieu@2229
    89
  : m_test (test)
mathieu@2229
    90
{}
mathieu@2229
    91
NoCount::~NoCount ()
mathieu@2229
    92
{
mathieu@2229
    93
  m_test->DestroyNotify ();
mathieu@2229
    94
}
mathieu@2229
    95
void
mathieu@2229
    96
NoCount::Nothing () const
mathieu@2229
    97
{}
mathieu@2229
    98
mathieu@223
    99
PtrTest::PtrTest ()
mathieu@223
   100
  : Test ("Ptr")
mathieu@223
   101
{}
mathieu@223
   102
mathieu@223
   103
PtrTest::~PtrTest ()
mathieu@223
   104
{}
mathieu@223
   105
mathieu@223
   106
void 
mathieu@223
   107
PtrTest::DestroyNotify (void)
mathieu@223
   108
{
mathieu@224
   109
  m_nDestroyed++;
mathieu@223
   110
}
mathieu@224
   111
Ptr<NoCount> 
mathieu@224
   112
PtrTest::CallTest (Ptr<NoCount> p)
mathieu@224
   113
{
mathieu@224
   114
  return p;
mathieu@224
   115
}
mathieu@223
   116
mathieu@225
   117
Ptr<NoCount> const 
mathieu@225
   118
PtrTest::CallTestConst (Ptr<NoCount> const p)
mathieu@225
   119
{
mathieu@225
   120
  return p;
mathieu@225
   121
}
mathieu@225
   122
mathieu@223
   123
bool
mathieu@223
   124
PtrTest::RunTests (void)
mathieu@223
   125
{
mathieu@223
   126
  bool ok = true;
mathieu@223
   127
mathieu@224
   128
  m_nDestroyed = false;
mathieu@223
   129
  {
mathieu@2229
   130
    Ptr<NoCount> p = Create<NoCount> (this);
mathieu@223
   131
  }
mathieu@224
   132
  if (m_nDestroyed != 1)
mathieu@223
   133
    {
mathieu@223
   134
      ok = false;
mathieu@223
   135
    }
mathieu@224
   136
mathieu@224
   137
  m_nDestroyed = 0;
mathieu@223
   138
  {
mathieu@223
   139
    Ptr<NoCount> p;
mathieu@2229
   140
    p = Create<NoCount> (this);
mathieu@225
   141
    p = p;
mathieu@223
   142
  }
mathieu@224
   143
  if (m_nDestroyed != 1)
mathieu@224
   144
    {
mathieu@224
   145
      ok = false;
mathieu@224
   146
    }
mathieu@224
   147
mathieu@224
   148
  m_nDestroyed = 0;
mathieu@224
   149
  {
mathieu@224
   150
    Ptr<NoCount> p1;
mathieu@2229
   151
    p1 = Create<NoCount> (this);
mathieu@224
   152
    Ptr<NoCount> p2 = p1;
mathieu@224
   153
  }
mathieu@224
   154
  if (m_nDestroyed != 1)
mathieu@224
   155
    {
mathieu@224
   156
      ok = false;
mathieu@224
   157
    }
mathieu@224
   158
mathieu@224
   159
  m_nDestroyed = 0;
mathieu@224
   160
  {
mathieu@224
   161
    Ptr<NoCount> p1;
mathieu@2229
   162
    p1 = Create<NoCount> (this);
mathieu@224
   163
    Ptr<NoCount> p2;
mathieu@224
   164
    p2 = p1;
mathieu@224
   165
  }
mathieu@224
   166
  if (m_nDestroyed != 1)
mathieu@224
   167
    {
mathieu@224
   168
      ok = false;
mathieu@224
   169
    }
mathieu@224
   170
mathieu@224
   171
  m_nDestroyed = 0;
mathieu@224
   172
  {
mathieu@224
   173
    Ptr<NoCount> p1;
mathieu@2229
   174
    p1 = Create<NoCount> (this);
mathieu@2229
   175
    Ptr<NoCount> p2 = Create<NoCount> (this);
mathieu@224
   176
    p2 = p1;
mathieu@224
   177
  }
mathieu@224
   178
  if (m_nDestroyed != 2)
mathieu@224
   179
    {
mathieu@224
   180
      ok = false;
mathieu@224
   181
    }
mathieu@224
   182
mathieu@224
   183
  m_nDestroyed = 0;
mathieu@224
   184
  {
mathieu@224
   185
    Ptr<NoCount> p1;
mathieu@2229
   186
    p1 = Create<NoCount> (this);
mathieu@224
   187
    Ptr<NoCount> p2;
mathieu@2229
   188
    p2 = Create<NoCount> (this);
mathieu@224
   189
    p2 = p1;
mathieu@224
   190
  }
mathieu@224
   191
  if (m_nDestroyed != 2)
mathieu@224
   192
    {
mathieu@224
   193
      ok = false;
mathieu@224
   194
    }
mathieu@224
   195
mathieu@224
   196
  m_nDestroyed = 0;
mathieu@224
   197
  {
mathieu@224
   198
    Ptr<NoCount> p1;
mathieu@2229
   199
    p1 = Create<NoCount> (this);
mathieu@2229
   200
    p1 = Create<NoCount> (this);
mathieu@224
   201
  }
mathieu@224
   202
  if (m_nDestroyed != 2)
mathieu@224
   203
    {
mathieu@224
   204
      ok = false;
mathieu@224
   205
    }
mathieu@224
   206
mathieu@224
   207
  m_nDestroyed = 0;
mathieu@224
   208
  {
mathieu@224
   209
    Ptr<NoCount> p1;
mathieu@224
   210
    {
mathieu@224
   211
      Ptr<NoCount> p2;
mathieu@2229
   212
      p1 = Create<NoCount> (this);
mathieu@2229
   213
      p2 = Create<NoCount> (this);
mathieu@224
   214
      p2 = p1;
mathieu@224
   215
    }
mathieu@224
   216
    if (m_nDestroyed != 1)
mathieu@224
   217
      {
mathieu@224
   218
        ok = false;
mathieu@224
   219
      }
mathieu@224
   220
  }
mathieu@224
   221
  if (m_nDestroyed != 2)
mathieu@224
   222
    {
mathieu@224
   223
      ok = false;
mathieu@224
   224
    }
mathieu@224
   225
mathieu@224
   226
  m_nDestroyed = 0;
mathieu@224
   227
  {
mathieu@224
   228
    Ptr<NoCount> p1;
mathieu@224
   229
    {
mathieu@224
   230
      Ptr<NoCount> p2;
mathieu@2229
   231
      p1 = Create<NoCount> (this);
mathieu@2229
   232
      p2 = Create<NoCount> (this);
mathieu@224
   233
      p2 = CallTest (p1);
mathieu@224
   234
    }
mathieu@224
   235
    if (m_nDestroyed != 1)
mathieu@224
   236
      {
mathieu@224
   237
        ok = false;
mathieu@224
   238
      }
mathieu@224
   239
  }
mathieu@224
   240
  if (m_nDestroyed != 2)
mathieu@223
   241
    {
mathieu@223
   242
      ok = false;
mathieu@223
   243
    }
mathieu@225
   244
mathieu@225
   245
  {
mathieu@225
   246
    Ptr<NoCount> p1;
mathieu@225
   247
    Ptr<NoCount> const p2 = CallTest (p1);
mathieu@225
   248
    Ptr<NoCount> const p3 = CallTestConst (p1);
mathieu@225
   249
    Ptr<NoCount> p4 = CallTestConst (p1);
mathieu@225
   250
    Ptr<NoCount const> p5 = p4;
mathieu@225
   251
    //p4 = p5; You cannot make a const pointer be a non-const pointer.
mathieu@3767
   252
    // but if you use ConstCast, you can.
mathieu@3767
   253
    p4 = ConstCast<NoCount> (p5);
mathieu@225
   254
    p5 = p1;
mathieu@225
   255
    Ptr<NoCount> p;
mathieu@225
   256
    if (p == 0)
mathieu@225
   257
      {}
mathieu@225
   258
    if (p != 0)
mathieu@225
   259
      {}
mathieu@225
   260
    if (0 == p)
mathieu@225
   261
      {}
mathieu@225
   262
    if (0 != p)
mathieu@225
   263
      {}
mathieu@225
   264
    if (p)
mathieu@225
   265
      {}
mathieu@225
   266
    if (!p)
mathieu@225
   267
      {}
mathieu@225
   268
  }
mathieu@225
   269
mathieu@225
   270
  m_nDestroyed = 0;
mathieu@225
   271
  {
mathieu@225
   272
    NoCount *raw;
mathieu@225
   273
    {
mathieu@2229
   274
      Ptr<NoCount> p = Create<NoCount> (this);
mathieu@225
   275
      {
mathieu@225
   276
        Ptr<NoCount const> p1 = p;
mathieu@225
   277
      }
mathieu@573
   278
      raw = GetPointer (p);
mathieu@544
   279
      p = 0;
mathieu@225
   280
    }
mathieu@225
   281
    if (m_nDestroyed != 0)
mathieu@225
   282
      {
mathieu@225
   283
        ok = false;
mathieu@225
   284
      }
mathieu@225
   285
    delete raw;
mathieu@225
   286
  }
mathieu@227
   287
mathieu@227
   288
  m_nDestroyed = 0;
mathieu@227
   289
  {
mathieu@2229
   290
    Ptr<NoCount> p = Create<NoCount> (this);
mathieu@573
   291
    const NoCount *v1 = PeekPointer (p);
mathieu@573
   292
    NoCount *v2 = PeekPointer (p);
mathieu@544
   293
    v1->Nothing ();
mathieu@544
   294
    v2->Nothing ();
mathieu@227
   295
  }
mathieu@544
   296
  if (m_nDestroyed != 1)
mathieu@227
   297
    {
mathieu@227
   298
      ok = false;
mathieu@227
   299
    }
mathieu@567
   300
mathieu@567
   301
  {
mathieu@2229
   302
    Ptr<Base> p0 = Create<NoCount> (this);
mathieu@2229
   303
    Ptr<NoCount> p1 = Create<NoCount> (this);
mathieu@567
   304
    if (p0 == p1)
mathieu@567
   305
      {
mathieu@567
   306
        ok = false;
mathieu@567
   307
      }
mathieu@567
   308
    if (p0 != p1)
mathieu@567
   309
      {
mathieu@567
   310
      }
mathieu@567
   311
    else
mathieu@567
   312
      {
mathieu@567
   313
        ok = false;
mathieu@567
   314
      }
mathieu@567
   315
  }
mathieu@2229
   316
#if 0
mathieu@685
   317
  {
mathieu@2370
   318
    Ptr<NoCount> p = Create<NoCount> (cb);
mathieu@685
   319
    Callback<void> callback = MakeCallback (&NoCount::Nothing, p);
mathieu@689
   320
    callback ();
mathieu@685
   321
  }
mathieu@685
   322
  {
mathieu@2370
   323
    Ptr<const NoCount> p = Create<NoCount> (cb);
mathieu@685
   324
    Callback<void> callback = MakeCallback (&NoCount::Nothing, p);
mathieu@689
   325
    callback ();
mathieu@685
   326
  }
mathieu@2229
   327
#endif
mathieu@1007
   328
mathieu@685
   329
#if 0
mathieu@685
   330
  // as expected, fails compilation.
mathieu@685
   331
  {
mathieu@2229
   332
    Ptr<const Base> p = Create<NoCount> (cb);
mathieu@685
   333
    Callback<void> callback = MakeCallback (&NoCount::Nothing, p);
mathieu@685
   334
  }
mathieu@1007
   335
  // local types are not allowed as arguments to a template.
mathieu@1007
   336
  {
mathieu@1007
   337
    class B
mathieu@1007
   338
    {
mathieu@1007
   339
    public:
mathieu@1007
   340
      B () {}
mathieu@1007
   341
    };
mathieu@1007
   342
    Foo<B> ();
mathieu@1007
   343
  }
mathieu@685
   344
#endif
mathieu@223
   345
  
mathieu@223
   346
mathieu@223
   347
  return ok;
mathieu@223
   348
}
mathieu@223
   349
mathieu@223
   350
PtrTest g_ptr_test;
mathieu@223
   351
mathieu@223
   352
}; // namespace ns3
mathieu@223
   353
mathieu@223
   354
#endif /* RUN_SELF_TESTS */