00001 /* 00002 * Copyright (C) 2006-2011, SRI International (R) 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU Lesser General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #pragma once 00019 00020 #ifndef __OpenKarto_SmartPointer_h__ 00021 #define __OpenKarto_SmartPointer_h__ 00022 00023 #include <OpenKarto/Referenced.h> 00024 00025 namespace karto 00026 { 00027 00029 00030 00034 00038 template<class T> 00039 class SmartPointer 00040 { 00041 public: 00045 SmartPointer() 00046 : m_pPointer(NULL) 00047 { 00048 } 00049 00053 SmartPointer(const SmartPointer& rOther) 00054 : m_pPointer(rOther.m_pPointer) 00055 { 00056 if (m_pPointer != NULL) 00057 { 00058 m_pPointer->Reference(); 00059 } 00060 } 00061 00065 template<class Other> SmartPointer(const SmartPointer<Other>& rOther) 00066 : m_pPointer(rOther.m_pPointer) 00067 { 00068 if (m_pPointer != NULL) 00069 { 00070 m_pPointer->Reference(); 00071 } 00072 } 00073 00077 SmartPointer(T* pPointer) 00078 : m_pPointer(pPointer) 00079 { 00080 if (m_pPointer != NULL) 00081 { 00082 m_pPointer->Reference(); 00083 } 00084 } 00085 00089 virtual ~SmartPointer() 00090 { 00091 Release(); 00092 } 00093 00094 public: 00098 inline void Release() 00099 { 00100 if (m_pPointer) 00101 { 00102 m_pPointer->Unreference(); 00103 } 00104 00105 m_pPointer = NULL; 00106 } 00107 00112 T* Get() const 00113 { 00114 return m_pPointer; 00115 } 00116 00121 kt_bool IsValid() const 00122 { 00123 return m_pPointer != NULL; 00124 } 00125 00126 public: 00131 operator T*() const 00132 { 00133 return m_pPointer; 00134 } 00135 00140 T& operator*() const 00141 { 00142 return *m_pPointer; 00143 } 00144 00149 T* operator->() const 00150 { 00151 return m_pPointer; 00152 } 00153 00157 inline SmartPointer& operator=(const SmartPointer& rOther) 00158 { 00159 if (m_pPointer==rOther.m_pPointer) 00160 { 00161 return *this; 00162 } 00163 00164 T* pTempPointer = m_pPointer; 00165 m_pPointer = rOther.m_pPointer; 00166 00167 if (m_pPointer) 00168 { 00169 m_pPointer->Reference(); 00170 } 00171 00172 if (pTempPointer) 00173 { 00174 pTempPointer->Unreference(); 00175 } 00176 00177 return *this; 00178 } 00179 00183 inline SmartPointer& operator=(T* pPointer) 00184 { 00185 if (m_pPointer == pPointer) 00186 { 00187 return *this; 00188 } 00189 00190 T* pTempPointer = m_pPointer; 00191 m_pPointer = pPointer; 00192 00193 if (m_pPointer) 00194 { 00195 m_pPointer->Reference(); 00196 } 00197 00198 if (pTempPointer) 00199 { 00200 pTempPointer->Unreference(); 00201 } 00202 00203 return *this; 00204 } 00205 00209 template<class Other> SmartPointer& operator=(const SmartPointer<Other>& rOther) 00210 { 00211 if (m_pPointer == rOther.m_pPointer) 00212 { 00213 return *this; 00214 } 00215 00216 T* pTempPointer = m_pPointer; 00217 m_pPointer = rOther.m_pPointer; 00218 00219 if (m_pPointer) 00220 { 00221 m_pPointer->Reference(); 00222 } 00223 00224 if (pTempPointer) 00225 { 00226 pTempPointer->Unreference(); 00227 } 00228 00229 return *this; 00230 } 00231 00232 private: 00233 T* m_pPointer; 00234 00235 template<class Other> friend class SmartPointer; 00236 }; 00237 00239 00240 } 00241 00242 #endif // __OpenKarto_SmartPointer_h__