source: XMLIO_V2/external/include/Poco/SharedPtr.h @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 8.6 KB
Line 
1//
2// SharedPtr.h
3//
4// $Id: //poco/1.3/Foundation/include/Poco/SharedPtr.h#8 $
5//
6// Library: Foundation
7// Package: Core
8// Module:  SharedPtr
9//
10// Definition of the SharedPtr template class.
11//
12// Copyright (c) 2005-2008, 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_SharedPtr_INCLUDED
40#define Foundation_SharedPtr_INCLUDED
41
42
43#include "Poco/Foundation.h"
44#include "Poco/Exception.h"
45#include "Poco/AtomicCounter.h"
46#include <algorithm>
47
48
49namespace Poco {
50
51
52class ReferenceCounter
53        /// Simple ReferenceCounter object, does not delete itself when count reaches 0.
54{
55public:
56        ReferenceCounter(): _cnt(1)
57        {
58        }
59
60        void duplicate()
61        {
62                ++_cnt;
63        }
64
65        int release()
66        {
67                return --_cnt;
68        }
69       
70        int referenceCount() const
71        {
72                return _cnt.value();
73        }
74
75private:
76        AtomicCounter _cnt;
77};
78
79
80template <class C>
81class ReleasePolicy
82        /// The default release policy for SharedPtr, which
83        /// simply uses the delete operator to delete an object.
84{
85public:
86        static void release(C* pObj)
87                /// Delete the object.
88                /// Note that pObj can be 0.
89        {
90                delete pObj;
91        }
92};
93
94
95template <class C>
96class ReleaseArrayPolicy
97        /// The release policy for SharedPtr holding arrays.
98{
99public:
100        static void release(C* pObj)
101                /// Delete the object.
102                /// Note that pObj can be 0.
103        {
104                delete [] pObj;
105        }
106};
107
108
109template <class C, class RC = ReferenceCounter, class RP = ReleasePolicy<C> >
110class SharedPtr
111        /// SharedPtr is a "smart" pointer for classes implementing
112        /// reference counting based garbage collection.
113        /// SharedPtr is thus similar to AutoPtr. Unlike the
114        /// AutoPtr template, which can only be used with
115        /// classes that support reference counting, SharedPtr
116        /// can be used with any class. For this to work, a
117        /// SharedPtr manages a reference count for the object
118        /// it manages.
119        ///
120        /// SharedPtr works in the following way:
121        /// If an SharedPtr is assigned an ordinary pointer to
122        /// an object (via the constructor or the assignment operator),
123        /// it takes ownership of the object and the object's reference
124        /// count is initialized to one.
125        /// If the SharedPtr is assigned another SharedPtr, the
126        /// object's reference count is incremented by one.
127        /// The destructor of SharedPtr decrements the object's
128        /// reference count by one and deletes the object if the
129        /// reference count reaches zero.
130        /// SharedPtr supports dereferencing with both the ->
131        /// and the * operator. An attempt to dereference a null
132        /// SharedPtr results in a NullPointerException being thrown.
133        /// SharedPtr also implements all relational operators and
134        /// a cast operator in case dynamic casting of the encapsulated data types
135        /// is required.
136{
137public:
138        SharedPtr(): _pCounter(new RC), _ptr(0)
139        {
140        }
141
142        SharedPtr(C* ptr): _pCounter(new RC), _ptr(ptr)
143        {
144        }
145
146        template <class Other, class OtherRP> 
147        SharedPtr(const SharedPtr<Other, RC, OtherRP>& ptr): _pCounter(ptr._pCounter), _ptr(const_cast<Other*>(ptr.get()))
148        {
149                _pCounter->duplicate();
150        }
151
152        SharedPtr(const SharedPtr& ptr): _pCounter(ptr._pCounter), _ptr(ptr._ptr)
153        {
154                _pCounter->duplicate();
155        }
156
157        ~SharedPtr()
158        {
159                release();
160        }
161
162        SharedPtr& assign(C* ptr)
163        {
164                if (get() != ptr)
165                {
166                        RC* pTmp = new RC;
167                        release();
168                        _pCounter = pTmp;
169                        _ptr = ptr;
170                }
171                return *this;
172        }
173       
174        SharedPtr& assign(const SharedPtr& ptr)
175        {
176                if (&ptr != this)
177                {
178                        SharedPtr tmp(ptr);
179                        swap(tmp);
180                }
181                return *this;
182        }
183       
184        template <class Other, class OtherRP>
185        SharedPtr& assign(const SharedPtr<Other, RC, OtherRP>& ptr)
186        {
187                if (ptr.get() != _ptr)
188                {
189                        SharedPtr tmp(ptr);
190                        swap(tmp);
191                }
192                return *this;
193        }
194
195        SharedPtr& operator = (C* ptr)
196        {
197                return assign(ptr);
198        }
199
200        SharedPtr& operator = (const SharedPtr& ptr)
201        {
202                return assign(ptr);
203        }
204
205        template <class Other, class OtherRP>
206        SharedPtr& operator = (const SharedPtr<Other, RC, OtherRP>& ptr)
207        {
208                return assign<Other>(ptr);
209        }
210
211        void swap(SharedPtr& ptr)
212        {
213                std::swap(_ptr, ptr._ptr);
214                std::swap(_pCounter, ptr._pCounter);
215        }
216
217        template <class Other> 
218        SharedPtr<Other, RC, RP> cast() const
219                /// Casts the SharedPtr via a dynamic cast to the given type.
220                /// Returns an SharedPtr containing NULL if the cast fails.
221                /// Example: (assume class Sub: public Super)
222                ///    SharedPtr<Super> super(new Sub());
223                ///    SharedPtr<Sub> sub = super.cast<Sub>();
224                ///    poco_assert (sub.get());
225        {
226                Other* pOther = dynamic_cast<Other*>(_ptr);
227                if (pOther)
228                        return SharedPtr<Other, RC, RP>(_pCounter, pOther);
229                return SharedPtr<Other, RC, RP>();
230        }
231
232        template <class Other> 
233        SharedPtr<Other, RC, RP> unsafeCast() const
234                /// Casts the SharedPtr via a static cast to the given type.
235                /// Example: (assume class Sub: public Super)
236                ///    SharedPtr<Super> super(new Sub());
237                ///    SharedPtr<Sub> sub = super.unsafeCast<Sub>();
238                ///    poco_assert (sub.get());
239        {
240                Other* pOther = static_cast<Other*>(_ptr);
241                return SharedPtr<Other, RC, RP>(_pCounter, pOther);
242        }
243
244        C* operator -> ()
245        {
246                return deref();
247        }
248
249        const C* operator -> () const
250        {
251                return deref();
252        }
253
254        C& operator * ()
255        {
256                return *deref();
257        }
258
259        const C& operator * () const
260        {
261                return *deref();
262        }
263
264        C* get()
265        {
266                return _ptr;
267        }
268
269        const C* get() const
270        {
271                return _ptr;
272        }
273
274        operator C* ()
275        {
276                return _ptr;
277        }
278       
279        operator const C* () const
280        {
281                return _ptr;
282        }
283
284        bool operator ! () const
285        {
286                return _ptr == 0;
287        }
288
289        bool isNull() const
290        {
291                return _ptr == 0;
292        }
293
294        bool operator == (const SharedPtr& ptr) const
295        {
296                return get() == ptr.get();
297        }
298
299        bool operator == (const C* ptr) const
300        {
301                return get() == ptr;
302        }
303
304        bool operator == (C* ptr) const
305        {
306                return get() == ptr;
307        }
308
309        bool operator != (const SharedPtr& ptr) const
310        {
311                return get() != ptr.get();
312        }
313
314        bool operator != (const C* ptr) const
315        {
316                return get() != ptr;
317        }
318
319        bool operator != (C* ptr) const
320        {
321                return get() != ptr;
322        }
323
324        bool operator < (const SharedPtr& ptr) const
325        {
326                return get() < ptr.get();
327        }
328
329        bool operator < (const C* ptr) const
330        {
331                return get() < ptr;
332        }
333
334        bool operator < (C* ptr) const
335        {
336                return get() < ptr;
337        }
338
339        bool operator <= (const SharedPtr& ptr) const
340        {
341                return get() <= ptr.get();
342        }
343
344        bool operator <= (const C* ptr) const
345        {
346                return get() <= ptr;
347        }
348
349        bool operator <= (C* ptr) const
350        {
351                return get() <= ptr;
352        }
353
354        bool operator > (const SharedPtr& ptr) const
355        {
356                return get() > ptr.get();
357        }
358
359        bool operator > (const C* ptr) const
360        {
361                return get() > ptr;
362        }
363
364        bool operator > (C* ptr) const
365        {
366                return get() > ptr;
367        }
368
369        bool operator >= (const SharedPtr& ptr) const
370        {
371                return get() >= ptr.get();
372        }
373
374        bool operator >= (const C* ptr) const
375        {
376                return get() >= ptr;
377        }
378
379        bool operator >= (C* ptr) const
380        {
381                return get() >= ptr;
382        }
383       
384        int referenceCount() const
385        {
386                return _pCounter->referenceCount();
387        }
388
389private:
390        C* deref() const
391        {
392                if (!_ptr)
393                        throw NullPointerException();
394
395                return _ptr;
396        }
397
398        void release()
399        {
400                poco_assert_dbg (_pCounter);
401                int i = _pCounter->release();
402                if (i == 0)
403                {
404                        RP::release(_ptr);
405                        _ptr = 0;
406
407                        delete _pCounter;
408                        _pCounter = 0;
409                }
410        }
411
412        SharedPtr(RC* pCounter, C* ptr): _pCounter(pCounter), _ptr(ptr)
413                /// for cast operation
414        {
415                poco_assert_dbg (_pCounter);
416                _pCounter->duplicate();
417        }
418
419private:
420        RC* _pCounter;
421        C*  _ptr;
422
423        template <class OtherC, class OtherRC, class OtherRP> friend class SharedPtr;
424};
425
426
427template <class C, class RC, class RP>
428inline void swap(SharedPtr<C, RC, RP>& p1, SharedPtr<C, RC, RP>& p2)
429{
430        p1.swap(p2);
431}
432
433
434} // namespace Poco
435
436
437#endif // Foundation_SharedPtr_INCLUDED
Note: See TracBrowser for help on using the repository browser.