]> git.tdb.fi Git - libs/core.git/blob - source/core/refptr.h
dd07256d79d45ca1fa1ff558eacab32ca925ed79
[libs/core.git] / source / core / refptr.h
1 /* $Id$
2
3 This file is part of libmspcore
4 Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #ifndef MSP_CORE_REFPTR_H_
9 #define MSP_CORE_REFPTR_H_
10
11 namespace Msp {
12
13 /**
14 A reference counting smart pointer.  When the last RefPtr for the data gets
15 destroyed, the data is deleted as well.
16 */
17 template<typename T>
18 class RefPtr
19 {
20 public:
21         RefPtr(): data(0), count(0) { }
22         RefPtr(T *d): data(d), count(0) { if(data) count=new unsigned(1); }
23         RefPtr(const RefPtr &p): data(p.data), count(p.count) { incref(); }
24         RefPtr &operator=(const RefPtr &p)
25         {
26                 decref();
27                 data=p.data;
28                 count=p.count;
29                 incref();
30                 return *this;
31         }
32         
33         ~RefPtr() { decref(); }
34
35         /**
36         Makes the RefPtr release its reference of the data.  Note that if there are
37         other RefPtrs left with the same data, it might still get deleted
38         automatically.
39         */
40         T *release()
41         {
42                 T *d=data;
43                 data=0;
44                 decref();
45                 count=0;
46                 return d;
47         }
48
49         T *get() const        { return data; }
50         T &operator*() const  { return *data; }
51         T *operator->() const { return data; }
52         operator bool() const { return data!=0; }
53
54         template<typename U>
55         static RefPtr<T> cast_dynamic(const RefPtr<U> &p)  { return RefPtr<T>(dynamic_cast<T *>(p.data), p.count); }
56         template<typename U> friend class RefPtr;
57 private:
58         T        *data;
59         unsigned *count;
60
61         RefPtr(T *d, unsigned *c): data(d), count(c) { incref(); }
62
63         void  incref()
64         {
65                 if(!count) return;
66                 ++*count;
67         }
68
69         void  decref()
70         {
71                 if(!count) return;
72                 --*count;
73                 if(!*count)
74                 {
75                         delete data;
76                         delete count;
77                         data=0;
78                         count=0;
79                 }
80         }
81 };
82
83 } // namespace Msp
84
85 #endif