Blender V2.61 - r43446

AUD_Reference.h

Go to the documentation of this file.
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