~ubuntu-branches/ubuntu/gutsy/poco/gutsy

« back to all changes in this revision

Viewing changes to Foundation/include/Poco/AutoPtr.h

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Burghardt
  • Date: 2007-04-27 18:33:48 UTC
  • Revision ID: james.westby@ubuntu.com-20070427183348-xgnpct0qd6a2ip34
Tags: upstream-1.2.9
ImportĀ upstreamĀ versionĀ 1.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// AutoPtr.h
 
3
//
 
4
// $Id: //poco/1.2/Foundation/include/Poco/AutoPtr.h#3 $
 
5
//
 
6
// Library: Foundation
 
7
// Package: Core
 
8
// Module:  AutoPtr
 
9
//
 
10
// Definition of the AutoPtr template class.
 
11
//
 
12
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
 
13
// and Contributors.
 
14
//
 
15
// Permission is hereby granted, free of charge, to any person or organization
 
16
// obtaining a copy of the software and accompanying documentation covered by
 
17
// this license (the "Software") to use, reproduce, display, distribute,
 
18
// execute, and transmit the Software, and to prepare derivative works of the
 
19
// Software, and to permit third-parties to whom the Software is furnished to
 
20
// do so, all subject to the following:
 
21
// 
 
22
// The copyright notices in the Software and this entire statement, including
 
23
// the above license grant, this restriction and the following disclaimer,
 
24
// must be included in all copies of the Software, in whole or in part, and
 
25
// all derivative works of the Software, unless such copies or derivative
 
26
// works are solely in the form of machine-executable object code generated by
 
27
// a source language processor.
 
28
// 
 
29
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
30
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
31
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 
32
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 
33
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 
34
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
35
// DEALINGS IN THE SOFTWARE.
 
36
//
 
37
 
 
38
 
 
39
#ifndef Foundation_AutoPtr_INCLUDED
 
40
#define Foundation_AutoPtr_INCLUDED
 
41
 
 
42
 
 
43
#include "Poco/Foundation.h"
 
44
#include "Poco/Exception.h"
 
45
#include <algorithm>
 
46
 
 
47
 
 
48
namespace Poco {
 
49
 
 
50
 
 
51
template <class C>
 
52
class AutoPtr
 
53
        /// AutoPtr is a "smart" pointer for classes implementing
 
54
        /// reference counting based garbage collection.
 
55
        /// To be usable with the AutoPtr template, a class must
 
56
        /// implement the following behaviour:
 
57
        /// A class must maintain a reference count.
 
58
        /// The constructors of the object initialize the reference
 
59
        /// count to one.
 
60
        /// The class must implement a public duplicate() method:
 
61
        ///     void duplicate();
 
62
        /// that increments the reference count by one.
 
63
        /// The class must implement a public release() method:
 
64
        ///     void release()
 
65
        /// that decrements the reference count by one, and,
 
66
        /// if the reference count reaches zero, deletes the
 
67
        /// object.
 
68
        ///
 
69
        /// AutoPtr works in the following way:
 
70
        /// If an AutoPtr is assigned an ordinary pointer to
 
71
        /// an object (via the constructor or the assignment operator),
 
72
        /// it takes ownership of the object and the object's reference 
 
73
        /// count remains unchanged.
 
74
        /// If the AutoPtr is assigned another AutoPtr, the
 
75
        /// object's reference count is incremented by one by
 
76
        /// calling duplicate() on its object.
 
77
        /// The destructor of AutoPtr calls release() on its
 
78
        /// object.
 
79
        /// AutoPtr supports dereferencing with both the ->
 
80
        /// and the * operator. An attempt to dereference a null
 
81
        /// AutoPtr results in a NullPointerException being thrown.
 
82
        /// AutoPtr also implements all relational operators.
 
83
        /// Note that AutoPtr allows casting of its encapsulated data types.
 
84
{
 
85
public:
 
86
        AutoPtr(): _ptr(0)
 
87
        {
 
88
        }
 
89
 
 
90
        AutoPtr(C* ptr): _ptr(ptr)
 
91
        {
 
92
        }
 
93
 
 
94
        AutoPtr(C* ptr, bool shared): _ptr(ptr)
 
95
        {
 
96
                if (shared && _ptr) _ptr->duplicate();
 
97
        }
 
98
 
 
99
        AutoPtr(const AutoPtr& ptr): _ptr(ptr._ptr)
 
100
        {
 
101
                if (_ptr) _ptr->duplicate();
 
102
        }
 
103
 
 
104
        template <class Other> 
 
105
        AutoPtr(const AutoPtr<Other>& ptr): _ptr(const_cast<Other*>(ptr.get()))
 
106
        {
 
107
                if (_ptr) _ptr->duplicate();
 
108
        }
 
109
 
 
110
        ~AutoPtr()
 
111
        {
 
112
                if (_ptr) _ptr->release();
 
113
        }
 
114
        
 
115
        AutoPtr& assign(C* ptr)
 
116
        {
 
117
                if (_ptr != ptr)
 
118
                {
 
119
                        if (_ptr) _ptr->release();
 
120
                        _ptr = ptr;
 
121
                }
 
122
                return *this;
 
123
        }
 
124
 
 
125
        AutoPtr& assign(C* ptr, bool shared)
 
126
        {
 
127
                if (_ptr != ptr)
 
128
                {
 
129
                        if (_ptr) _ptr->release();
 
130
                        _ptr = ptr;
 
131
                        if (shared && _ptr) _ptr->duplicate();
 
132
                }
 
133
                return *this;
 
134
        }
 
135
        
 
136
        AutoPtr& assign(const AutoPtr& ptr)
 
137
        {
 
138
                if (&ptr != this)
 
139
                {
 
140
                        if (_ptr) _ptr->release();
 
141
                        _ptr = ptr._ptr;
 
142
                        if (_ptr) _ptr->duplicate();
 
143
                }
 
144
                return *this;
 
145
        }
 
146
        
 
147
        template <class Other> 
 
148
        AutoPtr& assign(const AutoPtr<Other>& ptr)
 
149
        {
 
150
                if (ptr.get() != _ptr)
 
151
                {
 
152
                        if (_ptr) _ptr->release();
 
153
                        _ptr = const_cast<Other*>(ptr.get());
 
154
                        if (_ptr) _ptr->duplicate();
 
155
                }
 
156
                return *this;
 
157
        }
 
158
 
 
159
        AutoPtr& operator = (C* ptr)
 
160
        {
 
161
                return assign(ptr);
 
162
        }
 
163
 
 
164
        AutoPtr& operator = (const AutoPtr& ptr)
 
165
        {
 
166
                return assign(ptr);
 
167
        }
 
168
        
 
169
        template <class Other> 
 
170
        AutoPtr& operator = (const AutoPtr<Other>& ptr)
 
171
        {
 
172
                return assign<Other>(ptr);
 
173
        }
 
174
 
 
175
        void swap(AutoPtr& ptr)
 
176
        {
 
177
                std::swap(_ptr, ptr._ptr);
 
178
        }
 
179
        
 
180
        template <class Other> 
 
181
        AutoPtr<Other> cast() const
 
182
                /// Casts the AutoPtr via a dynamic cast to the given type.
 
183
                /// Returns an AutoPtr containing NULL if the cast fails.
 
184
                /// Example: (assume class Sub: public Super)
 
185
                ///    AutoPtr<Super> super(new Sub());
 
186
                ///    AutoPtr<Sub> sub = super.cast<Sub>();
 
187
                ///    poco_assert (sub.get());
 
188
        {
 
189
                Other* pOther = dynamic_cast<Other*>(_ptr);
 
190
                return AutoPtr<Other>(pOther, true);
 
191
        }
 
192
 
 
193
        C* operator -> ()
 
194
        {
 
195
                if (_ptr)
 
196
                        return _ptr;
 
197
                else
 
198
                        throw NullPointerException();
 
199
        }
 
200
 
 
201
        const C* operator -> () const
 
202
        {
 
203
                if (_ptr)
 
204
                        return _ptr;
 
205
                else
 
206
                        throw NullPointerException();
 
207
        }
 
208
 
 
209
        C& operator * ()
 
210
        {
 
211
                if (_ptr)
 
212
                        return *_ptr;
 
213
                else
 
214
                        throw NullPointerException();
 
215
        }
 
216
 
 
217
        const C& operator * () const
 
218
        {
 
219
                if (_ptr)
 
220
                        return *_ptr;
 
221
                else
 
222
                        throw NullPointerException();
 
223
        }
 
224
 
 
225
        C* get()
 
226
        {
 
227
                return _ptr;
 
228
        }
 
229
 
 
230
        const C* get() const
 
231
        {
 
232
                return _ptr;
 
233
        }
 
234
 
 
235
        operator C* ()
 
236
        {
 
237
                return _ptr;
 
238
        }
 
239
        
 
240
        operator const C* () const
 
241
        {
 
242
                return _ptr;
 
243
        }
 
244
        
 
245
        bool operator ! () const
 
246
        {
 
247
                return _ptr == 0;
 
248
        }
 
249
 
 
250
        bool isNull() const
 
251
        {
 
252
                return _ptr == 0;
 
253
        }
 
254
        
 
255
        C* duplicate()
 
256
        {
 
257
                if (_ptr) _ptr->duplicate();
 
258
                return _ptr;
 
259
        }
 
260
 
 
261
        bool operator == (const AutoPtr& ptr) const
 
262
        {
 
263
                return _ptr == ptr._ptr;
 
264
        }
 
265
 
 
266
        bool operator == (const C* ptr) const
 
267
        {
 
268
                return _ptr == ptr;
 
269
        }
 
270
 
 
271
        bool operator == (C* ptr) const
 
272
        {
 
273
                return _ptr == ptr;
 
274
        }
 
275
 
 
276
        bool operator != (const AutoPtr& ptr) const
 
277
        {
 
278
                return _ptr != ptr._ptr;
 
279
        }
 
280
 
 
281
        bool operator != (const C* ptr) const
 
282
        {
 
283
                return _ptr != ptr;
 
284
        }
 
285
 
 
286
        bool operator != (C* ptr) const
 
287
        {
 
288
                return _ptr != ptr;
 
289
        }
 
290
 
 
291
        bool operator < (const AutoPtr& ptr) const
 
292
        {
 
293
                return _ptr < ptr._ptr;
 
294
        }
 
295
 
 
296
        bool operator < (const C* ptr) const
 
297
        {
 
298
                return _ptr < ptr;
 
299
        }
 
300
 
 
301
        bool operator < (C* ptr) const
 
302
        {
 
303
                return _ptr < ptr;
 
304
        }
 
305
 
 
306
        bool operator <= (const AutoPtr& ptr) const
 
307
        {
 
308
                return _ptr <= ptr._ptr;
 
309
        }
 
310
 
 
311
        bool operator <= (const C* ptr) const
 
312
        {
 
313
                return _ptr <= ptr;
 
314
        }
 
315
 
 
316
        bool operator <= (C* ptr) const
 
317
        {
 
318
                return _ptr <= ptr;
 
319
        }
 
320
 
 
321
        bool operator > (const AutoPtr& ptr) const
 
322
        {
 
323
                return _ptr > ptr._ptr;
 
324
        }
 
325
 
 
326
        bool operator > (const C* ptr) const
 
327
        {
 
328
                return _ptr > ptr;
 
329
        }
 
330
 
 
331
        bool operator > (C* ptr) const
 
332
        {
 
333
                return _ptr > ptr;
 
334
        }
 
335
 
 
336
        bool operator >= (const AutoPtr& ptr) const
 
337
        {
 
338
                return _ptr >= ptr._ptr;
 
339
        }
 
340
 
 
341
        bool operator >= (const C* ptr) const
 
342
        {
 
343
                return _ptr >= ptr;
 
344
        }
 
345
 
 
346
        bool operator >= (C* ptr) const
 
347
        {
 
348
                return _ptr >= ptr;
 
349
        }
 
350
 
 
351
private:
 
352
        C* _ptr;
 
353
};
 
354
 
 
355
 
 
356
template <class C>
 
357
inline void swap(AutoPtr<C>& p1, AutoPtr<C>& p2)
 
358
{
 
359
        p1.swap(p2);
 
360
}
 
361
 
 
362
 
 
363
} // namespace Poco
 
364
 
 
365
 
 
366
#endif // Foundation_AutoPtr_INCLUDED