1 #ifndef MSP_CORE_REFPTR_H_
2 #define MSP_CORE_REFPTR_H_
10 KEEP = 1U<<(sizeof(unsigned)*8-1)
15 RefCounts(): count(0) { }
20 A reference counting smart pointer. When the last RefPtr for the data gets
21 destroyed, the data is deleted as well.
26 template<typename U> friend class RefPtr;
33 RefPtr(): data(0), counts(0) { }
34 RefPtr(T *d): data(d), counts(data ? new RefCounts : 0) { incref(); }
36 RefPtr(T *d, RefCounts *c): data(d), counts(d ? c : 0) { incref(); }
39 /* Must have this or the compiler will generate a default copy-c'tor despite
40 the template version */
41 RefPtr(const RefPtr &p): data(p.data), counts(p.counts) { incref(); }
44 RefPtr(const RefPtr<U> &p): data(p.data), counts(p.counts) { incref(); }
46 ~RefPtr() { decref(); }
48 RefPtr &operator=(T *);
50 // Likewise for the assignment operator
51 RefPtr &operator=(const RefPtr &p) { return assign(p); }
54 RefPtr &operator=(const RefPtr<U> &p) { return assign(p); }
58 RefPtr &assign(const RefPtr<U> &);
61 /** Makes the RefPtr release its reference of the data without deleting it.
62 Note that if there are other RefPtrs left with the same data, it might
63 still get deleted automatically. */
66 /** Marks the data to not be deleted. This affects all RefPtrs with the
68 void keep() { if(counts) counts->count |= RefCounts::KEEP; }
70 T *get() const { return data; }
71 T &operator*() const { return *data; }
72 T *operator->() const { return data; }
73 operator bool() const { return data!=0; }
75 unsigned refcount() const { return (data ? counts->count : 0); }
78 static RefPtr<T> cast_dynamic(const RefPtr<U> &p)
79 { return RefPtr<T>(dynamic_cast<T *>(p.data), p.counts); }
82 void incref() { if(counts) ++counts->count; }
88 RefPtr<T> &RefPtr<T>::operator=(T *d)
92 counts = (d ? new RefCounts : 0);
99 RefPtr<T> &RefPtr<T>::assign(const RefPtr<U> &p)
109 T *RefPtr<T>::release()
119 void RefPtr<T>::decref()
130 else if(counts->count==RefCounts::KEEP)