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