SmartPtr.h
1/*
2 * Copyright (C) 2006 by Tommi Maekitalo
3 * Copyright (C) 2006 by Marc Boris Duerner
4 * Copyright (C) 2006 by Stefan Bueder
5 * Copyright (C) 2010-2010 by Aloysius Indrayanto
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * As a special exception, you may use this file as part of a free
13 * software library without restriction. Specifically, if other files
14 * instantiate templates or use macros or inline functions from this
15 * file, or you compile this file and link it with other files to
16 * produce an executable, this file does not by itself cause the
17 * resulting executable to be covered by the GNU General Public
18 * License. This exception does not however invalidate any other
19 * reasons why the executable file might be covered by the GNU Library
20 * General Public License.
21 *
22 * This library is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with this library; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31
32#ifndef PT_SMARTPTR_H
33#define PT_SMARTPTR_H
34
35#include <Pt/Api.h>
36#include <Pt/Atomicity.h>
37#include <Pt/SerializationInfo.h>
38
39namespace Pt {
40
49template <typename T>
51{
52 private:
53 mutable const RefLinked* prev;
54 mutable const RefLinked* next;
55
56 protected:
59 : prev(0),
60 next(0)
61 { }
62
64 bool unlink(T* object)
65 {
66 bool ret = false;
67 if (object)
68 {
69 if (next == this)
70 {
71 ret = true;
72 }
73 else
74 {
75 next->prev = prev;
76 prev->next = next;
77 }
78 next = prev = this;
79 }
80 return ret;
81 }
82
84 void link(const RefLinked& ptr, T* object)
85 {
86 if (object)
87 {
88 prev = &ptr;
89 next = ptr.next;
90 prev->next = this;
91 next->prev = this;
92 }
93 }
94};
95
105
106template <typename T>
107class InternalRefCounted
108{
109 protected:
111 bool unlink(T* object)
112 {
113 if (object)
114 object->release();
115 return false;
116 }
117
119 void link(const InternalRefCounted& ptr, T* object)
120 {
121 if (object)
122 object->addRef();
123 }
124};
125
126
134template <typename T>
136{
137 public:
139 int refs() const
140 { return _count ? *_count : 0; }
141
142 protected:
145 : _count(0)
146 { }
147
149 bool unlink(T* object)
150 {
151 if ( _count && --*_count <= 0)
152 {
153 delete _count;
154 // no need to set _count to 0 since the pointer is either
155 // destroyed or another object is linked in
156 return true;
157 }
158 else
159 return false;
160 }
161
163 void link(const ExternalRefCounted& ptr, T* object)
164 {
165 if(object)
166 {
167 if(ptr._count == 0) {
168 _count = new unsigned(1);
169 }
170 else
171 {
172 _count = ptr._count;
173 ++*_count;
174 }
175 }
176 else
177 _count = 0;
178 }
179
180 private:
181 unsigned* _count;
182};
183
184
185template <typename T>
186class ExternalAtomicRefCounted
187{
188 public:
189 int refs() const
190 { return rc ? atomicGet(*rc) : 0; }
191
192 protected:
193 ExternalAtomicRefCounted()
194 : rc(0)
195 { }
196
197 bool unlink(T* object)
198 {
199 if (object && atomicDecrement(*rc) <= 0)
200 {
201 delete rc;
202 // no need to set rc to 0 since the pointer is either
203 // destroyed or another object is linked in
204 return true;
205 }
206 else
207 return false;
208 }
209
210 void link(const ExternalAtomicRefCounted& ptr, T* object)
211 {
212 if (object)
213 {
214 if (ptr.rc == 0)
215 rc = new atomic_t(1);
216 else
217 {
218 rc = ptr.rc;
219 atomicIncrement(*rc);
220 }
221 }
222 else
223 rc = 0;
224 }
225
226 private:
227 volatile atomic_t* rc;
228};
229
238
239template <typename T>
241{
242 protected:
243 static void destroy(T* ptr)
244 { delete ptr; }
245};
246
247
248template <typename T>
249class FreeDestroyPolicy
250{
251 protected:
252 void destroy(T* ptr)
253 { free(ptr); }
254};
255
256
257template <typename ObjectType>
258class ArrayDestroyPolicy
259{
260 protected:
261 static void destroy(ObjectType* ptr)
262 { delete[] ptr; }
263};
264
265
266template<typename T>
267struct AutoPtrRef
268{
269 T* ptr;
270
271 explicit AutoPtrRef(T* rhs)
272 : ptr(rhs)
273 { }
274};
275
276
288template<typename T,
289 typename Destroy = DeletePolicy<T> >
290class AutoPtr : public Destroy
291{
292 public:
293 typedef T element_type;
294
295 public:
297 explicit AutoPtr(T* ptr = 0)
298 : ap(ptr)
299 { }
300
302 AutoPtr(AutoPtrRef<T> rhs)
303 : ap(rhs.ptr) {
304 }
305
307 AutoPtr& operator= (AutoPtrRef<T> rhs)
308 {
309 reset(rhs.ptr);
310 return *this;
311 }
312
315 { this->destroy(ap); }
316
318 template<class Y>
319 operator AutoPtrRef<Y>()
320 {
321 return AutoPtrRef<Y>( release() );
322 }
323
325 T* get() const {
326 return ap;
327 }
328
330 T& operator*() const {
331 return *ap;
332 }
333
335 T* operator->() const
336 {
337 return ap;
338 }
339
341 bool operator!() const
342 {
343 return ap == 0;
344 }
345
353 operator bool () const
354 { return ap != 0; }
355
358 {
359 T* tmp(ap);
360 ap = 0;
361 return tmp;
362 }
363
365 void reset(T* ptr = 0)
366 {
367 if (ap != ptr)
368 {
369 this->destroy(ap);
370 ap = ptr;
371 }
372 }
373
374 private:
375 AutoPtr(AutoPtr &p);
376
378
379 private:
380 T* ap;
381};
382
383template <typename T>
384AutoPtr<T> move(AutoPtr<T>& p)
385{
386 return AutoPtr<T>( AutoPtrRef<T>(p) );
387}
388
393template <typename T, typename D, typename T2, typename D2>
395{ return a.get() == b.get(); }
396
401template <typename T, typename D, typename T2>
402bool operator==(const AutoPtr<T, D>& a, const T2* b)
403{ return a.get() == b; }
404
405
410template <typename T, typename D, typename T2, typename D2>
412{ return a.get() != b.get(); }
413
418template <typename T, typename D, typename T2>
419bool operator!=(const AutoPtr<T, D>& a, const T2* b)
420{ return a.get() != b; }
421
422
427template <typename T, typename D, typename T2, typename D2>
429{ return a.v() < b.get(); }
430
435template <typename T, typename D, typename T2>
436bool operator<(const AutoPtr<T, D>& a, const T2* b)
437{ return a.get() < b; }
438
439
457template <typename T,
458 typename OwnershipPolicy = ExternalRefCounted<T>,
459 typename DestroyPolicy = DeletePolicy<T> >
460class SmartPtr : public OwnershipPolicy,
461 public DestroyPolicy
462{
463 private:
465 T* object;
466
467 public:
473 : object(0)
474 {}
475
478 explicit SmartPtr(T* ptr)
479 : object(ptr)
480 { this->link(*this, ptr); }
481
484 SmartPtr(const SmartPtr& ptr)
485 : object(ptr.object)
486 { this->link(ptr, ptr.object); }
487
491 {
492 if (this->unlink(object))
493 this->destroy(object);
494 }
495
499 {
500 if(object == ptr.object)
501 return *this;
502
503 if( this->unlink(object) )
504 this->destroy(object);
505
506 object = ptr.object;
507
508 this->link(ptr, object);
509
510 return *this;
511 }
512
513 void reset(T* ptr = 0)
514 {
515 if(object == ptr)
516 return;
517
518 if( this->unlink(object) )
519 this->destroy(object);
520
521 object = ptr;
522
523 this->link(*this, object);
524 }
525
528 T* operator->() const
529 { return object; }
530
533 T& operator*() const
534 { return *object; }
535
538 bool operator! () const
539 { return object == 0; }
540
543 operator bool () const
544 { return object != 0; }
545
548 T* get()
549 { return object; }
550
553 const T* get() const
554 { return object; }
555};
556
557
562template <typename T, class O, typename D, typename T2, typename O2, typename D2>
564{ return a.get() == b.get(); }
565
570template <typename T, typename O, typename D, typename T2>
571bool operator==(const SmartPtr<T, O, D>& a, const T2* b)
572{ return a.get() == b; }
573
574
579template <typename T, typename O, typename D, typename T2, typename O2, typename D2>
581{ return a.get() != b.get(); }
582
587template <typename T, typename O, typename D, typename T2>
588bool operator!=(const SmartPtr<T, O, D>& a, const T2* b)
589{ return a.get() != b; }
590
591
596template <typename T, typename O, typename D, typename T2, typename O2, typename D2>
598{ return a.get() < b.get(); }
599
604template <typename T, typename O, typename D, typename T2>
605bool operator<(const SmartPtr<T, O, D>& a, const T2* b)
606{ return a.get() < b; }
607
608
613template <typename T, typename M, typename D >
615{
616 if( fixup.isNull() )
617 {
618 fixme = SmartPtr<T,M, D>();
619 }
620 else
621 {
622 const SmartPtr<T,M, D>* to = fixup.getTarget< SmartPtr<T, M, D> >();
623 fixme = *to;
624 }
625}
626
631template <typename T, typename M, typename D >
632void load(const LoadInfo& li, SmartPtr<T, M, D>& sp)
633{
634 if( li.in().isReference() )
635 {
636 li.in().loadReference(sp);
637 }
638 else
639 {
640 li.load(sp);
641 }
642}
643
648template <typename T, typename M>
649void operator >>=(const Pt::SerializationInfo& si, SmartPtr<T, M>& sp)
650{
651 sp.reset( new T() );
652 si >>= *sp;
653}
654
659template <typename T, typename M, typename D >
661{
662 if( ! sp.get() || ! si.save( *sp ) )
663 {
664 si.out() <<= sp.get();
665 }
666}
667
672template <typename T, typename M, typename D >
673void operator <<=(Pt::SerializationInfo& si, const SmartPtr<T, M, D>& sp)
674{
675 if( sp.getPointer() )
676 {
677 si <<= *sp;
678 }
679 else
680 {
681 si <<= sp.getPointer();
682 }
683}
684
685} // namespace Pt
686
687#endif // PT_SMARTPTR_H
Policy based Auto pointer.
Definition SmartPtr.h:291
bool operator!=(const AutoPtr< T, D > &a, const AutoPtr< T2, D2 > &b)
Equality comparison operator.
Definition SmartPtr.h:411
T & operator*() const
Access value.
Definition SmartPtr.h:330
bool operator<(const AutoPtr< T, D > &a, const AutoPtr< T2, D2 > &b)
Less-than comparison operator.
Definition SmartPtr.h:428
bool operator<(const AutoPtr< T, D > &a, const T2 *b)
Less-than comparison operator.
Definition SmartPtr.h:436
T * release()
Release ownership.
Definition SmartPtr.h:357
~AutoPtr()
Destructor.
Definition SmartPtr.h:314
bool operator!() const
Returns true if nullptr.
Definition SmartPtr.h:341
AutoPtr(T *ptr=0)
Default constructor.
Definition SmartPtr.h:297
bool operator==(const AutoPtr< T, D > &a, const AutoPtr< T2, D2 > &b)
Equality comparison operator.
Definition SmartPtr.h:394
T * operator->() const
Access value.
Definition SmartPtr.h:335
bool operator==(const AutoPtr< T, D > &a, const T2 *b)
Equality comparison operator.
Definition SmartPtr.h:402
void reset(T *ptr=0)
Reset value.
Definition SmartPtr.h:365
AutoPtr & operator=(AutoPtrRef< T > rhs)
Assignment operator.
Definition SmartPtr.h:307
bool operator!=(const AutoPtr< T, D > &a, const T2 *b)
Equality comparison operator.
Definition SmartPtr.h:419
T * get() const
Access value.
Definition SmartPtr.h:325
AutoPtr(AutoPtrRef< T > rhs)
Copy constructor.
Definition SmartPtr.h:302
Deleter policy for SmartPtr.
Definition SmartPtr.h:241
Non-intrusive reference counting for SmartPtr.
Definition SmartPtr.h:136
int refs() const
Returns the refcount.
Definition SmartPtr.h:139
bool unlink(T *object)
unlink a smart pointer from a managed object
Definition SmartPtr.h:149
ExternalRefCounted()
Default constructor.
Definition SmartPtr.h:144
void link(const ExternalRefCounted &ptr, T *object)
link a smart pointer to a managed object
Definition SmartPtr.h:163
Fixup of references during serialization.
Definition FixupInfo.h:43
Loads referencable types.
Definition SerializationInfo.h:916
const SerializationInfo & in() const
Returns the SerializationInfo to load from.
Definition SerializationInfo.h:925
void load(T &type) const
Loads the type.
Definition SerializationInfo.h:931
bool unlink(T *object)
Unlink a smart pointer from a managed object.
Definition SmartPtr.h:64
RefLinked()
Default constructor.
Definition SmartPtr.h:58
void link(const RefLinked &ptr, T *object)
Link a smart pointer to a managed object.
Definition SmartPtr.h:84
Saves referencable types.
Definition SerializationInfo.h:843
SerializationInfo & out() const
Returns the SerializationInfo to save to.
Definition SerializationInfo.h:852
bool save(const T &type)
Returns true if type was saved, false if type was already saved.
Definition SerializationInfo.h:858
Represents arbitrary types during serialization.
Definition SerializationInfo.h:59
bool isReference() const
Returns true if reference.
Definition SerializationInfo.h:168
void loadReference(T &fixme, unsigned mid=0) const
Load a reference during deserialization.
Definition SerializationInfo.h:579
T * get()
Get non-owning pointer.
Definition SmartPtr.h:548
T & operator*() const
Access value.
Definition SmartPtr.h:533
SmartPtr(T *ptr)
Constructs from a pointer to manage.
Definition SmartPtr.h:478
bool unlink(T *object)
unlink a smart pointer from a managed object
Definition SmartPtr.h:111
bool operator==(const SmartPtr< T, O, D > &a, const T2 *b)
Equality comparison operator.
Definition SmartPtr.h:571
SmartPtr(const SmartPtr &ptr)
Copy constructor.
Definition SmartPtr.h:484
void fixup(const Pt::FixupInfo &fixup, SmartPtr< T, M, D > &fixme)
Custom fixup for deserialization.
Definition SmartPtr.h:614
bool operator!() const
Returns true if the raw pointer is null.
Definition SmartPtr.h:538
SmartPtr()
Default Constructor.
Definition SmartPtr.h:472
bool operator!=(const SmartPtr< T, O, D > &a, const T2 *b)
Equality comparison operator.
Definition SmartPtr.h:588
T * operator->() const
Access value.
Definition SmartPtr.h:528
void save(Pt::SaveInfo &si, const SmartPtr< T, M, D > &sp)
Custom saving for serialization.
Definition SmartPtr.h:660
bool operator<(const SmartPtr< T, O, D > &a, const T2 *b)
Less-than comparison operator.
Definition SmartPtr.h:605
SmartPtr & operator=(const SmartPtr &ptr)
Assign from another SmartPtr.
Definition SmartPtr.h:498
void load(const LoadInfo &li, SmartPtr< T, M, D > &sp)
Custom loading for deserialization.
Definition SmartPtr.h:632
bool operator<(const SmartPtr< T, O, D > &a, const SmartPtr< T2, O2, D2 > &b)
Less-than comparison operator.
Definition SmartPtr.h:597
void link(const InternalRefCounted &ptr, T *object)
link a smart pointer to a managed object
Definition SmartPtr.h:119
~SmartPtr()
Destructor.
Definition SmartPtr.h:490
bool operator==(const SmartPtr< T, O, D > &a, const SmartPtr< T2, O2, D2 > &b)
Equality comparison operator.
Definition SmartPtr.h:563
bool operator!=(const SmartPtr< T, O, D > &a, const SmartPtr< T2, O2, D2 > &b)
Equality comparison operator.
Definition SmartPtr.h:580
const T * get() const
Get non-owning pointer.
Definition SmartPtr.h:553
int atomicDecrement(volatile atomic_t &val)
Decreases a value by one as an atomic operation.
int atomicGet(volatile atomic_t &val)
Atomically get a value.
int atomicIncrement(volatile atomic_t &val)
Increases a value by one as an atomic operation.
Core module.
Definition Allocator.h:33
atomic_t(int v=0)
Construct with initial value.