1/*
2 * PROGRAM: JRD Access Method
3 * MODULE: auto.h
4 * DESCRIPTION: STL::auto_ptr replacement
5 *
6 * *** warning ***
7 * Unlike STL's auto_ptr ALWAYS deletes ptr in destructor -
8 * no ownership flag!
9 *
10 * The contents of this file are subject to the Initial
11 * Developer's Public License Version 1.0 (the "License");
12 * you may not use this file except in compliance with the
13 * License. You may obtain a copy of the License at
14 * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
15 *
16 * Software distributed under the License is distributed AS IS,
17 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
18 * See the License for the specific language governing rights
19 * and limitations under the License.
20 *
21 * The Original Code was created by Alexander Peshkoff
22 * for the Firebird Open Source RDBMS project.
23 *
24 * Copyright (c) 2004 Alexander Peshkoff <peshkoff@mail.ru>
25 * and all contributors signed below.
26 *
27 * All Rights Reserved.
28 * Contributor(s): ______________________________________.
29 */
30
31#ifndef CLASSES_AUTO_PTR_H
32#define CLASSES_AUTO_PTR_H
33
34#include <stdio.h>
35
36namespace Firebird {
37
38
39template <typename What>
40class SimpleDelete
41{
42public:
43 static void clear(What* ptr)
44 {
45 delete ptr;
46 }
47};
48
49template <typename What>
50class ArrayDelete
51{
52public:
53 static void clear(What* ptr)
54 {
55 delete[] ptr;
56 }
57};
58
59template <typename T>
60class SimpleRelease
61{
62public:
63 static void clear(T* ptr)
64 {
65 if (ptr)
66 {
67 ptr->release();
68 }
69 }
70};
71
72
73template <typename T>
74class SimpleDispose
75{
76public:
77 static void clear(T* ptr)
78 {
79 if (ptr)
80 {
81 ptr->dispose();
82 }
83 }
84};
85
86
87template <typename Where, typename Clear = SimpleDelete<Where> >
88class AutoPtr
89{
90private:
91 Where* ptr;
92public:
93 AutoPtr<Where, Clear>(Where* v = NULL)
94 : ptr(v)
95 {}
96
97 ~AutoPtr()
98 {
99 Clear::clear(ptr);
100 }
101
102 AutoPtr<Where, Clear>& operator= (Where* v)
103 {
104 Clear::clear(ptr);
105 ptr = v;
106 return *this;
107 }
108
109 operator Where*()
110 {
111 return ptr;
112 }
113
114 Where* get()
115 {
116 return ptr;
117 }
118
119 operator const Where*() const
120 {
121 return ptr;
122 }
123
124 const Where* get() const
125 {
126 return ptr;
127 }
128
129 bool operator !() const
130 {
131 return !ptr;
132 }
133
134 bool hasData() const
135 {
136 return ptr != NULL;
137 }
138
139 Where* operator->()
140 {
141 return ptr;
142 }
143
144 const Where* operator->() const
145 {
146 return ptr;
147 }
148
149 Where* release()
150 {
151 Where* tmp = ptr;
152 ptr = NULL;
153 return tmp;
154 }
155
156 void reset(Where* v = NULL)
157 {
158 if (v != ptr)
159 {
160 Clear::clear(ptr);
161 ptr = v;
162 }
163 }
164
165private:
166 AutoPtr<Where, Clear>(AutoPtr<Where, Clear>&);
167 void operator=(AutoPtr<Where, Clear>&);
168};
169
170
171template <typename T>
172class AutoSetRestore
173{
174public:
175 AutoSetRestore(T* aValue, T newValue)
176 : value(aValue),
177 oldValue(*aValue)
178 {
179 *value = newValue;
180 }
181
182 ~AutoSetRestore()
183 {
184 *value = oldValue;
185 }
186
187private:
188 // copying is prohibited
189 AutoSetRestore(const AutoSetRestore&);
190 AutoSetRestore& operator =(const AutoSetRestore&);
191
192 T* value;
193 T oldValue;
194};
195
196template <typename T, typename T2>
197class AutoSetRestore2
198{
199private:
200 typedef T (T2::*Getter)();
201 typedef void (T2::*Setter)(T);
202
203public:
204 AutoSetRestore2(T2* aPointer, Getter aGetter, Setter aSetter, T newValue)
205 : pointer(aPointer),
206 setter(aSetter),
207 oldValue((aPointer->*aGetter)())
208 {
209 (aPointer->*aSetter)(newValue);
210 }
211
212 ~AutoSetRestore2()
213 {
214 (pointer->*setter)(oldValue);
215 }
216
217private:
218 // copying is prohibited
219 AutoSetRestore2(const AutoSetRestore2&);
220 AutoSetRestore2& operator =(const AutoSetRestore2&);
221
222private:
223 T2* pointer;
224 Setter setter;
225 T oldValue;
226};
227
228
229// One more typical class for AutoPtr cleanup
230class FileClose
231{
232public:
233 static void clear(FILE *f)
234 {
235 if (f) {
236 fclose(f);
237 }
238 }
239};
240
241
242} //namespace Firebird
243
244#endif // CLASSES_AUTO_PTR_H
245
246