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