1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef ZORBA_STORE_ITEM_HANDLE_H 17 #define ZORBA_STORE_ITEM_HANDLE_H 18 19 #include <string> 20 #include <sstream> 21 22 namespace zorba 23 { 24 25 namespace store 26 { 27 28 29 /******************************************************************************* 30 Template class for smart pointers-to-T objects. T must be Item or a subclass 31 of Item. 32 ********************************************************************************/ 33 template<class T> class ItemHandle 34 { 35 protected: 36 T * p; 37 38 public: 39 union union_T 40 { 41 T** t; 42 void** v; 43 }; 44 45 public: ItemHandle()46 ItemHandle() : p(0) 47 { 48 } 49 ItemHandle(T * ptr)50 ItemHandle(T* ptr) : p(ptr) 51 { 52 if (p) 53 p->addReference(); 54 } 55 ItemHandle(const ItemHandle & rhs)56 ItemHandle(const ItemHandle& rhs) : p(rhs.getp()) 57 { 58 if (p) 59 p->addReference(); 60 } 61 ~ItemHandle()62 ~ItemHandle() 63 { 64 if (p) 65 p->removeReference(); 66 67 p = NULL; // do not remove 68 } 69 isNull()70 bool isNull () const { return p == NULL; } 71 setNull()72 void setNull() { p = NULL; } 73 getp()74 T* getp() const { return p; } 75 getp_ref()76 union_T getp_ref() { union_T u_t; u_t.t = &p; return u_t;} 77 78 operator T* () { return getp(); } 79 80 operator const T* () const { return getp(); } 81 82 T* operator->() const { return p; } 83 84 T& operator*() const { return *p; } 85 86 bool operator==(const ItemHandle& h) const { return p == h.p; } 87 88 bool operator==(const T* pp) const { return p == pp; } 89 90 bool operator!=(const ItemHandle& h) const { return p != h.p; } 91 92 bool operator!=(const T* pp) const { return p != pp; } 93 94 bool operator<(const ItemHandle& h) const { return p < h.p; } 95 96 cast()97 template <class otherT> ItemHandle<otherT> cast() const 98 { 99 return ItemHandle<otherT> (static_cast<otherT *>(p)); 100 } 101 102 template <class otherT> operator ItemHandle<otherT> () 103 { 104 return cast<otherT>(); 105 } 106 107 template <class otherT> operator const ItemHandle<otherT> () const 108 { 109 return cast<otherT>(); 110 } 111 112 ItemHandle& operator=(const T* rhs) 113 { 114 if (p != rhs) 115 { 116 if (p) 117 p->removeReference(); 118 119 p = const_cast<T*>(rhs); 120 121 if (p) 122 p->addReference(); 123 } 124 125 return *this; 126 } 127 128 template <class otherT> ItemHandle& operator=(const otherT* rhs) 129 { 130 if (p != rhs) 131 { 132 if (p) 133 p->removeReference(); 134 135 p = static_cast<T*>(const_cast<otherT*>(rhs)); 136 137 if (p) 138 p->addReference(); 139 } 140 return *this; 141 } 142 143 ItemHandle& operator=(const ItemHandle& rhs) 144 { 145 return assign(rhs); 146 } 147 148 template <class otherT> ItemHandle& operator=(const ItemHandle<otherT>& rhs) 149 { 150 return assign(rhs); 151 } 152 transfer(ItemHandle<otherT> & rhs)153 template <class otherT> ItemHandle& transfer(ItemHandle<otherT>& rhs) 154 { 155 if (p != rhs.getp()) 156 { 157 if (p) 158 p->removeReference(); 159 160 p = static_cast<T*>(rhs.getp()); 161 162 rhs.setNull(); 163 } 164 return *this; 165 } 166 transfer(ItemHandle & rhs)167 ItemHandle& transfer(ItemHandle& rhs) 168 { 169 if (p != rhs.p) 170 { 171 if (p) 172 p->removeReference(); 173 174 p = rhs.p; 175 176 rhs.p = NULL; 177 } 178 return *this; 179 } 180 release()181 T* release() 182 { 183 T* tmp = p; 184 p = NULL; 185 return tmp; 186 } 187 188 public: debug()189 std::string debug() const 190 { 191 std::ostringstream oss; 192 oss << "ItemHandle[refcount=" << p->getRefCount() << ']'; 193 return oss.str(); 194 } 195 196 protected: assign(const ItemHandle<otherT> & rhs)197 template <class otherT> ItemHandle& assign(const ItemHandle<otherT>& rhs) 198 { 199 if (p != rhs.getp()) 200 { 201 if (p) 202 p->removeReference(); 203 204 p = static_cast<T*>(rhs.getp()); 205 206 if (p) 207 p->addReference(); 208 } 209 210 return *this; 211 } 212 }; 213 214 215 } // namespace store 216 } // namespace zorba 217 218 #endif 219 220 /* 221 * Local variables: 222 * mode: c++ 223 * End: 224 */ 225 /* vim:set et sw=2 ts=2: */ 226