2 suPHP - (c)2002-2005 Sebastian Marsching <sebastian@marsching.com>
4 This file is part of suPHP.
6 suPHP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 suPHP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with suPHP; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef SUPHP_SMARTPTR_H
27 #define SUPHP_SMARTPTR_H
31 #include "PointerException.hpp"
35 * Class template encapsulating pointers.
40 static std::map<T*, int> *counter;
43 void increment(T* key_ptr);
44 void decrement(T* key_ptr);
48 * Constructor using NULL pointer
53 * Constructor taking T* as argument
60 SmartPtr(const SmartPtr<T>& ref);
70 const SmartPtr& operator=(const SmartPtr<T>& ref);
73 * Dereference operator.
74 * Returns reference to object hold by smart pointer
76 T& operator*() const throw(PointerException);
79 * Member access operator
81 T* operator->() const throw(PointerException);
84 * Returns underlying pointer
89 * Returns underlying pointer and releases it
90 * from management by the SmartPtr.
91 * Throws an exception if underlying pointer is
92 * hold by more than one SmartPtr.
94 T* release() throw (PointerException);
97 * Resets SmartPtr to point to another object
99 void reset(T* obj_ptr);
102 * Compares to pointers.
103 * Returns true, if both point to the same object,
106 bool operator==(const SmartPtr<T>& ref);
111 std::map<T*, int> *suPHP::SmartPtr<T>::counter;
114 suPHP::SmartPtr<T>::SmartPtr() {
115 if (SmartPtr<T>::counter == NULL) {
116 SmartPtr<T>::counter = new std::map<T*, int>;
122 suPHP::SmartPtr<T>::SmartPtr(T* obj_ptr) {
123 if (SmartPtr<T>::counter == NULL) {
124 SmartPtr<T>::counter = new std::map<T*, int>;
127 this->increment(obj_ptr);
131 suPHP::SmartPtr<T>::SmartPtr(const SmartPtr<T>& ref) {
132 if (SmartPtr<T>::counter == NULL) {
133 SmartPtr<T>::counter = new std::map<T*, int>;
137 this->increment(ref.ptr);
141 suPHP::SmartPtr<T>::~SmartPtr() {
142 if (this->ptr != NULL)
143 this->decrement(this->ptr);
144 if (SmartPtr<T>::counter != NULL && SmartPtr<T>::counter->size() == 0) {
145 delete SmartPtr<T>::counter;
146 SmartPtr<T>::counter = NULL;
151 const SmartPtr<T>& suPHP::SmartPtr<T>::operator=(
152 const SmartPtr<T>& ref) {
158 T& suPHP::SmartPtr<T>::operator*() const throw (PointerException) {
159 if (this->ptr == NULL)
160 throw PointerException("Cannot dereference NULL pointer",
166 T* suPHP::SmartPtr<T>::operator->() const throw (PointerException) {
167 if (this->ptr == NULL)
168 throw PointerException("Cannot access member of NULL pointer",
174 T* suPHP::SmartPtr<T>::get() const {
179 T* suPHP::SmartPtr<T>::release() throw (PointerException) {
180 T* obj_ptr = this->ptr;
184 int& c = SmartPtr<T>::counter->find(obj_ptr)->second;
187 throw PointerException(
188 "Cannot release object hold by more than one SmartPointer.",
191 SmartPtr<T>::counter->erase(obj_ptr);
198 void suPHP::SmartPtr<T>::reset(T* obj_ptr) {
199 if (obj_ptr != this->ptr) {
200 this->decrement(this->ptr);
202 this->increment(obj_ptr);
207 void suPHP::SmartPtr<T>::increment(T* key_ptr) {
211 if (SmartPtr<T>::counter->find(key_ptr)
212 != SmartPtr<T>::counter->end()) {
213 (SmartPtr<T>::counter->find(key_ptr)->second)++;
215 std::pair<T*, int> p;
218 SmartPtr<T>::counter->insert(p);
223 void suPHP::SmartPtr<T>::decrement(T* key_ptr) {
227 int& c = SmartPtr<T>::counter->find(key_ptr)->second;
231 SmartPtr<T>::counter->erase(key_ptr);
236 bool suPHP::SmartPtr<T>::operator==(const SmartPtr<T>& ref) {
237 if (this->get() == ref.get())
245 #endif // SUPHP_SMARTPTR_H