cwidget  0.5.17
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 
14 namespace 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:19
T * unsafe_get_ref() const
Extract the pointer.
Definition: ref_ptr.h:159
The namespace containing everything defined by cwidget.
Definition: columnify.cc:26