00001 //========================================================================== 00002 // 00003 // File: Handle.h 00004 // 00005 // Created: 00006 // 00007 // Author: Øyvind Hjelle <oyvind.hjelle@math.sintef.no> 00008 // 00009 // Revision: $Id: Handle.h,v 1.2 2006/07/26 12:08:44 oyvindhj Exp $ 00010 // 00011 // Description: 00012 // 00013 //========================================================================== 00014 // Copyright (C) 2000-2003 SINTEF Applied Mathematics. All rights reserved. 00015 // 00016 // This file may be distributed under the terms of the Q Public License 00017 // as defined by Trolltech AS of Norway and appearing in the file 00018 // LICENSE.QPL included in the packaging of this file. 00019 // 00020 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00021 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00022 // 00023 //========================================================================== 00024 00025 00026 #ifndef _HANDLE_H_ 00027 #define _HANDLE_H_ 00028 00029 00030 #include <assert.h> 00031 00032 00033 //-------------------------------------------------------------------------- 00034 // Handle class 00035 //-------------------------------------------------------------------------- 00036 00042 template <class T> 00043 class Handle { 00044 00045 protected: 00046 T* classptr; 00047 00048 public: 00049 Handle() { classptr = 0; } 00050 00051 Handle(const T& ref) { 00052 classptr = (T*) &ref; 00053 classptr->increment(); 00054 } 00055 00056 Handle(T* p) { 00057 classptr = p; 00058 if (classptr != 0) classptr->increment(); 00059 } 00060 00061 Handle(const Handle<T>& ref) { 00062 classptr = ref.classptr; 00063 if (classptr != 0) 00064 classptr->increment(); 00065 } 00066 00067 ~Handle() { 00068 if (classptr != 0) { 00069 classptr->decrement (); 00070 assert(classptr->getNoRefs() >= 0); 00071 if (!classptr->isReferenced()) { 00072 if (classptr->dynamicObj()) 00073 delete classptr; 00074 } 00075 } 00076 } 00077 00078 void rebind(const T * pc) { 00079 if (classptr != pc) { 00080 T* p = (T*) pc; // cast const away 00081 if (p != 0) 00082 p->increment(); 00083 if (classptr != 0) { 00084 classptr->decrement (); 00085 assert(classptr->getNoRefs() >= 0); 00086 if (!classptr->isReferenced() && classptr->dynamicObj()) 00087 delete classptr; 00088 } 00089 classptr = p; 00090 } 00091 } 00092 00093 void rebind(const T& p) { rebind(&p); } 00094 00095 const T* operator->() const { return classptr; } 00096 T* operator->() { return classptr; } 00097 const T& operator()() const { return *classptr; } 00098 T& operator()() { return *classptr; } 00099 const T& operator*() const { return *classptr; } 00100 T& operator*() { return *classptr; } 00101 const T* getPtr() const { return classptr; } 00102 T* getPtr() { return classptr; } 00103 const T& getRef() const { return *classptr; } 00104 T& getRef() { return *classptr; } 00105 00106 void operator=(const Handle<T>& h) { rebind(h.getPtr()); } 00107 void operator=(const T* p) { rebind(p); } 00108 void operator=(const T& p) { rebind(p); } 00109 00110 bool operator==(const Handle<T>& h) const { return classptr == h.classptr; } 00111 bool operator!=(const Handle<T>& h) const { return classptr != h.classptr; } 00112 bool operator< (const Handle<T>& h) const { return classptr < h.classptr; } 00113 bool operator> (const Handle<T>& h) const { return classptr > h.classptr; } 00114 00115 }; 00116 00117 #endif