refcnttest.cc revision 7842
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 357842Sgblack@eecs.umich.edu#include "base/cprintf.hh" 367824Sgblack@eecs.umich.edu#include "base/refcnt.hh" 377842Sgblack@eecs.umich.edu#include "unittest/unittest.hh" 387824Sgblack@eecs.umich.edu 397824Sgblack@eecs.umich.eduusing namespace std; 407842Sgblack@eecs.umich.eduusing UnitTest::setCase; 417824Sgblack@eecs.umich.edu 427824Sgblack@eecs.umich.edunamespace { 437824Sgblack@eecs.umich.edu 447842Sgblack@eecs.umich.edubool printNewDel = false; 457842Sgblack@eecs.umich.edu 467824Sgblack@eecs.umich.educlass TestRC; 477824Sgblack@eecs.umich.edutypedef list<TestRC *> LiveList; 487824Sgblack@eecs.umich.eduLiveList liveList; 497824Sgblack@eecs.umich.edu 507824Sgblack@eecs.umich.eduint 517824Sgblack@eecs.umich.edulive() 527824Sgblack@eecs.umich.edu{ 537824Sgblack@eecs.umich.edu return liveList.size(); 547824Sgblack@eecs.umich.edu} 557824Sgblack@eecs.umich.edu 567824Sgblack@eecs.umich.eduint 577824Sgblack@eecs.umich.eduliveChange() 587824Sgblack@eecs.umich.edu{ 597824Sgblack@eecs.umich.edu static int oldLive = 0; 607824Sgblack@eecs.umich.edu int newLive = live(); 617824Sgblack@eecs.umich.edu int diff = newLive - oldLive; 627824Sgblack@eecs.umich.edu oldLive = newLive; 637824Sgblack@eecs.umich.edu return diff; 647824Sgblack@eecs.umich.edu} 657824Sgblack@eecs.umich.edu 667824Sgblack@eecs.umich.educlass TestRC : public RefCounted 677824Sgblack@eecs.umich.edu{ 687824Sgblack@eecs.umich.edu protected: 697824Sgblack@eecs.umich.edu const char *_tag; 707824Sgblack@eecs.umich.edu LiveList::iterator liveIt; 717824Sgblack@eecs.umich.edu 727824Sgblack@eecs.umich.edu public: 737824Sgblack@eecs.umich.edu TestRC(const char *newTag) : _tag(newTag) 747824Sgblack@eecs.umich.edu { 757842Sgblack@eecs.umich.edu if (printNewDel) 767842Sgblack@eecs.umich.edu cprintf(" Creating object \"%s\"\n", _tag); 777824Sgblack@eecs.umich.edu liveList.push_front(this); 787824Sgblack@eecs.umich.edu liveIt = liveList.begin(); 797824Sgblack@eecs.umich.edu } 807824Sgblack@eecs.umich.edu 817824Sgblack@eecs.umich.edu ~TestRC() 827824Sgblack@eecs.umich.edu { 837842Sgblack@eecs.umich.edu if (printNewDel) 847842Sgblack@eecs.umich.edu cprintf(" Destroying object \"%s\"\n", _tag); 857824Sgblack@eecs.umich.edu liveList.erase(liveIt); 867824Sgblack@eecs.umich.edu } 877824Sgblack@eecs.umich.edu 887824Sgblack@eecs.umich.edu const char * 897824Sgblack@eecs.umich.edu tag() 907824Sgblack@eecs.umich.edu { 917824Sgblack@eecs.umich.edu return _tag; 927824Sgblack@eecs.umich.edu } 937824Sgblack@eecs.umich.edu 947824Sgblack@eecs.umich.edu int testVal; 957824Sgblack@eecs.umich.edu}; 967824Sgblack@eecs.umich.edu 977824Sgblack@eecs.umich.edutypedef RefCountingPtr<TestRC> Ptr; 987824Sgblack@eecs.umich.edu 997842Sgblack@eecs.umich.edu} // anonymous namespace 1007824Sgblack@eecs.umich.edu 1017824Sgblack@eecs.umich.eduint 1027824Sgblack@eecs.umich.edumain() 1037824Sgblack@eecs.umich.edu{ 1047824Sgblack@eecs.umich.edu assert(live() == 0); 1057824Sgblack@eecs.umich.edu assert(liveChange() == 0); 1067824Sgblack@eecs.umich.edu 1077824Sgblack@eecs.umich.edu // Create an empty Ptr and verify it's data pointer is NULL. 1087842Sgblack@eecs.umich.edu setCase("NULL check"); 1097824Sgblack@eecs.umich.edu Ptr nullCheck; 1107842Sgblack@eecs.umich.edu EXPECT_EQ(nullCheck.get(), NULL); 1117824Sgblack@eecs.umich.edu 1127842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 0); 1137824Sgblack@eecs.umich.edu 1147824Sgblack@eecs.umich.edu // Construct a Ptr from a TestRC pointer. 1157842Sgblack@eecs.umich.edu setCase("construction from pointer"); 1167824Sgblack@eecs.umich.edu Ptr constFromPointer = new TestRC("construction from pointer"); 1177824Sgblack@eecs.umich.edu 1187842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 1); 1197824Sgblack@eecs.umich.edu 1207824Sgblack@eecs.umich.edu // Construct a Ptr from an existing Ptr. 1217842Sgblack@eecs.umich.edu setCase("construction from a Ptr"); 1227824Sgblack@eecs.umich.edu Ptr constFromPtr = constFromPointer; 1237824Sgblack@eecs.umich.edu 1247842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 0); 1257824Sgblack@eecs.umich.edu 1267824Sgblack@eecs.umich.edu // Test a Ptr being destroyed. 1277842Sgblack@eecs.umich.edu setCase("destroying a Ptr"); 1287824Sgblack@eecs.umich.edu Ptr *ptrPtr = new Ptr(new TestRC("destroying a ptr")); 1297842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 1); 1307824Sgblack@eecs.umich.edu delete ptrPtr; 1317842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), -1); 1327824Sgblack@eecs.umich.edu 1337824Sgblack@eecs.umich.edu // Test assignment from a pointer and from a Ptr. 1347842Sgblack@eecs.umich.edu setCase("assignment operators"); 1357824Sgblack@eecs.umich.edu Ptr assignmentTarget; 1367824Sgblack@eecs.umich.edu TestRC *assignmentSourcePointer = new TestRC("assignment source 1"); 1377842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 1); 1387824Sgblack@eecs.umich.edu assignmentTarget = assignmentSourcePointer; 1397842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 0); 1407824Sgblack@eecs.umich.edu assignmentTarget = NULL; 1417842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), -1); 1427824Sgblack@eecs.umich.edu Ptr assignmentSourcePtr(new TestRC("assignment source 2")); 1437842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 1); 1447824Sgblack@eecs.umich.edu assignmentTarget = assignmentSourcePtr; 1457842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 0); 1467824Sgblack@eecs.umich.edu assignmentSourcePtr = NULL; 1477842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 0); 1487824Sgblack@eecs.umich.edu assignmentTarget = NULL; 1497842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), -1); 1507824Sgblack@eecs.umich.edu 1517824Sgblack@eecs.umich.edu // Test access to members of the pointed to class and dereferencing. 1527842Sgblack@eecs.umich.edu setCase("access to members"); 1537824Sgblack@eecs.umich.edu TestRC *accessTest = new TestRC("access test"); 1547824Sgblack@eecs.umich.edu Ptr accessTestPtr = accessTest; 1557824Sgblack@eecs.umich.edu accessTest->testVal = 1; 1567842Sgblack@eecs.umich.edu EXPECT_EQ(accessTestPtr->testVal, 1); 1577842Sgblack@eecs.umich.edu EXPECT_EQ((*accessTestPtr).testVal, 1); 1587824Sgblack@eecs.umich.edu accessTest->testVal = 2; 1597842Sgblack@eecs.umich.edu EXPECT_EQ(accessTestPtr->testVal, 2); 1607842Sgblack@eecs.umich.edu EXPECT_EQ((*accessTestPtr).testVal, 2); 1617824Sgblack@eecs.umich.edu accessTestPtr->testVal = 3; 1627842Sgblack@eecs.umich.edu EXPECT_EQ(accessTest->testVal, 3); 1637824Sgblack@eecs.umich.edu (*accessTestPtr).testVal = 4; 1647842Sgblack@eecs.umich.edu EXPECT_EQ(accessTest->testVal, 4); 1657824Sgblack@eecs.umich.edu accessTestPtr = NULL; 1667824Sgblack@eecs.umich.edu accessTest = NULL; 1677842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 0); 1687824Sgblack@eecs.umich.edu 1697824Sgblack@eecs.umich.edu // Test bool and ! operator overloads. 1707842Sgblack@eecs.umich.edu setCase("conversion to bool and ! overload"); 1717824Sgblack@eecs.umich.edu Ptr boolTest = new TestRC("bool test"); 1727842Sgblack@eecs.umich.edu EXPECT_EQ(boolTest, true); 1737842Sgblack@eecs.umich.edu EXPECT_EQ(!boolTest, false); 1747824Sgblack@eecs.umich.edu boolTest = NULL; 1757842Sgblack@eecs.umich.edu EXPECT_EQ(boolTest, false); 1767842Sgblack@eecs.umich.edu EXPECT_EQ(!boolTest, true); 1777842Sgblack@eecs.umich.edu EXPECT_EQ(liveChange(), 0); 1787824Sgblack@eecs.umich.edu 1797824Sgblack@eecs.umich.edu // Test the equality operators. 1807842Sgblack@eecs.umich.edu setCase("equality operators"); 1817824Sgblack@eecs.umich.edu TestRC *equalTestA = new TestRC("equal test a"); 1827824Sgblack@eecs.umich.edu Ptr equalTestAPtr = equalTestA; 1837824Sgblack@eecs.umich.edu Ptr equalTestAPtr2 = equalTestA; 1847824Sgblack@eecs.umich.edu TestRC *equalTestB = new TestRC("equal test b"); 1857824Sgblack@eecs.umich.edu Ptr equalTestBPtr = equalTestB; 1867842Sgblack@eecs.umich.edu EXPECT_TRUE(equalTestA == equalTestAPtr); 1877842Sgblack@eecs.umich.edu EXPECT_TRUE(equalTestAPtr == equalTestA); 1887842Sgblack@eecs.umich.edu EXPECT_TRUE(equalTestAPtr == equalTestAPtr2); 1897842Sgblack@eecs.umich.edu EXPECT_TRUE(equalTestA != equalTestBPtr); 1907842Sgblack@eecs.umich.edu EXPECT_TRUE(equalTestAPtr != equalTestB); 1917842Sgblack@eecs.umich.edu EXPECT_TRUE(equalTestAPtr != equalTestBPtr); 1927824Sgblack@eecs.umich.edu 1937842Sgblack@eecs.umich.edu return UnitTest::printResults(); 1947824Sgblack@eecs.umich.edu} 195