Main Page | Modules | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | Related Pages

smartpointer.h

00001 /*
00002 
00003   MusicXML Library
00004   Copyright (C) 2003  Grame
00005 
00006   This library is free software; you can redistribute it and/or
00007   modify it under the terms of the GNU Lesser General Public
00008   License as published by the Free Software Foundation; either
00009   version 2.1 of the License, or (at your option) any later version.
00010 
00011   This library is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   Lesser General Public License for more details.
00015 
00016   You should have received a copy of the GNU Lesser General Public
00017   License along with this library; if not, write to the Free Software
00018   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020   Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France
00021   grame@grame.fr
00022 
00023 */
00024 
00025 #ifndef __smartpointer__
00026 #define __smartpointer__
00027 
00028 #include <cassert>
00029 #include "exports.h"
00030 
00038 class EXP smartable {
00039     private:
00040         unsigned    refCount;       
00041     public:
00043         unsigned refs() const         { return refCount; }
00045         void addReference()           { refCount++; assert(refCount != 0); }
00047         void removeReference();
00048         
00049     protected:
00050         smartable() : refCount(0) {}
00051         smartable(const smartable&): refCount(0) {}
00053         virtual ~smartable()    { assert (refCount == 0); }
00054         smartable& operator=(const smartable&) { return *this; }
00055 };
00056 
00067 template<class T> class EXP SMARTP {
00068     private:
00070         T* fSmartPtr;
00071 
00072     public:
00074         SMARTP()    : fSmartPtr(0) {}
00076         SMARTP(T* rawptr) : fSmartPtr(rawptr)              { if (fSmartPtr) fSmartPtr->addReference(); }
00078         template<class T2> 
00079         SMARTP(const SMARTP<T2>& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); }
00081         SMARTP(const SMARTP& ptr) : fSmartPtr((T*)ptr)     { if (fSmartPtr) fSmartPtr->addReference(); }
00082 
00084         ~SMARTP()  { if (fSmartPtr) fSmartPtr->removeReference(); }
00085         
00087         operator T*() const  { return fSmartPtr;    }
00088 
00090         T& operator*() const {
00091             // checks for null dereference
00092             assert (fSmartPtr != 0);
00093             return *fSmartPtr;
00094         }
00095 
00097         T* operator->() const   { 
00098             // checks for null dereference
00099             assert (fSmartPtr != 0);
00100             return fSmartPtr;
00101         }
00102 
00104         template <class T2>
00105         SMARTP& operator=(T2 p1_)   { *this=(T*)p1_; return *this; }
00106 
00108         SMARTP& operator=(T* p_)    {
00109             // check first that pointers differ
00110             if (fSmartPtr != p_) {
00111                 // increments the ref count of the new pointer if not null
00112                 if (p_ != 0) p_->addReference();
00113                 // decrements the ref count of the old pointer if not null
00114                 if (fSmartPtr != 0) fSmartPtr->removeReference();
00115                 // and finally stores the new actual pointer
00116                 fSmartPtr = p_;
00117             }
00118             return *this;
00119         }
00121         SMARTP& operator=(const SMARTP<T>& p_)                { return operator=((T *) p_); }
00123         template<class T2> SMARTP& cast(T2* p_)               { return operator=(dynamic_cast<T*>(p_)); }
00125         template<class T2> SMARTP& cast(const SMARTP<T2>& p_) { return operator=(dynamic_cast<T*>(p_)); }
00126 };
00127 
00128 
00129 #endif

Generated on Tue Mar 23 09:49:43 2004 for LibMusicXML by doxygen 1.3.3