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