00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2005,2006 INRIA 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 * 00018 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 00019 */ 00020 #include "ptr.h" 00021 00022 #ifdef RUN_SELF_TESTS 00023 00024 #include "test.h" 00025 00026 namespace ns3 { 00027 00028 class NoCount; 00029 00030 template <typename T> 00031 void Foo (void) {} 00032 00033 class PtrTest : Test 00034 { 00035 public: 00036 PtrTest (); 00037 virtual ~PtrTest (); 00038 virtual bool RunTests (void); 00039 void DestroyNotify (void); 00040 private: 00041 Ptr<NoCount> CallTest (Ptr<NoCount> p); 00042 Ptr<NoCount> const CallTestConst (Ptr<NoCount> const p); 00043 uint32_t m_nDestroyed; 00044 }; 00045 00046 00047 class Base 00048 { 00049 public: 00050 Base (); 00051 virtual ~Base (); 00052 void Ref (void) const; 00053 void Unref (void) const; 00054 private: 00055 mutable uint32_t m_count; 00056 }; 00057 00058 class NoCount : public Base 00059 { 00060 public: 00061 NoCount (PtrTest *test); 00062 ~NoCount (); 00063 void Nothing (void) const; 00064 private: 00065 PtrTest *m_test; 00066 }; 00067 00068 Base::Base () 00069 : m_count (1) 00070 {} 00071 Base::~Base () 00072 {} 00073 void 00074 Base::Ref (void) const 00075 { 00076 m_count++; 00077 } 00078 void 00079 Base::Unref (void) const 00080 { 00081 m_count--; 00082 if (m_count == 0) 00083 { 00084 delete this; 00085 } 00086 } 00087 00088 NoCount::NoCount (PtrTest *test) 00089 : m_test (test) 00090 {} 00091 NoCount::~NoCount () 00092 { 00093 m_test->DestroyNotify (); 00094 } 00095 void 00096 NoCount::Nothing () const 00097 {} 00098 00099 PtrTest::PtrTest () 00100 : Test ("Ptr") 00101 {} 00102 00103 PtrTest::~PtrTest () 00104 {} 00105 00106 void 00107 PtrTest::DestroyNotify (void) 00108 { 00109 m_nDestroyed++; 00110 } 00111 Ptr<NoCount> 00112 PtrTest::CallTest (Ptr<NoCount> p) 00113 { 00114 return p; 00115 } 00116 00117 Ptr<NoCount> const 00118 PtrTest::CallTestConst (Ptr<NoCount> const p) 00119 { 00120 return p; 00121 } 00122 00123 bool 00124 PtrTest::RunTests (void) 00125 { 00126 bool ok = true; 00127 00128 m_nDestroyed = false; 00129 { 00130 Ptr<NoCount> p = Create<NoCount> (this); 00131 } 00132 if (m_nDestroyed != 1) 00133 { 00134 ok = false; 00135 } 00136 00137 m_nDestroyed = 0; 00138 { 00139 Ptr<NoCount> p; 00140 p = Create<NoCount> (this); 00141 p = p; 00142 } 00143 if (m_nDestroyed != 1) 00144 { 00145 ok = false; 00146 } 00147 00148 m_nDestroyed = 0; 00149 { 00150 Ptr<NoCount> p1; 00151 p1 = Create<NoCount> (this); 00152 Ptr<NoCount> p2 = p1; 00153 } 00154 if (m_nDestroyed != 1) 00155 { 00156 ok = false; 00157 } 00158 00159 m_nDestroyed = 0; 00160 { 00161 Ptr<NoCount> p1; 00162 p1 = Create<NoCount> (this); 00163 Ptr<NoCount> p2; 00164 p2 = p1; 00165 } 00166 if (m_nDestroyed != 1) 00167 { 00168 ok = false; 00169 } 00170 00171 m_nDestroyed = 0; 00172 { 00173 Ptr<NoCount> p1; 00174 p1 = Create<NoCount> (this); 00175 Ptr<NoCount> p2 = Create<NoCount> (this); 00176 p2 = p1; 00177 } 00178 if (m_nDestroyed != 2) 00179 { 00180 ok = false; 00181 } 00182 00183 m_nDestroyed = 0; 00184 { 00185 Ptr<NoCount> p1; 00186 p1 = Create<NoCount> (this); 00187 Ptr<NoCount> p2; 00188 p2 = Create<NoCount> (this); 00189 p2 = p1; 00190 } 00191 if (m_nDestroyed != 2) 00192 { 00193 ok = false; 00194 } 00195 00196 m_nDestroyed = 0; 00197 { 00198 Ptr<NoCount> p1; 00199 p1 = Create<NoCount> (this); 00200 p1 = Create<NoCount> (this); 00201 } 00202 if (m_nDestroyed != 2) 00203 { 00204 ok = false; 00205 } 00206 00207 m_nDestroyed = 0; 00208 { 00209 Ptr<NoCount> p1; 00210 { 00211 Ptr<NoCount> p2; 00212 p1 = Create<NoCount> (this); 00213 p2 = Create<NoCount> (this); 00214 p2 = p1; 00215 } 00216 if (m_nDestroyed != 1) 00217 { 00218 ok = false; 00219 } 00220 } 00221 if (m_nDestroyed != 2) 00222 { 00223 ok = false; 00224 } 00225 00226 m_nDestroyed = 0; 00227 { 00228 Ptr<NoCount> p1; 00229 { 00230 Ptr<NoCount> p2; 00231 p1 = Create<NoCount> (this); 00232 p2 = Create<NoCount> (this); 00233 p2 = CallTest (p1); 00234 } 00235 if (m_nDestroyed != 1) 00236 { 00237 ok = false; 00238 } 00239 } 00240 if (m_nDestroyed != 2) 00241 { 00242 ok = false; 00243 } 00244 00245 { 00246 Ptr<NoCount> p1; 00247 Ptr<NoCount> const p2 = CallTest (p1); 00248 Ptr<NoCount> const p3 = CallTestConst (p1); 00249 Ptr<NoCount> p4 = CallTestConst (p1); 00250 Ptr<NoCount const> p5 = p4; 00251 //p4 = p5; You cannot make a const pointer be a non-const pointer. 00252 // but if you use ConstCast, you can. 00253 p4 = ConstCast<NoCount> (p5); 00254 p5 = p1; 00255 Ptr<NoCount> p; 00256 if (p == 0) 00257 {} 00258 if (p != 0) 00259 {} 00260 if (0 == p) 00261 {} 00262 if (0 != p) 00263 {} 00264 if (p) 00265 {} 00266 if (!p) 00267 {} 00268 } 00269 00270 m_nDestroyed = 0; 00271 { 00272 NoCount *raw; 00273 { 00274 Ptr<NoCount> p = Create<NoCount> (this); 00275 { 00276 Ptr<NoCount const> p1 = p; 00277 } 00278 raw = GetPointer (p); 00279 p = 0; 00280 } 00281 if (m_nDestroyed != 0) 00282 { 00283 ok = false; 00284 } 00285 delete raw; 00286 } 00287 00288 m_nDestroyed = 0; 00289 { 00290 Ptr<NoCount> p = Create<NoCount> (this); 00291 const NoCount *v1 = PeekPointer (p); 00292 NoCount *v2 = PeekPointer (p); 00293 v1->Nothing (); 00294 v2->Nothing (); 00295 } 00296 if (m_nDestroyed != 1) 00297 { 00298 ok = false; 00299 } 00300 00301 { 00302 Ptr<Base> p0 = Create<NoCount> (this); 00303 Ptr<NoCount> p1 = Create<NoCount> (this); 00304 if (p0 == p1) 00305 { 00306 ok = false; 00307 } 00308 if (p0 != p1) 00309 { 00310 } 00311 else 00312 { 00313 ok = false; 00314 } 00315 } 00316 #if 0 00317 { 00318 Ptr<NoCount> p = Create<NoCount> (cb); 00319 Callback<void> callback = MakeCallback (&NoCount::Nothing, p); 00320 callback (); 00321 } 00322 { 00323 Ptr<const NoCount> p = Create<NoCount> (cb); 00324 Callback<void> callback = MakeCallback (&NoCount::Nothing, p); 00325 callback (); 00326 } 00327 #endif 00328 00329 #if 0 00330 // as expected, fails compilation. 00331 { 00332 Ptr<const Base> p = Create<NoCount> (cb); 00333 Callback<void> callback = MakeCallback (&NoCount::Nothing, p); 00334 } 00335 // local types are not allowed as arguments to a template. 00336 { 00337 class B 00338 { 00339 public: 00340 B () {} 00341 }; 00342 Foo<B> (); 00343 } 00344 #endif 00345 00346 00347 return ok; 00348 } 00349 00350 PtrTest g_ptr_test; 00351 00352 }; // namespace ns3 00353 00354 #endif /* RUN_SELF_TESTS */