Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * Copyright 2009-2011 Jörg Hermann Müller 00005 * 00006 * This file is part of AudaSpace. 00007 * 00008 * Audaspace is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * AudaSpace is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with Audaspace; if not, write to the Free Software Foundation, 00020 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 * 00022 * ***** END GPL LICENSE BLOCK ***** 00023 */ 00024 00029 #ifndef AUD_REFERENCE 00030 #define AUD_REFERENCE 00031 00032 #include <map> 00033 #include <cstddef> 00034 00035 // #define MEM_DEBUG 00036 00037 #ifdef MEM_DEBUG 00038 #include <iostream> 00039 #include <typeinfo> 00040 #endif 00041 00045 class AUD_ReferenceHandler 00046 { 00047 private: 00051 static std::map<void*, unsigned int> m_references; 00052 00053 public: 00058 static inline void incref(void* reference) 00059 { 00060 if(!reference) 00061 return; 00062 00063 std::map<void*, unsigned int>::iterator result = m_references.find(reference); 00064 if(result != m_references.end()) 00065 { 00066 m_references[reference]++; 00067 } 00068 else 00069 { 00070 m_references[reference] = 1; 00071 } 00072 } 00073 00079 static inline bool decref(void* reference) 00080 { 00081 if(!reference) 00082 return false; 00083 00084 if(!--m_references[reference]) 00085 { 00086 m_references.erase(reference); 00087 return true; 00088 } 00089 return false; 00090 } 00091 }; 00092 00093 template <class T> 00097 class AUD_Reference 00098 { 00099 private: 00101 T* m_reference; 00102 void* m_original; 00103 public: 00108 template <class U> 00109 AUD_Reference(U* reference) 00110 { 00111 m_original = reference; 00112 m_reference = dynamic_cast<T*>(reference); 00113 AUD_ReferenceHandler::incref(m_original); 00114 #ifdef MEM_DEBUG 00115 if(m_reference != NULL) 00116 std::cerr << "+" << typeid(*m_reference).name() << std::endl; 00117 #endif 00118 } 00119 00120 AUD_Reference() 00121 { 00122 m_original = NULL; 00123 m_reference = NULL; 00124 } 00125 00130 AUD_Reference(const AUD_Reference& ref) 00131 { 00132 m_original = ref.m_original; 00133 m_reference = ref.m_reference; 00134 AUD_ReferenceHandler::incref(m_original); 00135 #ifdef MEM_DEBUG 00136 if(m_reference != NULL) 00137 std::cerr << "+" << typeid(*m_reference).name() << std::endl; 00138 #endif 00139 } 00140 00141 template <class U> 00142 explicit AUD_Reference(const AUD_Reference<U>& ref) 00143 { 00144 m_original = ref.get(); 00145 m_reference = dynamic_cast<T*>(ref.get()); 00146 AUD_ReferenceHandler::incref(m_original); 00147 #ifdef MEM_DEBUG 00148 if(m_reference != NULL) 00149 std::cerr << "+" << typeid(*m_reference).name() << std::endl; 00150 #endif 00151 } 00152 00157 ~AUD_Reference() 00158 { 00159 #ifdef MEM_DEBUG 00160 if(m_reference != NULL) 00161 std::cerr << "-" << typeid(*m_reference).name() << std::endl; 00162 #endif 00163 if(AUD_ReferenceHandler::decref(m_original)) 00164 delete m_reference; 00165 } 00166 00171 AUD_Reference& operator=(const AUD_Reference& ref) 00172 { 00173 if(&ref == this) 00174 return *this; 00175 00176 #ifdef MEM_DEBUG 00177 if(m_reference != NULL) 00178 std::cerr << "-" << typeid(*m_reference).name() << std::endl; 00179 #endif 00180 if(AUD_ReferenceHandler::decref(m_original)) 00181 delete m_reference; 00182 00183 m_original = ref.m_original; 00184 m_reference = ref.m_reference; 00185 AUD_ReferenceHandler::incref(m_original); 00186 #ifdef MEM_DEBUG 00187 if(m_reference != NULL) 00188 std::cerr << "+" << typeid(*m_reference).name() << std::endl; 00189 #endif 00190 00191 return *this; 00192 } 00193 00197 inline bool isNull() const 00198 { 00199 return m_reference == NULL; 00200 } 00201 00205 inline T* get() const 00206 { 00207 return m_reference; 00208 } 00209 00213 inline void* getOriginal() const 00214 { 00215 return m_original; 00216 } 00217 00221 inline T& operator*() const 00222 { 00223 return *m_reference; 00224 } 00225 00229 inline T* operator->() const 00230 { 00231 return m_reference; 00232 } 00233 }; 00234 00235 template<class T, class U> 00236 inline bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b) 00237 { 00238 return a.getOriginal() == b.getOriginal(); 00239 } 00240 00241 template<class T, class U> 00242 inline bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b) 00243 { 00244 return a.getOriginal() != b.getOriginal(); 00245 } 00246 00247 #endif // AUD_REFERENCE