00001 /* -*- C++ -*- */ 00002 00003 /* COPYRIGHT 00004 * 00005 * This file is part of the Visual Effects Engine - VEE 00006 * 00007 * Read the "VEE-LICENSE" file for the license. 00008 * 00009 * Authors & Copyright: 00010 * 00011 * Tommi Ilmonen, Tuukka Heikura, Marko Myllymaa and 00012 * Janne Kontkanen 2001-2004 00013 * 00014 * Additional copyrights: Tekes 2003-2004 00015 * 00016 * firstname.lastname@hut.fi 00017 * 00018 */ 00019 00020 #ifndef VEE_REFERENCE_OBJECT_H 00021 #define VEE_REFERENCE_OBJECT_H 00022 00024 template <typename T> 00025 class VEE_ReferenceObj 00026 { 00027 public: 00028 VEE_ReferenceObj() : m_count(1) {} 00029 00030 T m_object; 00031 unsigned m_count; 00032 }; 00033 00035 template <typename T> 00036 class VEE_ReferenceObject 00037 { 00038 public: 00039 VEE_ReferenceObject() : m_holder(0) {} 00040 VEE_ReferenceObject(const T &obj) 00041 : m_holder(new VEE_ReferenceObj<T>) { m_holder->m_object = obj; } 00042 00043 VEE_ReferenceObject(const VEE_ReferenceObject &that) 00044 { 00045 m_holder = ((VEE_ReferenceObject *) & that)->m_holder; 00046 if(m_holder) 00047 m_holder->m_count++; 00048 } 00049 00050 ~VEE_ReferenceObject() { breakLink(); } 00051 00052 T & ref() { check(); return m_holder->m_object; } 00053 const T & ref() const { check(); return m_holder->m_object; } 00054 00055 T & operator *() { check(); return m_holder->m_object; } 00056 const T & operator *() const { check(); return m_holder->m_object; } 00057 00059 void deepCopy(const VEE_ReferenceObject &that) 00060 { 00061 if(!m_holder) 00062 m_holder = new VEE_ReferenceObj<T>; 00063 else if(m_holder->count > 1) { 00064 --m_holder->m_count; 00065 m_holder = new VEE_ReferenceObj<T>; 00066 } 00067 m_holder->m_object = that.m_holder->m_object; 00068 } 00069 00070 00072 VEE_ReferenceObject & operator = (const VEE_ReferenceObject &that) 00073 { 00074 that.check(); 00075 if(m_holder == that.m_holder) return *this; 00076 00077 breakLink(); 00078 m_holder = ((VEE_ReferenceObject *) & that)->m_holder; 00079 m_holder->m_count++; 00080 00081 return *this; 00082 } 00083 00084 protected: 00085 00086 void breakLink() 00087 { 00088 if(!m_holder) return; 00089 if(! --m_holder->m_count) 00090 delete m_holder; 00091 m_holder = 0; 00092 } 00093 00094 void check() const 00095 { 00096 if(!m_holder) 00097 ((VEE_ReferenceObject *) this)->m_holder = new VEE_ReferenceObj<T>; 00098 } 00099 00100 VEE_ReferenceObj<T> *m_holder; 00101 }; 00102 00105 00106 template <typename T> 00107 class VEE_ReferencePtr 00108 { 00109 public: 00110 VEE_ReferencePtr(T * obj = 0) : m_object(obj), m_count(1) {} 00111 ~VEE_ReferencePtr() { delete m_object; } 00112 00113 T *m_object; 00114 unsigned m_count; 00115 }; 00116 00118 template <typename T> 00119 class VEE_RefPtr 00120 { 00121 public: 00122 VEE_RefPtr() : m_holder(0) {} 00123 VEE_RefPtr(T *obj) 00124 : m_holder(obj ? new VEE_ReferencePtr<T>(obj) : 0) { } 00125 00126 VEE_RefPtr(const VEE_RefPtr &that) 00127 { 00128 m_holder = ((VEE_RefPtr *) & that)->m_holder; 00129 if(m_holder) m_holder->m_count++; 00130 } 00131 00132 ~VEE_RefPtr() { breakLink(); } 00133 00134 T * ptr() { return m_holder ? m_holder->m_object : 0; } 00135 const T * ptr() const { return m_holder ? m_holder->m_object : 0; } 00136 00137 T * operator *() { return m_holder ? m_holder->m_object : 0; } 00138 const T & operator *() const { return m_holder ? m_holder->m_object : 0; } 00139 00140 VEE_RefPtr &link(T * obj) { return ((*this) = obj); } 00141 void clear() { breakLink(); } 00142 00144 VEE_RefPtr & operator = (const VEE_RefPtr &that) 00145 { 00146 if(m_holder == that.m_holder) return *this; 00147 00148 breakLink(); 00149 m_holder = ((VEE_RefPtr *) & that)->m_holder; 00150 m_holder->m_count++; 00151 00152 return *this; 00153 } 00154 00155 VEE_RefPtr & operator = (T *obj) 00156 { 00157 if(m_holder) 00158 if(obj == m_holder->m_object) 00159 return * this; 00160 00161 breakLink(); 00162 if(obj) 00163 m_holder = new VEE_ReferencePtr<T>(obj); 00164 return * this; 00165 } 00166 00167 void breakLink() 00168 { 00169 if(!m_holder) return; 00170 if(! --m_holder->m_count) 00171 delete m_holder; 00172 m_holder = 0; 00173 } 00174 00178 bool operator == (const VEE_RefPtr &that) const 00179 { return ptr() == that.ptr(); } 00180 00181 protected: 00182 00183 00184 VEE_ReferencePtr<T> *m_holder; 00185 }; 00186 00187 template <typename T> 00188 class VEE_SafePtr 00189 { 00190 public: 00191 VEE_SafePtr(T * ptr = 0) : m_ptr(ptr) {} 00192 ~VEE_SafePtr() { delete m_ptr; } 00193 00194 VEE_SafePtr & operator = (T *ptr) {delete m_ptr; m_ptr = ptr; return *this;} 00195 00196 T * ptr() { return m_ptr; } 00197 00198 protected: 00199 T * m_ptr; 00200 00201 private: 00202 VEE_SafePtr & operator = (const VEE_SafePtr &) { return *this; } 00203 }; 00204 00205 #endif 00206