Back to index

lightning-sunbird  0.9+nobinonly
TestAutoPtr.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 // vim:cindent:ts=4:et:sw=4:
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is TestCOMPtrEq.cpp.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * L. David Baron.
00020  * Portions created by the Initial Developer are Copyright (C) 2001
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   L. David Baron <dbaron@dbaron.org> (original author)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsAutoPtr.h"
00041 #include <stdio.h>
00042 #include "nscore.h"
00043 
00044 class TestObjectBaseA {
00045     public:
00046         // Virtual dtor for deleting through base class pointer
00047         virtual ~TestObjectBaseA() { };
00048         int fooA;
00049 };
00050 
00051 class TestObjectBaseB {
00052     public:
00053         // Virtual dtor for deleting through base class pointer
00054         virtual ~TestObjectBaseB() { };
00055         int fooB;
00056 };
00057 
00058 class TestObject : public TestObjectBaseA, public TestObjectBaseB {
00059     public:
00060         TestObject()
00061         {
00062             printf("  Creating TestObject %p.\n",
00063                    NS_STATIC_CAST(void*, this));
00064         }
00065 
00066         // Virtual dtor for deleting through base class pointer
00067         virtual ~TestObject()
00068         {
00069             printf("  Destroying TestObject %p.\n",
00070                    NS_STATIC_CAST(void*, this));
00071         }
00072 };
00073 
00074 class TestRefObjectBaseA {
00075     public:
00076         int fooA;
00077         // Must return |nsrefcnt| to keep |nsDerivedSafe| happy.
00078         virtual nsrefcnt AddRef() = 0;
00079         virtual nsrefcnt Release() = 0;
00080 };
00081 
00082 class TestRefObjectBaseB {
00083     public:
00084         int fooB;
00085         virtual nsrefcnt AddRef() = 0;
00086         virtual nsrefcnt Release() = 0;
00087 };
00088 
00089 class TestRefObject : public TestRefObjectBaseA, public TestRefObjectBaseB {
00090     public:
00091         TestRefObject()
00092             : mRefCount(0)
00093         {
00094             printf("  Creating TestRefObject %p.\n",
00095                    NS_STATIC_CAST(void*, this));
00096         }
00097 
00098         ~TestRefObject()
00099         {
00100             printf("  Destroying TestRefObject %p.\n",
00101                    NS_STATIC_CAST(void*, this));
00102         }
00103 
00104         nsrefcnt AddRef()
00105         {
00106             ++mRefCount;
00107             printf("  AddRef to %d on TestRefObject %p.\n",
00108                    mRefCount, NS_STATIC_CAST(void*, this));
00109             return mRefCount;
00110         }
00111 
00112         nsrefcnt Release()
00113         {
00114             --mRefCount;
00115             printf("  Release to %d on TestRefObject %p.\n",
00116                    mRefCount, NS_STATIC_CAST(void*, this));
00117             if (mRefCount == 0) {
00118                 delete NS_CONST_CAST(TestRefObject*, this);
00119                 return 0;
00120             }
00121             return mRefCount;
00122         }
00123 
00124     protected:
00125         PRUint32 mRefCount;
00126 
00127 };
00128 
00129 static void CreateTestObject(TestObject **aResult)
00130 {
00131     *aResult = new TestObject();
00132 }
00133 
00134 static void CreateTestRefObject(TestRefObject **aResult)
00135 {
00136     (*aResult = new TestRefObject())->AddRef();
00137 }
00138 
00139 static void DoSomethingWithTestObject(TestObject *aIn)
00140 {
00141     printf("  Doing something with |TestObject| %p.\n",
00142            NS_STATIC_CAST(void*, aIn));
00143 }
00144 
00145 static void DoSomethingWithConstTestObject(const TestObject *aIn)
00146 {
00147     printf("  Doing something with |const TestObject| %p.\n",
00148            NS_STATIC_CAST(const void*, aIn));
00149 }
00150 
00151 static void DoSomethingWithTestRefObject(TestRefObject *aIn)
00152 {
00153     printf("  Doing something with |TestRefObject| %p.\n",
00154            NS_STATIC_CAST(void*, aIn));
00155 }
00156 
00157 static void DoSomethingWithConstTestRefObject(const TestRefObject *aIn)
00158 {
00159     printf("  Doing something with |const TestRefObject| %p.\n",
00160            NS_STATIC_CAST(const void*, aIn));
00161 }
00162 
00163 static void DoSomethingWithTestObjectBaseB(TestObjectBaseB *aIn)
00164 {
00165     printf("  Doing something with |TestObjectBaseB| %p.\n",
00166            NS_STATIC_CAST(void*, aIn));
00167 }
00168 
00169 static void DoSomethingWithConstTestObjectBaseB(const TestObjectBaseB *aIn)
00170 {
00171     printf("  Doing something with |const TestObjectBaseB| %p.\n",
00172            NS_STATIC_CAST(const void*, aIn));
00173 }
00174 
00175 static void DoSomethingWithTestRefObjectBaseB(TestRefObjectBaseB *aIn)
00176 {
00177     printf("  Doing something with |TestRefObjectBaseB| %p.\n",
00178            NS_STATIC_CAST(void*, aIn));
00179 }
00180 
00181 static void DoSomethingWithConstTestRefObjectBaseB(const TestRefObjectBaseB *aIn)
00182 {
00183     printf("  Doing something with |const TestRefObjectBaseB| %p.\n",
00184            NS_STATIC_CAST(const void*, aIn));
00185 }
00186 
00187 int main()
00188 {
00189     {
00190         printf("Should create one |TestObject|:\n");
00191         nsAutoPtr<TestObject> pobj( new TestObject() );
00192         printf("Should destroy one |TestObject|:\n");
00193     }
00194 
00195     {
00196         printf("Should create one |TestObject|:\n");
00197         nsAutoPtr<TestObject> pobj( new TestObject() );
00198         printf("Should create one |TestObject| and then destroy one:\n");
00199         pobj = new TestObject();
00200         printf("Should destroy one |TestObject|:\n");
00201     }
00202 
00203     {
00204         printf("Should create 3 |TestObject|s:\n");
00205         nsAutoArrayPtr<TestObject> pobj( new TestObject[3] );
00206         printf("Should create 5 |TestObject|s and then destroy 3:\n");
00207         pobj = new TestObject[5];
00208         printf("Should destroy 5 |TestObject|s:\n");
00209     }
00210 
00211     {
00212         printf("Should create and AddRef one |TestRefObject|:\n");
00213         nsRefPtr<TestRefObject> pobj( new TestRefObject() );
00214         printf("Should Release and destroy one |TestRefObject|:\n");
00215     }
00216 
00217     {
00218         printf("Should create and AddRef one |TestRefObject|:\n");
00219         nsRefPtr<TestRefObject> pobj( new TestRefObject() );
00220         printf("Should create and AddRef one |TestRefObject| and then Release and destroy one:\n");
00221         pobj = new TestRefObject();
00222         printf("Should Release and destroy one |TestRefObject|:\n");
00223     }
00224 
00225     {
00226         printf("Should create and AddRef one |TestRefObject|:\n");
00227         nsRefPtr<TestRefObject> p1( new TestRefObject() );
00228         printf("Should AddRef one |TestRefObject|:\n");
00229         nsRefPtr<TestRefObject> p2( p1 );
00230         printf("Should Release twice and destroy one |TestRefObject|:\n");
00231     }
00232 
00233     printf("\nTesting equality (with all const-ness combinations):\n");
00234 
00235     {
00236         nsRefPtr<TestRefObject> p1( new TestRefObject() );
00237         nsRefPtr<TestRefObject> p2( p1 );
00238         printf("equality %s.\n",
00239                ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
00240     }
00241 
00242     {
00243         const nsRefPtr<TestRefObject> p1( new TestRefObject() );
00244         nsRefPtr<TestRefObject> p2( p1 );
00245         printf("equality %s.\n",
00246                ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
00247     }
00248 
00249     {
00250         nsRefPtr<TestRefObject> p1( new TestRefObject() );
00251         const nsRefPtr<TestRefObject> p2( p1 );
00252         printf("equality %s.\n",
00253                ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
00254     }
00255 
00256     {
00257         const nsRefPtr<TestRefObject> p1( new TestRefObject() );
00258         const nsRefPtr<TestRefObject> p2( p1 );
00259         printf("equality %s.\n",
00260                ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
00261     }
00262 
00263     {
00264         nsRefPtr<TestRefObject> p1( new TestRefObject() );
00265         TestRefObject * p2 = p1;
00266         printf("equality %s.\n",
00267                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00268     }
00269 
00270     {
00271         const nsRefPtr<TestRefObject> p1( new TestRefObject() );
00272         TestRefObject * p2 = p1;
00273         printf("equality %s.\n",
00274                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00275     }
00276 
00277 #if 0 /* MSVC++ 6.0 can't be coaxed to accept this */
00278     {
00279         nsRefPtr<TestRefObject> p1( new TestRefObject() );
00280         TestRefObject * const p2 = p1;
00281         printf("equality %s.\n",
00282                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00283     }
00284 
00285     {
00286         const nsRefPtr<TestRefObject> p1( new TestRefObject() );
00287         TestRefObject * const p2 = p1;
00288         printf("equality %s.\n",
00289                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00290     }
00291 #endif /* Things that MSVC++ 6.0 can't be coaxed to accept */
00292 
00293     {
00294         nsRefPtr<TestRefObject> p1( new TestRefObject() );
00295         const TestRefObject * p2 = p1;
00296         printf("equality %s.\n",
00297                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00298     }
00299 
00300     {
00301         const nsRefPtr<TestRefObject> p1( new TestRefObject() );
00302         const TestRefObject * p2 = p1;
00303         printf("equality %s.\n",
00304                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00305     }
00306 
00307     {
00308         nsRefPtr<TestRefObject> p1( new TestRefObject() );
00309         const TestRefObject * const p2 = p1;
00310         printf("equality %s.\n",
00311                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00312     }
00313 
00314     {
00315         const nsRefPtr<TestRefObject> p1( new TestRefObject() );
00316         const TestRefObject * const p2 = p1;
00317         printf("equality %s.\n",
00318                ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
00319     }
00320 
00321     printf("\nTesting getter_Transfers and getter_AddRefs.\n");
00322 
00323     {
00324         nsAutoPtr<TestObject> ptr;
00325         printf("Should create one |TestObject|:\n");
00326         CreateTestObject(getter_Transfers(ptr));
00327         printf("Should destroy one |TestObject|:\n");
00328     }
00329 
00330     {
00331         nsRefPtr<TestRefObject> ptr;
00332         printf("Should create and AddRef one |TestRefObject|:\n");
00333         CreateTestRefObject(getter_AddRefs(ptr));
00334         printf("Should Release and destroy one |TestRefObject|:\n");
00335     }
00336 
00337     printf("\nTesting casts and equality tests.\n");
00338 
00339     if ((void*)(TestObject*)0x1000 ==
00340         (void*)(TestObjectBaseB*)(TestObject*)0x1000)
00341         printf("\n\nAll these tests are meaningless!\n\n\n");
00342 
00343     {
00344         nsAutoPtr<TestObject> p1(new TestObject());
00345         TestObjectBaseB *p2 = p1;
00346         printf("equality %s.\n",
00347                ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
00348                 (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
00349                ? "OK" : "broken");
00350     }
00351 
00352     {
00353         TestObject *p1 = new TestObject();
00354         nsAutoPtr<TestObjectBaseB> p2(p1);
00355         printf("equality %s.\n",
00356                ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
00357                 (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
00358                ? "OK" : "broken");
00359     }
00360 
00361     {
00362         nsRefPtr<TestRefObject> p1 = new TestRefObject();
00363         // nsCOMPtr requires a |get| for something like this as well
00364         nsRefPtr<TestRefObjectBaseB> p2 = p1.get();
00365         printf("equality %s.\n",
00366                ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
00367                 (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
00368                ? "OK" : "broken");
00369     }
00370 
00371     {
00372         nsRefPtr<TestRefObject> p1 = new TestRefObject();
00373         TestRefObjectBaseB *p2 = p1;
00374         printf("equality %s.\n",
00375                ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
00376                 (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
00377                ? "OK" : "broken");
00378     }
00379 
00380     {
00381         TestRefObject *p1 = new TestRefObject();
00382         nsRefPtr<TestRefObjectBaseB> p2 = p1;
00383         printf("equality %s.\n",
00384                ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
00385                 (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
00386                ? "OK" : "broken");
00387     }
00388 
00389     printf("\nTesting |forget()|.\n");
00390 
00391     {
00392         printf("Should create one |TestObject|:\n");
00393         nsAutoPtr<TestObject> pobj( new TestObject() );
00394         printf("Should do nothing:\n");
00395         nsAutoPtr<TestObject> pobj2( pobj.forget() );
00396         printf("Should destroy one |TestObject|:\n");
00397     }
00398 
00399     {
00400         printf("Should create 3 |TestObject|s:\n");
00401         nsAutoArrayPtr<TestObject> pobj( new TestObject[3] );
00402         printf("Should do nothing:\n");
00403         nsAutoArrayPtr<TestObject> pobj2( pobj.forget() );
00404         printf("Should destroy 3 |TestObject|s:\n");
00405     }
00406 
00407     printf("\nTesting construction.\n");
00408 
00409     {
00410         printf("Should create one |TestObject|:\n");
00411         nsAutoPtr<TestObject> pobj(new TestObject());
00412         printf("Should destroy one |TestObject|:\n");
00413     }
00414 
00415     {
00416         printf("Should create 3 |TestObject|s:\n");
00417         nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
00418         printf("Should destroy 3 |TestObject|s:\n");
00419     }
00420 
00421     {
00422         printf("Should create and AddRef one |TestRefObject|:\n");
00423         nsRefPtr<TestRefObject> pobj = new TestRefObject();
00424         printf("Should Release and destroy one |TestRefObject|:\n");
00425     }
00426 
00427     printf("\nTesting calling of functions (including array access and casts).\n");
00428 
00429     {
00430         printf("Should create one |TestObject|:\n");
00431         nsAutoPtr<TestObject> pobj(new TestObject());
00432         printf("Should do something with one |TestObject|:\n");
00433         DoSomethingWithTestObject(pobj);
00434         printf("Should do something with one |TestObject|:\n");
00435         DoSomethingWithConstTestObject(pobj);
00436         printf("Should destroy one |TestObject|:\n");
00437     }
00438 
00439     {
00440         printf("Should create 3 |TestObject|s:\n");
00441         nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
00442         printf("Should do something with one |TestObject|:\n");
00443         DoSomethingWithTestObject(&pobj[2]);
00444         printf("Should do something with one |TestObject|:\n");
00445         DoSomethingWithConstTestObject(&pobj[1]);
00446         printf("Should do something with one |TestObject|:\n");
00447         DoSomethingWithTestObject(pobj + 2);
00448         printf("Should do something with one |TestObject|:\n");
00449         DoSomethingWithConstTestObject(pobj + 1);
00450         printf("Should destroy 3 |TestObject|s:\n");
00451     }
00452 
00453     {
00454         printf("Should create and AddRef one |TestRefObject|:\n");
00455         nsRefPtr<TestRefObject> pobj = new TestRefObject();
00456         printf("Should do something with one |TestRefObject|:\n");
00457         DoSomethingWithTestRefObject(pobj);
00458         printf("Should do something with one |TestRefObject|:\n");
00459         DoSomethingWithConstTestRefObject(pobj);
00460         printf("Should Release and destroy one |TestRefObject|:\n");
00461     }
00462 
00463     {
00464         printf("Should create one |TestObject|:\n");
00465         nsAutoPtr<TestObject> pobj(new TestObject());
00466         printf("Should do something with one |TestObject|:\n");
00467         DoSomethingWithTestObjectBaseB(pobj);
00468         printf("Should do something with one |TestObject|:\n");
00469         DoSomethingWithConstTestObjectBaseB(pobj);
00470         printf("Should destroy one |TestObject|:\n");
00471     }
00472 
00473     {
00474         printf("Should create 3 |TestObject|s:\n");
00475         nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
00476         printf("Should do something with one |TestObject|:\n");
00477         DoSomethingWithTestObjectBaseB(&pobj[2]);
00478         printf("Should do something with one |TestObject|:\n");
00479         DoSomethingWithConstTestObjectBaseB(&pobj[1]);
00480         printf("Should do something with one |TestObject|:\n");
00481         DoSomethingWithTestObjectBaseB(pobj + 2);
00482         printf("Should do something with one |TestObject|:\n");
00483         DoSomethingWithConstTestObjectBaseB(pobj + 1);
00484         printf("Should destroy 3 |TestObject|s:\n");
00485     }
00486 
00487     {
00488         printf("Should create and AddRef one |TestRefObject|:\n");
00489         nsRefPtr<TestRefObject> pobj = new TestRefObject();
00490         printf("Should do something with one |TestRefObject|:\n");
00491         DoSomethingWithTestRefObjectBaseB(pobj);
00492         printf("Should do something with one |TestRefObject|:\n");
00493         DoSomethingWithConstTestRefObjectBaseB(pobj);
00494         printf("Should Release and destroy one |TestRefObject|:\n");
00495     }
00496 
00497     {
00498         printf("Should create one |TestObject|:\n");
00499         const nsAutoPtr<TestObject> pobj(new TestObject());
00500         printf("Should do something with one |TestObject|:\n");
00501         DoSomethingWithTestObject(pobj);
00502         printf("Should do something with one |TestObject|:\n");
00503         DoSomethingWithConstTestObject(pobj);
00504         printf("Should destroy one |TestObject|:\n");
00505     }
00506 
00507     {
00508         printf("Should create 3 |TestObject|s:\n");
00509         const nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
00510         printf("Should do something with one |TestObject|:\n");
00511         DoSomethingWithTestObject(&pobj[2]);
00512         printf("Should do something with one |TestObject|:\n");
00513         DoSomethingWithConstTestObject(&pobj[1]);
00514         printf("Should do something with one |TestObject|:\n");
00515         DoSomethingWithTestObject(pobj + 2);
00516         printf("Should do something with one |TestObject|:\n");
00517         DoSomethingWithConstTestObject(pobj + 1);
00518         printf("Should destroy 3 |TestObject|s:\n");
00519     }
00520 
00521     {
00522         printf("Should create and AddRef one |TestRefObject|:\n");
00523         const nsRefPtr<TestRefObject> pobj = new TestRefObject();
00524         printf("Should do something with one |TestRefObject|:\n");
00525         DoSomethingWithTestRefObject(pobj);
00526         printf("Should do something with one |TestRefObject|:\n");
00527         DoSomethingWithConstTestRefObject(pobj);
00528         printf("Should Release and destroy one |TestRefObject|:\n");
00529     }
00530 
00531     {
00532         printf("Should create one |TestObject|:\n");
00533         const nsAutoPtr<TestObject> pobj(new TestObject());
00534         printf("Should do something with one |TestObject|:\n");
00535         DoSomethingWithTestObjectBaseB(pobj);
00536         printf("Should do something with one |TestObject|:\n");
00537         DoSomethingWithConstTestObjectBaseB(pobj);
00538         printf("Should destroy one |TestObject|:\n");
00539     }
00540 
00541     {
00542         printf("Should create 3 |TestObject|s:\n");
00543         const nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
00544         printf("Should do something with one |TestObject|:\n");
00545         DoSomethingWithTestObjectBaseB(&pobj[2]);
00546         printf("Should do something with one |TestObject|:\n");
00547         DoSomethingWithConstTestObjectBaseB(&pobj[1]);
00548         printf("Should do something with one |TestObject|:\n");
00549         DoSomethingWithTestObjectBaseB(pobj + 2);
00550         printf("Should do something with one |TestObject|:\n");
00551         DoSomethingWithConstTestObjectBaseB(pobj + 1);
00552         printf("Should destroy 3 |TestObject|s:\n");
00553     }
00554 
00555     {
00556         printf("Should create and AddRef one |TestRefObject|:\n");
00557         const nsRefPtr<TestRefObject> pobj = new TestRefObject();
00558         printf("Should do something with one |TestRefObject|:\n");
00559         DoSomethingWithTestRefObjectBaseB(pobj);
00560         printf("Should do something with one |TestRefObject|:\n");
00561         DoSomethingWithConstTestRefObjectBaseB(pobj);
00562         printf("Should Release and destroy one |TestRefObject|:\n");
00563     }
00564 
00565     return 0;
00566 }