1 //------------------------------------------------------------------------------ 2 // emCrossPtr.h 3 // 4 // Copyright (C) 2007-2008 Oliver Hamann. 5 // 6 // Homepage: http://eaglemode.sourceforge.net/ 7 // 8 // This program is free software: you can redistribute it and/or modify it under 9 // the terms of the GNU General Public License version 3 as published by the 10 // Free Software Foundation. 11 // 12 // This program is distributed in the hope that it will be useful, but WITHOUT 13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for 15 // more details. 16 // 17 // You should have received a copy of the GNU General Public License version 3 18 // along with this program. If not, see <http://www.gnu.org/licenses/>. 19 //------------------------------------------------------------------------------ 20 21 #ifndef emCrossPtr_h 22 #define emCrossPtr_h 23 24 #ifndef emStd1_h 25 #include <emCore/emStd1.h> 26 #endif 27 28 class emCrossPtrPrivate { 29 protected: 30 friend class emCrossPtrList; 31 void Unlink(); 32 void * Obj; 33 emCrossPtrPrivate * * ThisPtr; 34 emCrossPtrPrivate * Next; 35 }; 36 37 38 //============================================================================== 39 //================================= emCrossPtr ================================= 40 //============================================================================== 41 42 template <class CLS> class emCrossPtr : private emCrossPtrPrivate { 43 44 public: 45 46 // Template class for an object pointer which is automatically set to 47 // NULL when the object is destructed. It is something like a so-called 48 // weak reference (in compare to emRef). The name "cross pointer" comes 49 // from the fact that these pointers can be safely used to cross the 50 // ownership hierarchy. 51 // 52 // The template parameter CLS is the class of the object to be pointed. 53 // It must be an emCrossPtrList or a class that has the method 54 // LinkCrossPtr(emCrossPtrPrivate) which forwards the call to a member 55 // emCrossPtrList. Typical candidates are emContext, emModel, emPanel 56 // and their derivatives. 57 58 emCrossPtr(); 59 // Construct a NULL pointer. 60 61 emCrossPtr(const emCrossPtr & crossPtr); 62 // Construct a copied pointer. 63 64 emCrossPtr(CLS * obj); 65 // Construct from a normal pointer (NULL is allowed). 66 67 ~emCrossPtr(); 68 // Destructor. 69 70 emCrossPtr & operator = (const emCrossPtr & crossPtr); 71 emCrossPtr & operator = (CLS * obj); 72 // Copy operators (NULL-pointer is allowed). 73 74 operator CLS * () const; 75 // Cast this to a normal pointer (can be NULL). 76 77 CLS * Get() const; 78 // Get the normal pointer (can be NULL). 79 80 CLS * operator -> () const; 81 // This makes this class a so-called "smart pointer". For 82 // example, if p is an emCrossPtr to an object which has a 83 // method named Hello(), one could say p->Hello() instead of 84 // p.Get()->Hello(). 85 }; 86 87 88 //============================================================================== 89 //=============================== emCrossPtrList =============================== 90 //============================================================================== 91 92 class emCrossPtrList : public emUncopyable { 93 94 public: 95 96 // Class for a list of cross pointers pointing to an object. 97 98 emCrossPtrList(); 99 // Start with an empty list. 100 101 ~emCrossPtrList(); 102 // Like BreakCrossPtrs(). 103 104 void BreakCrossPtrs(); 105 // Remove all cross pointers and set them to NULL. This could be 106 // called at the beginning of a destructor of an object for 107 // getting rid of the pointers a little bit earlier than through 108 // the destructor of this list. 109 110 void LinkCrossPtr(emCrossPtrPrivate & crossPtr); 111 // Insert a cross pointer to this list (the field crossPtr.Obj 112 // is not touched by this). This method is only to be called by 113 // emCrossPtr or by forwarding from an object class instance to 114 // a member instance of this class. 115 116 private: 117 emCrossPtrPrivate * First; 118 }; 119 120 121 //============================================================================== 122 //============================== Implementations =============================== 123 //============================================================================== 124 emCrossPtr()125template <class CLS> inline emCrossPtr<CLS>::emCrossPtr() 126 { 127 Obj=NULL; 128 } 129 emCrossPtr(const emCrossPtr & crossPtr)130template <class CLS> inline emCrossPtr<CLS>::emCrossPtr( 131 const emCrossPtr & crossPtr 132 ) 133 { 134 Obj=crossPtr.Obj; 135 if (Obj) ((CLS*)Obj)->LinkCrossPtr(*this); 136 } 137 emCrossPtr(CLS * obj)138template <class CLS> inline emCrossPtr<CLS>::emCrossPtr(CLS * obj) 139 { 140 Obj=obj; 141 if (obj) obj->LinkCrossPtr(*this); 142 } 143 ~emCrossPtr()144template <class CLS> inline emCrossPtr<CLS>::~emCrossPtr() 145 { 146 if (Obj) Unlink(); 147 } 148 149 template <class CLS> emCrossPtr<CLS> & emCrossPtr<CLS>::operator = ( 150 const emCrossPtr & crossPtr 151 ) 152 { 153 if (Obj) Unlink(); 154 Obj=crossPtr.Obj; 155 if (Obj) ((CLS*)Obj)->LinkCrossPtr(*this); 156 return *this; 157 } 158 159 template <class CLS> emCrossPtr<CLS> & emCrossPtr<CLS>::operator = (CLS * obj) 160 { 161 if (Obj) Unlink(); 162 Obj=obj; 163 if (obj) obj->LinkCrossPtr(*this); 164 return *this; 165 } 166 167 template <class CLS> inline emCrossPtr<CLS>::operator CLS * () const 168 { 169 return (CLS*)Obj; 170 } 171 Get()172template <class CLS> inline CLS * emCrossPtr<CLS>::Get() const 173 { 174 return (CLS*)Obj; 175 } 176 177 template <class CLS> inline CLS * emCrossPtr<CLS>::operator -> () const 178 { 179 return (CLS*)Obj; 180 } 181 emCrossPtrList()182inline emCrossPtrList::emCrossPtrList() 183 { 184 First=NULL; 185 } 186 ~emCrossPtrList()187inline emCrossPtrList::~emCrossPtrList() 188 { 189 BreakCrossPtrs(); 190 } 191 192 193 #endif 194