refcnttest.cc revision 7824
17824Sgblack@eecs.umich.edu/* 27824Sgblack@eecs.umich.edu * Copyright (c) 2010 The Regents of The University of Michigan 37824Sgblack@eecs.umich.edu * All rights reserved. 47824Sgblack@eecs.umich.edu * 57824Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67824Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77824Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87824Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97824Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107824Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117824Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127824Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137824Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147824Sgblack@eecs.umich.edu * this software without specific prior written permission. 157824Sgblack@eecs.umich.edu * 167824Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177824Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187824Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197824Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207824Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217824Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227824Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237824Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247824Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257824Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267824Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277824Sgblack@eecs.umich.edu * 287824Sgblack@eecs.umich.edu * Authors: Gabe Black 297824Sgblack@eecs.umich.edu */ 307824Sgblack@eecs.umich.edu 317824Sgblack@eecs.umich.edu#include <cassert> 327824Sgblack@eecs.umich.edu#include <iostream> 337824Sgblack@eecs.umich.edu#include <list> 347824Sgblack@eecs.umich.edu 357824Sgblack@eecs.umich.edu#include "base/refcnt.hh" 367824Sgblack@eecs.umich.edu 377824Sgblack@eecs.umich.eduusing namespace std; 387824Sgblack@eecs.umich.edu 397824Sgblack@eecs.umich.edunamespace { 407824Sgblack@eecs.umich.edu 417824Sgblack@eecs.umich.educlass TestRC; 427824Sgblack@eecs.umich.edutypedef list<TestRC *> LiveList; 437824Sgblack@eecs.umich.eduLiveList liveList; 447824Sgblack@eecs.umich.edu 457824Sgblack@eecs.umich.eduint 467824Sgblack@eecs.umich.edulive() 477824Sgblack@eecs.umich.edu{ 487824Sgblack@eecs.umich.edu return liveList.size(); 497824Sgblack@eecs.umich.edu} 507824Sgblack@eecs.umich.edu 517824Sgblack@eecs.umich.eduint 527824Sgblack@eecs.umich.eduliveChange() 537824Sgblack@eecs.umich.edu{ 547824Sgblack@eecs.umich.edu static int oldLive = 0; 557824Sgblack@eecs.umich.edu int newLive = live(); 567824Sgblack@eecs.umich.edu int diff = newLive - oldLive; 577824Sgblack@eecs.umich.edu oldLive = newLive; 587824Sgblack@eecs.umich.edu return diff; 597824Sgblack@eecs.umich.edu} 607824Sgblack@eecs.umich.edu 617824Sgblack@eecs.umich.educlass TestRC : public RefCounted 627824Sgblack@eecs.umich.edu{ 637824Sgblack@eecs.umich.edu protected: 647824Sgblack@eecs.umich.edu const char *_tag; 657824Sgblack@eecs.umich.edu LiveList::iterator liveIt; 667824Sgblack@eecs.umich.edu 677824Sgblack@eecs.umich.edu public: 687824Sgblack@eecs.umich.edu TestRC(const char *newTag) : _tag(newTag) 697824Sgblack@eecs.umich.edu { 707824Sgblack@eecs.umich.edu cout << " Creating object \"" << _tag << "\"\n"; 717824Sgblack@eecs.umich.edu liveList.push_front(this); 727824Sgblack@eecs.umich.edu liveIt = liveList.begin(); 737824Sgblack@eecs.umich.edu } 747824Sgblack@eecs.umich.edu 757824Sgblack@eecs.umich.edu ~TestRC() 767824Sgblack@eecs.umich.edu { 777824Sgblack@eecs.umich.edu cout << " Destroying object \"" << _tag << "\"\n"; 787824Sgblack@eecs.umich.edu liveList.erase(liveIt); 797824Sgblack@eecs.umich.edu } 807824Sgblack@eecs.umich.edu 817824Sgblack@eecs.umich.edu const char * 827824Sgblack@eecs.umich.edu tag() 837824Sgblack@eecs.umich.edu { 847824Sgblack@eecs.umich.edu return _tag; 857824Sgblack@eecs.umich.edu } 867824Sgblack@eecs.umich.edu 877824Sgblack@eecs.umich.edu int testVal; 887824Sgblack@eecs.umich.edu}; 897824Sgblack@eecs.umich.edu 907824Sgblack@eecs.umich.edutypedef RefCountingPtr<TestRC> Ptr; 917824Sgblack@eecs.umich.edu 927824Sgblack@eecs.umich.edu} 937824Sgblack@eecs.umich.edu 947824Sgblack@eecs.umich.eduint 957824Sgblack@eecs.umich.edumain() 967824Sgblack@eecs.umich.edu{ 977824Sgblack@eecs.umich.edu assert(live() == 0); 987824Sgblack@eecs.umich.edu assert(liveChange() == 0); 997824Sgblack@eecs.umich.edu 1007824Sgblack@eecs.umich.edu // Create an empty Ptr and verify it's data pointer is NULL. 1017824Sgblack@eecs.umich.edu cout << "NULL check.\n"; 1027824Sgblack@eecs.umich.edu Ptr nullCheck; 1037824Sgblack@eecs.umich.edu assert(nullCheck.get() == NULL); 1047824Sgblack@eecs.umich.edu 1057824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1067824Sgblack@eecs.umich.edu 1077824Sgblack@eecs.umich.edu // Construct a Ptr from a TestRC pointer. 1087824Sgblack@eecs.umich.edu cout << "Construction from pointer.\n"; 1097824Sgblack@eecs.umich.edu Ptr constFromPointer = new TestRC("construction from pointer"); 1107824Sgblack@eecs.umich.edu 1117824Sgblack@eecs.umich.edu assert(liveChange() == 1); 1127824Sgblack@eecs.umich.edu 1137824Sgblack@eecs.umich.edu // Construct a Ptr from an existing Ptr. 1147824Sgblack@eecs.umich.edu cout << "Construction from a Ptr.\n"; 1157824Sgblack@eecs.umich.edu Ptr constFromPtr = constFromPointer; 1167824Sgblack@eecs.umich.edu 1177824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1187824Sgblack@eecs.umich.edu 1197824Sgblack@eecs.umich.edu // Test a Ptr being destroyed. 1207824Sgblack@eecs.umich.edu cout << "Destroying a Ptr.\n"; 1217824Sgblack@eecs.umich.edu Ptr *ptrPtr = new Ptr(new TestRC("destroying a ptr")); 1227824Sgblack@eecs.umich.edu assert(liveChange() == 1); 1237824Sgblack@eecs.umich.edu delete ptrPtr; 1247824Sgblack@eecs.umich.edu assert(liveChange() == -1); 1257824Sgblack@eecs.umich.edu 1267824Sgblack@eecs.umich.edu // Test assignment from a pointer and from a Ptr. 1277824Sgblack@eecs.umich.edu cout << "Assignment operators.\n"; 1287824Sgblack@eecs.umich.edu Ptr assignmentTarget; 1297824Sgblack@eecs.umich.edu TestRC *assignmentSourcePointer = new TestRC("assignment source 1"); 1307824Sgblack@eecs.umich.edu assert(liveChange() == 1); 1317824Sgblack@eecs.umich.edu assignmentTarget = assignmentSourcePointer; 1327824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1337824Sgblack@eecs.umich.edu assignmentTarget = NULL; 1347824Sgblack@eecs.umich.edu assert(liveChange() == -1); 1357824Sgblack@eecs.umich.edu Ptr assignmentSourcePtr(new TestRC("assignment source 2")); 1367824Sgblack@eecs.umich.edu assert(liveChange() == 1); 1377824Sgblack@eecs.umich.edu assignmentTarget = assignmentSourcePtr; 1387824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1397824Sgblack@eecs.umich.edu assignmentSourcePtr = NULL; 1407824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1417824Sgblack@eecs.umich.edu assignmentTarget = NULL; 1427824Sgblack@eecs.umich.edu assert(liveChange() == -1); 1437824Sgblack@eecs.umich.edu 1447824Sgblack@eecs.umich.edu // Test access to members of the pointed to class and dereferencing. 1457824Sgblack@eecs.umich.edu cout << "Access to members.\n"; 1467824Sgblack@eecs.umich.edu TestRC *accessTest = new TestRC("access test"); 1477824Sgblack@eecs.umich.edu Ptr accessTestPtr = accessTest; 1487824Sgblack@eecs.umich.edu accessTest->testVal = 1; 1497824Sgblack@eecs.umich.edu assert(accessTestPtr->testVal == 1); 1507824Sgblack@eecs.umich.edu assert((*accessTestPtr).testVal == 1); 1517824Sgblack@eecs.umich.edu accessTest->testVal = 2; 1527824Sgblack@eecs.umich.edu assert(accessTestPtr->testVal == 2); 1537824Sgblack@eecs.umich.edu assert((*accessTestPtr).testVal == 2); 1547824Sgblack@eecs.umich.edu accessTestPtr->testVal = 3; 1557824Sgblack@eecs.umich.edu assert(accessTest->testVal == 3); 1567824Sgblack@eecs.umich.edu (*accessTestPtr).testVal = 4; 1577824Sgblack@eecs.umich.edu assert(accessTest->testVal == 4); 1587824Sgblack@eecs.umich.edu accessTestPtr = NULL; 1597824Sgblack@eecs.umich.edu accessTest = NULL; 1607824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1617824Sgblack@eecs.umich.edu 1627824Sgblack@eecs.umich.edu // Test bool and ! operator overloads. 1637824Sgblack@eecs.umich.edu cout << "Conversion to bool and ! overload.\n"; 1647824Sgblack@eecs.umich.edu Ptr boolTest = new TestRC("bool test"); 1657824Sgblack@eecs.umich.edu assert(boolTest == true); 1667824Sgblack@eecs.umich.edu assert(!boolTest == false); 1677824Sgblack@eecs.umich.edu boolTest = NULL; 1687824Sgblack@eecs.umich.edu assert(boolTest == false); 1697824Sgblack@eecs.umich.edu assert(!boolTest == true); 1707824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1717824Sgblack@eecs.umich.edu 1727824Sgblack@eecs.umich.edu // Test the equality operators. 1737824Sgblack@eecs.umich.edu cout << "Equality operators.\n"; 1747824Sgblack@eecs.umich.edu TestRC *equalTestA = new TestRC("equal test a"); 1757824Sgblack@eecs.umich.edu Ptr equalTestAPtr = equalTestA; 1767824Sgblack@eecs.umich.edu Ptr equalTestAPtr2 = equalTestA; 1777824Sgblack@eecs.umich.edu TestRC *equalTestB = new TestRC("equal test b"); 1787824Sgblack@eecs.umich.edu Ptr equalTestBPtr = equalTestB; 1797824Sgblack@eecs.umich.edu assert(equalTestA == equalTestAPtr); 1807824Sgblack@eecs.umich.edu assert(equalTestAPtr == equalTestA); 1817824Sgblack@eecs.umich.edu assert(equalTestAPtr == equalTestAPtr2); 1827824Sgblack@eecs.umich.edu assert(equalTestA != equalTestBPtr); 1837824Sgblack@eecs.umich.edu assert(equalTestAPtr != equalTestB); 1847824Sgblack@eecs.umich.edu assert(equalTestAPtr != equalTestBPtr); 1857824Sgblack@eecs.umich.edu 1867824Sgblack@eecs.umich.edu cout << flush; 1877824Sgblack@eecs.umich.edu} 188