L4Re – L4 Runtime Environment
ref_ptr
1 // vim:set ft=cpp: -*- Mode: C++ -*-
2 /*
3  * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
4  * economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  *
10  * As a special exception, you may use this file as part of a free software
11  * library without restriction. Specifically, if other files instantiate
12  * templates or use macros or inline functions from this file, or you compile
13  * this file and link it with other files to produce an executable, this
14  * file does not by itself cause the resulting executable to be covered by
15  * the GNU General Public License. This exception does not however
16  * invalidate any other reasons why the executable file might be covered by
17  * the GNU General Public License.
18  */
19 
20 #pragma once
21 
22 #include "type_traits"
23 #include <cstddef>
24 #include <l4/sys/compiler.h>
25 
26 namespace cxx {
27 
28 template< typename T >
29 struct Default_ref_counter
30 {
31  void h_drop_ref(T *p) noexcept
32  {
33  if (p->remove_ref() == 0)
34  delete p;
35  }
36 
37  void h_take_ref(T *p) noexcept
38  {
39  p->add_ref();
40  }
41 };
42 
43 struct Ref_ptr_base
44 {
45  enum Default_value
46  { Nil = 0 };
47 };
48 
49 template<typename T, template< typename X > class CNT = Default_ref_counter>
50 class Weak_ptr;
51 
77 template <
78  typename T = void,
79  template< typename X > class CNT = Default_ref_counter
80 >
81 class Ref_ptr : public Ref_ptr_base, private CNT<T>
82 {
83 private:
84  typedef decltype(nullptr) Null_type;
85  typedef Weak_ptr<T, CNT> Wp;
86 
87 public:
89  Ref_ptr() noexcept : _p(0) {}
90 
91  Ref_ptr(Ref_ptr_base::Default_value v) : _p((T*)v) {}
92 
98  Ref_ptr(Wp const &o) noexcept : _p(o.ptr())
99  { __take_ref(); }
100 
102  Ref_ptr(decltype(nullptr) n) noexcept : _p(n) {}
103 
110  template<typename X>
111  explicit Ref_ptr(X *o) noexcept : _p(o)
112  { __take_ref(); }
113 
124  Ref_ptr(T *o, bool d) noexcept : _p(o) { (void)d; }
125 
131  T *get() const noexcept
132  {
133  return _p;
134  }
135 
137  T *ptr() const noexcept
138  {
139  return _p;
140  }
141 
148  T *release() noexcept
149  {
150  T *p = _p;
151  _p = 0;
152  return p;
153  }
154 
155  ~Ref_ptr() noexcept
156  { __drop_ref(); }
157 
158  template<typename OT>
159  Ref_ptr(Ref_ptr<OT, CNT> const &o) noexcept
160  {
161  _p = o.ptr();
162  __take_ref();
163  }
164 
165  Ref_ptr(Ref_ptr<T> const &o) noexcept
166  {
167  _p = o._p;
168  __take_ref();
169  }
170 
171  template< typename OT >
172  void operator = (Ref_ptr<OT> const &o) noexcept
173  {
174  __drop_ref();
175  _p = o.ptr();
176  __take_ref();
177  }
178 
179  void operator = (Ref_ptr<T> const &o) noexcept
180  {
181  if (&o == this)
182  return;
183 
184  __drop_ref();
185  _p = o._p;
186  __take_ref();
187  }
188 
189  void operator = (Null_type) noexcept
190  {
191  __drop_ref();
192  _p = 0;
193  }
194 
195  template<typename OT>
196  Ref_ptr(Ref_ptr<OT, CNT> &&o) noexcept
197  { _p = o.release(); }
198 
199  Ref_ptr(Ref_ptr<T> &&o) noexcept
200  { _p = o.release(); }
201 
202  template< typename OT >
203  void operator = (Ref_ptr<OT> &&o) noexcept
204  {
205  __drop_ref();
206  _p = o.release();
207  }
208 
209  void operator = (Ref_ptr<T> &&o) noexcept
210  {
211  if (&o == this)
212  return;
213 
214  __drop_ref();
215  _p = o.release();
216  }
217 
218  explicit operator bool () const noexcept { return _p; }
219 
220  T *operator -> () const noexcept
221  { return _p; }
222 
223  bool operator == (Ref_ptr const &o) const noexcept
224  { return _p == o._p; }
225 
226  bool operator != (Ref_ptr const &o) const noexcept
227  { return _p != o._p; }
228 
229  bool operator < (Ref_ptr const &o) const noexcept
230  { return _p < o._p; }
231 
232  bool operator <= (Ref_ptr const &o) const noexcept
233  { return _p <= o._p; }
234 
235  bool operator > (Ref_ptr const &o) const noexcept
236  { return _p > o._p; }
237 
238  bool operator >= (Ref_ptr const &o) const noexcept
239  { return _p >= o._p; }
240 
241  bool operator == (T const *o) const noexcept
242  { return _p == o; }
243 
244  bool operator < (T const *o) const noexcept
245  { return _p < o; }
246 
247  bool operator <= (T const *o) const noexcept
248  { return _p <= o; }
249 
250  bool operator > (T const *o) const noexcept
251  { return _p > o; }
252 
253  bool operator >= (T const *o) const noexcept
254  { return _p >= o; }
255 
256 private:
257  void __drop_ref() noexcept
258  {
259  if (_p)
260  static_cast<CNT<T>*>(this)->h_drop_ref(_p);
261  }
262 
263  void __take_ref() noexcept
264  {
265  if (_p)
266  static_cast<CNT<T>*>(this)->h_take_ref(_p);
267  }
268 
269  T *_p;
270 };
271 
272 
273 template<typename T, template< typename X > class CNT>
274 class Weak_ptr
275 {
276 private:
277  struct Null_type;
278  typedef Ref_ptr<T, CNT> Rp;
279 
280 public:
281  Weak_ptr() = default;
282  Weak_ptr(decltype(nullptr)) : _p(nullptr) {}
283  // backwards 0 ctor
284  explicit Weak_ptr(int x) noexcept
285  L4_DEPRECATED("Use initialization from 'nullptr'")
286  : _p(nullptr)
287  { if (x != 0) __builtin_trap(); }
288 
289  Weak_ptr(Rp const &o) noexcept : _p(o.ptr()) {}
290  explicit Weak_ptr(T *o) noexcept : _p(o) {}
291 
292  template<typename OT>
293  Weak_ptr(Weak_ptr<OT, CNT> const &o) noexcept : _p(o.ptr()) {}
294 
295  Weak_ptr(Weak_ptr<T, CNT> const &o) noexcept : _p(o._p) {}
296 
297  Weak_ptr<T, CNT> &operator = (const Weak_ptr<T, CNT> &o) = default;
298 
299  T *get() const noexcept { return _p; }
300  T *ptr() const noexcept { return _p; }
301 
302  T *operator -> () const noexcept { return _p; }
303  operator Null_type const * () const noexcept
304  { return reinterpret_cast<Null_type const*>(_p); }
305 
306 private:
307  T *_p;
308 };
309 
310 template<typename OT, typename T> inline
311 Ref_ptr<OT> ref_ptr_static_cast(Ref_ptr<T> const &o)
312 { return ref_ptr(static_cast<OT*>(o.ptr())); }
313 
314 template< typename T >
315 inline Ref_ptr<T> ref_ptr(T *t)
316 { return Ref_ptr<T>(t); }
317 
318 template< typename T >
319 inline Weak_ptr<T> weak_ptr(T *t)
320 { return Weak_ptr<T>(t); }
321 
322 
323 class Ref_obj
324 {
325 private:
326  mutable int _ref_cnt;
327 
328 public:
329  Ref_obj() : _ref_cnt(0) {}
330  void add_ref() const noexcept { ++_ref_cnt; }
331  int remove_ref() const noexcept { return --_ref_cnt; }
332 };
333 
334 template< typename T, typename... Args >
335 Ref_ptr<T>
336 make_ref_obj(Args &&... args)
337 { return cxx::Ref_ptr<T>(new T(cxx::forward<Args>(args)...)); }
338 
339 template<typename T, typename U>
340 Ref_ptr<T>
341 dynamic_pointer_cast(Ref_ptr<U> const &p) noexcept
342 {
343  // our constructor from a naked pointer increments the counter
344  return Ref_ptr<T>(dynamic_cast<T *>(p.get()));
345 }
346 
347 template<typename T, typename U>
348 Ref_ptr<T>
349 static_pointer_cast(Ref_ptr<U> const &p) noexcept
350 {
351  // our constructor from a naked pointer increments the counter
352  return Ref_ptr<T>(static_cast<T *>(p.get()));
353 }
354 
355 }
A reference-counting pointer with automatic cleanup.
Definition: ref_ptr:82
Ref_ptr(Wp const &o) noexcept
Create a shared pointer from a weak pointer.
Definition: ref_ptr:98
Ref_ptr() noexcept
Default constructor creates a pointer with no managed object.
Definition: ref_ptr:89
Ref_ptr(decltype(nullptr) n) noexcept
allow creation from nullptr
Definition: ref_ptr:102
T * get() const noexcept
Return a raw pointer to the object this shared pointer points to.
Definition: ref_ptr:131
T * release() noexcept
Release the shared pointer without removing the reference.
Definition: ref_ptr:148
Ref_ptr(X *o) noexcept
Create a shared pointer from a raw pointer.
Definition: ref_ptr:111
Ref_ptr(T *o, bool d) noexcept
Create a shared pointer from a raw pointer without creating a new reference.
Definition: ref_ptr:124
T * ptr() const noexcept
Return a raw pointer to the object this shared pointer points to.
Definition: ref_ptr:137
L4 compiler related defines.
#define L4_DEPRECATED(s)
Mark symbol deprecated.
Definition: compiler.h:243
Our C++ library.
Definition: arith:22