Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

RageUtil_AutoPtr.h

Go to the documentation of this file.
00001 #ifndef RAGE_UTIL_AUTO_PTR_H 00002 #define RAGE_UTIL_AUTO_PTR_H 00003 00004 /* 00005 * This is a simple copy-on-write refcounted smart pointer. Once constructed, all read-only 00006 * access to the object is made without extra copying. If you need read-write access, you 00007 * can get a pointer with Get(), which will cause the object to deep-copy. (Don't free 00008 * the resulting pointer.) 00009 * 00010 * Note that there are no non-const operator* or operator-> overloads, because that would 00011 * cause all const access by code with non-const permissions to deep-copy. For example, 00012 * 00013 * AutoPtrCopyOnWrite<int> a( new int(1) ); 00014 * AutoPtrCopyOnWrite<int> b( a ); 00015 * printf( "%i\n", *a ); 00016 * 00017 * If we have a non-const operator*, this *a will use it (even though it only needs const 00018 * access), and will copy the underlying object wastefully. g++ std::string has this behavior, 00019 * which is why it's important to qualify strings as "const" when const access is desired, 00020 * but that's brittle, so let's make all potential deep-copying explicit. 00021 */ 00022 00023 template<class T> 00024 class AutoPtrCopyOnWrite 00025 { 00026 public: 00027 /* This constructor only exists to make us work with STL containers. */ 00028 inline AutoPtrCopyOnWrite() 00029 { 00030 m_pPtr = NULL; 00031 m_iRefCount = new int(1); 00032 } 00033 00034 explicit inline AutoPtrCopyOnWrite( T *p ) 00035 { 00036 m_pPtr = p; 00037 m_iRefCount = new int(1); 00038 } 00039 00040 inline AutoPtrCopyOnWrite( const AutoPtrCopyOnWrite &rhs ) 00041 { 00042 m_pPtr = rhs.m_pPtr; 00043 m_iRefCount = rhs.m_iRefCount; 00044 ++(*m_iRefCount); 00045 } 00046 00047 void Swap( AutoPtrCopyOnWrite<T> &rhs ) 00048 { 00049 swap( m_pPtr, rhs.m_pPtr ); 00050 swap( m_iRefCount, rhs.m_iRefCount ); 00051 } 00052 00053 inline AutoPtrCopyOnWrite<T> &operator=( const AutoPtrCopyOnWrite &rhs ) 00054 { 00055 AutoPtrCopyOnWrite<T> obj( rhs ); 00056 this->Swap( obj ); 00057 return *this; 00058 } 00059 00060 ~AutoPtrCopyOnWrite() 00061 { 00062 --(*m_iRefCount); 00063 if( *m_iRefCount == 0 ) 00064 { 00065 delete m_pPtr; 00066 delete m_iRefCount; 00067 } 00068 } 00069 00070 /* Get a non-const pointer. This will deep-copy the object if necessary. */ 00071 T *Get() 00072 { 00073 if( *m_iRefCount > 1 ) 00074 { 00075 --*m_iRefCount; 00076 m_pPtr = new T(*m_pPtr); 00077 m_iRefCount = new int(1); 00078 } 00079 00080 return m_pPtr; 00081 } 00082 00083 const T &operator *() const { return *m_pPtr; } 00084 const T *operator ->() const { return m_pPtr; } 00085 00086 private: 00087 T *m_pPtr; 00088 int *m_iRefCount; 00089 }; 00090 00091 template<class T> 00092 inline void swap( AutoPtrCopyOnWrite<T> &a, AutoPtrCopyOnWrite<T> &b ) 00093 { 00094 a.Swap(b); 00095 } 00096 00097 #endif 00098 00099 /* 00100 * (c) 2005 Glenn Maynard 00101 * All rights reserved. 00102 * 00103 * Permission is hereby granted, free of charge, to any person obtaining a 00104 * copy of this software and associated documentation files (the 00105 * "Software"), to deal in the Software without restriction, including 00106 * without limitation the rights to use, copy, modify, merge, publish, 00107 * distribute, and/or sell copies of the Software, and to permit persons to 00108 * whom the Software is furnished to do so, provided that the above 00109 * copyright notice(s) and this permission notice appear in all copies of 00110 * the Software and that both the above copyright notice(s) and this 00111 * permission notice appear in supporting documentation. 00112 * 00113 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00114 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00115 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 00116 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS 00117 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT 00118 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 00119 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00120 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00121 * PERFORMANCE OF THIS SOFTWARE. 00122 */

Generated on Thu Jan 27 20:57:30 2005 for StepMania by doxygen 1.3.7