cwidget 0.5.18
ref_ptr.h
1// ref_ptr.h -*-c++-*-
2//
3// A reference-counting pointer. The object behind the pointer should
4// implement incref() and decref(); the pointer arranges for these
5// methods to be called at the appropriate times.
6
7#ifndef REF_PTR_H
8#define REF_PTR_H
9
10#include <sigc++/reference_wrapper.h>
11
12#include <cwidget/generic/util/eassert.h>
13
14namespace cwidget
15{
16 namespace util
17 {
18 template<class T>
19 class ref_ptr
20 {
21 T *ref;
22
23 public:
24 ref_ptr(T *_ref)
25 :ref(_ref)
26 {
27 if(ref != 0)
28 ref->incref();
29 }
30
31 ref_ptr(const ref_ptr &other)
32 :ref(other.ref)
33 {
34 if(ref != 0)
35 ref->incref();
36 }
37
38 template<class S>
39 ref_ptr(const ref_ptr<S> &other)
40 :ref(other.unsafe_get_ref())
41 {
42 if(ref != 0)
43 ref->incref();
44 }
45
46 ref_ptr()
47 :ref(0)
48 {
49 }
50
51 ~ref_ptr()
52 {
53 if(ref != 0)
54 ref->decref();
55 }
56
57 ref_ptr &operator=(const ref_ptr &other)
58 {
59 if(other.ref != 0)
60 other.ref->incref();
61
62 if(ref != 0)
63 ref->decref();
64
65 ref = other.ref;
66
67 return *this;
68 }
69
70 const sigc::reference_wrapper<T> weak_ref() const
71 {
72 eassert(ref != 0);
73
74 return sigc::ref(*ref);
75 }
76
77 // If S is assignment-compatible with T and both have
78 // reference-counting methods, perform this assignment.
79 //
80 // Read: upcasting pointers.
81 template<class S>
82 ref_ptr<T> &operator=(const ref_ptr<S> &other)
83 {
84 S * const other_ref = other.unsafe_get_ref();
85
86 if(other_ref != 0)
87 other_ref->incref();
88
89 if(ref != 0)
90 ref->decref();
91
92 ref = other_ref;
93
94 return *this;
95 }
96
97 template<class S>
98 bool operator==(const ref_ptr<S> &other) const
99 {
100 return ref == other.unsafe_get_ref();
101 }
102
103 template<class S>
104 bool operator!=(const ref_ptr<S> &other) const
105 {
106 return ref != other.unsafe_get_ref();
107 }
108
109 template<class S>
110 bool operator<(const ref_ptr<S> &other) const
111 {
112 return ref < other.unsafe_get_ref();
113 }
114
115 template<class S>
116 bool operator>(const ref_ptr<S> &other) const
117 {
118 return ref > other.unsafe_get_ref();
119 }
120
121 template<class S>
122 bool operator<=(const ref_ptr<S> &other) const
123 {
124 return ref <= other.unsafe_get_ref();
125 }
126
127 template<class S>
128 bool operator>=(const ref_ptr<S> &other) const
129 {
130 return ref >= other.unsafe_get_ref();
131 }
132
133 // Safe downcasting.
134 template<class S>
135 ref_ptr<S> dyn_downcast() const
136 {
137 return ref_ptr<S>(dynamic_cast<S*>(ref));
138 }
139
140 void clear()
141 {
142 (*this) = 0;
143 }
144
145 bool valid() const
146 {
147 return ref != 0;
148 }
149
150 T *operator->() const
151 {
152 return ref;
153 }
154
159 T *unsafe_get_ref() const
160 {
161 return ref;
162 }
163 };
164 }
165}
166
167#endif
Definition ref_ptr.h:20
T * unsafe_get_ref() const
Extract the pointer.
Definition ref_ptr.h:159
The namespace containing everything defined by cwidget.
Definition columnify.cc:28