refCounter.h

Go to the documentation of this file.
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1