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 __sp_smartpointer__ 00026 #define __sp_smartpointer__ 00027 00028 #include <cassert> 00029 #include "ScoreProcessingExport.h" 00030 00038 class SPEXPORT sp_smartable { 00039 00040 private: 00041 long refCount; 00042 00043 public: 00045 unsigned refs() const { return refCount; } 00047 void addReference(); 00049 void removeReference(); 00050 00051 protected: 00052 sp_smartable() : refCount(0) {} 00053 sp_smartable(const sp_smartable&): refCount(0) {} 00055 virtual ~sp_smartable() { assert (refCount == 0); } 00056 sp_smartable& operator=(const sp_smartable&) { return *this; } 00057 }; 00058 00059 00067 class SPEXPORT atomic_sp_smartable { 00068 00069 private: 00070 long refCount; 00071 00072 public: 00074 unsigned refs() const { return refCount; } 00076 void addReference(); 00078 void removeReference(); 00079 00080 protected: 00081 atomic_sp_smartable() : refCount(0) {} 00082 atomic_sp_smartable(const atomic_sp_smartable&): refCount(0) {} 00084 virtual ~atomic_sp_smartable() { assert (refCount == 0); } 00085 atomic_sp_smartable& operator=(const atomic_sp_smartable&) { return *this; } 00086 }; 00087 00088 00099 template<class T> class SP_SMARTP { 00100 private: 00102 T* fSmartPtr; 00103 00104 public: 00106 SP_SMARTP() : fSmartPtr(0) {} 00108 SP_SMARTP(T* rawptr) : fSmartPtr(rawptr) { if (fSmartPtr) fSmartPtr->addReference(); } 00110 template<class T2> 00111 SP_SMARTP(const SP_SMARTP<T2>& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); } 00113 SP_SMARTP(const SP_SMARTP& ptr) : fSmartPtr((T*)ptr) { if (fSmartPtr) fSmartPtr->addReference(); } 00114 00116 ~SP_SMARTP() { if (fSmartPtr) fSmartPtr->removeReference(); } 00117 00119 operator T*() const { return fSmartPtr; } 00120 00122 T& operator*() const { 00123 // checks for null dereference 00124 assert (fSmartPtr != 0); 00125 return *fSmartPtr; 00126 } 00127 00129 T* operator->() const { 00130 // checks for null dereference 00131 assert (fSmartPtr != 0); 00132 return fSmartPtr; 00133 } 00134 00135 bool operator<(T* p_) const { 00136 // checks for null dereference 00137 assert (fSmartPtr != 0); 00138 return (fSmartPtr < p_); 00139 } 00140 00142 template <class T2> 00143 SP_SMARTP& operator=(T2 p1_) { *this=(T*)p1_; return *this; } 00144 00146 SP_SMARTP& operator=(T* p_) { 00147 // check first that pointers differ 00148 if (fSmartPtr != p_) { 00149 // increments the ref count of the new pointer if not null 00150 if (p_ != 0) p_->addReference(); 00151 // decrements the ref count of the old pointer if not null 00152 if (fSmartPtr != 0) fSmartPtr->removeReference(); 00153 // and finally stores the new actual pointer 00154 fSmartPtr = p_; 00155 } 00156 return *this; 00157 } 00159 SP_SMARTP& operator=(const SP_SMARTP<T>& p_) { return operator=((T *) p_); } 00161 template<class T2> SP_SMARTP& cast(T2* p_) { return operator=(dynamic_cast<T*>(p_)); } 00163 template<class T2> SP_SMARTP& cast(const SP_SMARTP<T2>& p_) { return operator=(dynamic_cast<T*>(p_)); } 00164 }; 00165 00166 00167 #endif
1.5.8