00001 /* 00002 * See the dyninst/COPYRIGHT file for copyright information. 00003 * 00004 * We provide the Paradyn Tools (below described as "Paradyn") 00005 * on an AS IS basis, and do not warrant its validity or performance. 00006 * We reserve the right to update, modify, or discontinue this 00007 * software at any time. We shall have no obligation to supply such 00008 * updates or modifications or any other form of support to you. 00009 * 00010 * By your use of Paradyn, you understand and agree that we (or any 00011 * other person or entity with proprietary rights in Paradyn) are 00012 * under no obligation to provide either maintenance services, 00013 * update services, notices of latent defects, or correction of 00014 * defects for Paradyn. 00015 * 00016 * This library is free software; you can redistribute it and/or 00017 * modify it under the terms of the GNU Lesser General Public 00018 * License as published by the Free Software Foundation; either 00019 * version 2.1 of the License, or (at your option) any later version. 00020 * 00021 * This library is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00024 * Lesser General Public License for more details. 00025 * 00026 * You should have received a copy of the GNU Lesser General Public 00027 * License along with this library; if not, write to the Free Software 00028 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00029 */ 00030 00031 00032 // $Id: refCounter.h,v 1.7 2007/05/30 19:20:03 legendre Exp $ 00033 // refCounter.h 00034 // Ariel Tamches 00035 00036 #ifndef _REF_COUNTER_H_ 00037 #define _REF_COUNTER_H_ 00038 00039 #ifdef external_templates 00040 #pragma interface 00041 #endif 00042 00043 #include <assert.h> 00044 00045 template <class T> 00046 class refCounter { 00047 private: 00048 class actualData { 00049 private: 00050 mutable unsigned refCount; 00051 T data; 00052 public: 00053 actualData(const T &src) : data(src) {refCount=0;} 00054 ~actualData() {} 00055 void reference() const {refCount++;} 00056 bool dereference() const { 00057 assert(refCount > 0); 00058 return (--refCount == 0); 00059 } 00060 T &getData() {return data;} 00061 const T &getData() const {return data;} 00062 }; 00063 actualData *theData; 00064 // allocated with new, but not necessarily by us. _Never_ NULL. 00065 00066 private: 00067 void reference() const { 00068 assert(theData); 00069 theData->reference(); 00070 } 00071 void dereference() const { 00072 assert(theData); 00073 if (theData->dereference()) 00074 delete theData; 00075 } 00076 00077 // explicitly disallowed 00078 // (Visual C++ still requires a body, however) 00079 refCounter() {} 00080 00081 public: 00082 refCounter(const T &src) { 00083 // examples: 00084 // T y; (y is initialized somehow...) 00085 // refCounter<T> x = y; or 00086 // refCounter<T> x(y); 00087 theData = new actualData(src); 00088 assert(theData); 00089 reference(); 00090 } 00091 refCounter(const refCounter &src) { 00092 // This constructor is what this whole class revolves around. It's fast. 00093 // examples: 00094 // refCounter<T> y; (y is initialized somehow...) 00095 // refCounter<T> x = y; or 00096 // refCounter<T> x(y); 00097 src.reference(); // just bumps up a ref count --> fast 00098 theData = src.theData; // just a ptr assignment --> fast 00099 } 00100 ~refCounter() { 00101 dereference(); 00102 } 00103 refCounter &operator=(const refCounter &src) { 00104 if (this == &src) 00105 return *this; // protect against x=x 00106 00107 dereference(); 00108 00109 // ...and attach to the new stuff efficiently 00110 theData = src.theData; // just a ptr assignment --> fast 00111 reference(); // just bumps a ref cnt --> fast 00112 return *this; 00113 } 00114 refCounter &operator=(const T &src) { 00115 dereference(); 00116 theData = new actualData(src); 00117 reference(); 00118 return *this; 00119 } 00120 T &getData() { 00121 assert(theData); 00122 return theData->getData(); 00123 } 00124 const T &getData() const { 00125 assert(theData); 00126 return theData->getData(); 00127 } 00128 }; 00129 00130 #endif
1.6.1