00001 /* SimData: Data Infrastructure for Simulations 00002 * Copyright (C) 2002 Mark Rose <tm2@stm.lbl.gov> 00003 * 00004 * This file is part of SimData. 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 */ 00020 00021 00029 #ifndef __SIMDATA_REF_H__ 00030 #define __SIMDATA_REF_H__ 00031 00032 #include <cassert> 00033 #include <list> 00034 #include <vector> 00035 00036 #include <SimData/Namespace.h> 00037 #include <SimData/Export.h> 00038 #include <SimData/Exception.h> 00039 #include <SimData/Log.h> 00040 00041 00042 NAMESPACE_SIMDATA 00043 00044 00045 class Referenced; 00046 class ReferencePointer; 00047 class LinkBase; 00048 00049 00050 SIMDATA_EXCEPTION(ConversionError); 00051 00052 00063 template<class T> 00064 class Ref { 00065 public: 00066 typedef std::vector< Ref<T> > vector; 00067 typedef std::list< Ref<T> > list; 00068 00069 /* TODO add Python bindings 00070 // SWIG python specific comparisons 00071 bool __eq__(const Ref& other); 00072 bool __ne__(const Ref& other); 00073 */ 00074 00075 00078 Ref(): _reference(0) { 00079 } 00080 00081 00084 Ref(T* ptr): _reference(ptr) { 00085 if (ptr) ptr->_ref(); 00086 } 00087 00090 Ref(LinkBase const & r): _reference(0) { 00091 _rebind(r._get()); 00092 } 00093 00096 template <typename Q> 00097 Ref(Ref<Q> const & r): _reference(0) { 00098 Q *rp = r.get(); 00099 if (rp != 0) { 00100 //rp->_ref(); 00101 //_reference = static_cast<T*>(rp); 00102 _rebind(rp); 00103 } 00104 } 00105 00108 Ref(Ref const & r): _reference(r._reference) { 00109 if (_reference != 0) _reference->_ref(); 00110 } 00111 00115 ~Ref() { 00116 if (_reference) _reference->_deref(); 00117 } 00118 00121 inline bool unique() const { 00122 if (_reference == 0) return true; 00123 return (_reference->_count() == 1); 00124 } 00125 00128 inline int count() const { 00129 if (_reference == 0) return 1; 00130 return _reference->_count(); 00131 } 00132 00133 #ifndef SWIG 00134 00136 template <class Q> 00137 Ref const & operator=(Ref<Q> const & r) { 00138 _rebind(r.get()); 00139 return *this; 00140 } 00141 00144 Ref const & operator=(Ref const & r) { 00145 _rebind(r.get()); 00146 return *this; 00147 } 00148 00151 LinkBase const & operator=(LinkBase const & r) { 00152 _rebind(r._get()); 00153 return r; 00154 } 00155 00158 template <class Q> 00159 inline Q *operator=(Q *ptr) { 00160 _rebind(ptr); 00161 return ptr; 00162 } 00163 00168 inline void *operator=(void *ptr) { 00169 assert(ptr==0); 00170 if (_reference != 0) _reference->_deref(); 00171 _reference = 0; 00172 return ptr; 00173 } 00174 #endif // SWIG 00175 00176 00179 inline T* get() const { 00180 return _reference; 00181 } 00182 00185 inline T* operator->() const { 00186 return _reference; 00187 } 00188 00191 inline T & operator*() const { 00192 return *_reference; 00193 } 00194 00195 #ifndef SWIG 00196 00198 inline bool operator!() const { 00199 return _reference == 0; 00200 } 00201 #endif // SWIG 00202 00205 inline bool valid() const { 00206 return _reference != 0; 00207 } 00208 00211 template <class Q> 00212 inline bool operator==(Ref<Q> const & p) const { 00213 return _reference == p.get(); 00214 } 00215 00218 inline bool operator==(Referenced const * p) const { 00219 return _reference == p; 00220 } 00221 00224 template <class Q> 00225 inline bool operator!=(Ref<Q> const & p) const { 00226 return _reference != p.get(); 00227 } 00228 00231 inline bool operator!=(Referenced const * p) const { 00232 return _reference != p; 00233 } 00234 00235 00236 protected: 00239 template <class Q> 00240 void _rebind(Q* ptr) { 00241 if (ptr) ptr->_ref(); 00242 if (_reference != 0) _reference->_deref(); 00243 _reference = dynamic_cast<T*>(ptr); 00244 if (_reference == 0 && ptr != 0) { 00245 SIMDATA_LOG(LOG_ALL, LOG_ERROR, "simdata::Ref() assignment: incompatible types (dynamic cast failed)."); 00246 throw ConversionError(); 00247 } 00248 } 00249 00252 T* _reference; 00253 }; 00254 00255 00262 class SIMDATA_EXPORT Referenced { 00263 00264 template <class T> friend class Ref; 00265 friend class ReferencePointer; 00266 00267 public: 00268 Referenced(): __count(0) {} 00269 00270 protected: 00279 virtual ~Referenced() { 00280 if (__count != 0) { 00281 SIMDATA_LOG(LOG_ALL, LOG_ERROR, "simdata::Referenced(" << std::hex << int(this) << ") deleted with non-zero reference count (" << __count << "): memory corruption possible."); 00282 } 00283 } 00284 00285 private: 00286 inline void _ref() const { ++__count; } 00287 00288 inline void _deref() const { 00289 if (--__count <= 0) { 00290 delete this; 00291 } 00292 } 00293 inline unsigned _count() const { return __count; } 00294 00295 mutable unsigned __count; 00296 00297 Referenced(Referenced const &); //: __count(0) {} 00298 00299 #ifndef SWIG 00300 inline Referenced& operator=(Referenced const &);// { return *this; } 00301 #endif // SWIG 00302 00303 }; 00304 00305 00306 NAMESPACE_SIMDATA_END 00307 00308 00309 #endif //__SIMDATA_OBJECT_H__ 00310
|
SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage. Generated on Tue Oct 14 12:06:39 2003, using Doxygen 1.2.18. |