L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
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
26namespace cxx {
27
28template< typename T >
29struct 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
43struct Ref_ptr_base
44{
45 enum Default_value
46 { Nil = 0 };
47};
48
49template<typename T, template< typename X > class CNT = Default_ref_counter>
50class Weak_ptr;
51
77template <
78 typename T = void,
79 template< typename X > class CNT = Default_ref_counter
80>
81class Ref_ptr : public Ref_ptr_base, private CNT<T>
82{
83private:
84 typedef decltype(nullptr) Null_type;
85 typedef Weak_ptr<T, CNT> Wp;
86
87public:
89 Ref_ptr() noexcept : _p(0) {}
90
91 Ref_ptr(Ref_ptr_base::Default_value v)
92 : _p(reinterpret_cast<T*>(static_cast<unsigned long>(v))) {}
93
99 Ref_ptr(Wp const &o) noexcept : _p(o.ptr())
100 { __take_ref(); }
101
103 Ref_ptr(decltype(nullptr) n) noexcept : _p(n) {}
104
111 template<typename X>
112 explicit Ref_ptr(X *o) noexcept : _p(o)
113 { __take_ref(); }
114
125 Ref_ptr(T *o, [[maybe_unused]] bool d) noexcept : _p(o) { }
126
132 T *get() const noexcept __attribute__((pure))
133 {
134 return _p;
135 }
136
138 T *ptr() const noexcept __attribute__((pure))
139 {
140 return _p;
141 }
142
149 T *release() noexcept
150 {
151 T *p = _p;
152 _p = 0;
153 return p;
154 }
155
156 ~Ref_ptr() noexcept
157 { __drop_ref(); }
158
159 template<typename OT>
160 Ref_ptr(Ref_ptr<OT, CNT> const &o) noexcept
161 {
162 _p = o.ptr();
163 __take_ref();
164 }
165
166 Ref_ptr(Ref_ptr<T> const &o) noexcept
167 {
168 _p = o._p;
169 __take_ref();
170 }
171
172 template< typename OT >
173 void operator = (Ref_ptr<OT> const &o) noexcept
174 {
175 __drop_ref();
176 _p = o.ptr();
177 __take_ref();
178 }
179
180 void operator = (Ref_ptr<T> const &o) noexcept
181 {
182 if (&o == this)
183 return;
184
185 __drop_ref();
186 _p = o._p;
187 __take_ref();
188 }
189
190 void operator = (Null_type) noexcept
191 {
192 __drop_ref();
193 _p = 0;
194 }
195
196 template<typename OT>
197 Ref_ptr(Ref_ptr<OT, CNT> &&o) noexcept
198 { _p = o.release(); }
199
200 Ref_ptr(Ref_ptr<T> &&o) noexcept
201 { _p = o.release(); }
202
203 template< typename OT >
204 void operator = (Ref_ptr<OT> &&o) noexcept
205 {
206 __drop_ref();
207 _p = o.release();
208 }
209
210 void operator = (Ref_ptr<T> &&o) noexcept
211 {
212 if (&o == this)
213 return;
214
215 __drop_ref();
216 _p = o.release();
217 }
218
219 explicit operator bool () const noexcept { return _p; }
220
221 T *operator -> () const noexcept
222 { return _p; }
223
224 bool operator == (Ref_ptr const &o) const noexcept
225 { return _p == o._p; }
226
227 bool operator != (Ref_ptr const &o) const noexcept
228 { return _p != o._p; }
229
230 bool operator < (Ref_ptr const &o) const noexcept
231 { return _p < o._p; }
232
233 bool operator <= (Ref_ptr const &o) const noexcept
234 { return _p <= o._p; }
235
236 bool operator > (Ref_ptr const &o) const noexcept
237 { return _p > o._p; }
238
239 bool operator >= (Ref_ptr const &o) const noexcept
240 { return _p >= o._p; }
241
242 bool operator == (T const *o) const noexcept
243 { return _p == o; }
244
245 bool operator < (T const *o) const noexcept
246 { return _p < o; }
247
248 bool operator <= (T const *o) const noexcept
249 { return _p <= o; }
250
251 bool operator > (T const *o) const noexcept
252 { return _p > o; }
253
254 bool operator >= (T const *o) const noexcept
255 { return _p >= o; }
256
257private:
258 void __drop_ref() noexcept
259 {
260 if (_p)
261 static_cast<CNT<T>*>(this)->h_drop_ref(_p);
262 }
263
264 void __take_ref() noexcept
265 {
266 if (_p)
267 static_cast<CNT<T>*>(this)->h_take_ref(_p);
268 }
269
270 T *_p;
271};
272
273
274template<typename T, template< typename X > class CNT>
275class Weak_ptr
276{
277private:
278 struct Null_type;
279 typedef Ref_ptr<T, CNT> Rp;
280
281public:
282 Weak_ptr() = default;
283 Weak_ptr(decltype(nullptr)) : _p(nullptr) {}
284 // backwards 0 ctor
285 explicit Weak_ptr(int x) noexcept
286 L4_DEPRECATED("Use initialization from 'nullptr'")
287 : _p(nullptr)
288 { if (x != 0) __builtin_trap(); }
289
290 Weak_ptr(Rp const &o) noexcept : _p(o.ptr()) {}
291 explicit Weak_ptr(T *o) noexcept : _p(o) {}
292
293 template<typename OT>
294 Weak_ptr(Weak_ptr<OT, CNT> const &o) noexcept : _p(o.ptr()) {}
295
296 Weak_ptr(Weak_ptr<T, CNT> const &o) noexcept : _p(o._p) {}
297
298 Weak_ptr<T, CNT> &operator = (const Weak_ptr<T, CNT> &o) = default;
299
300 T *get() const noexcept { return _p; }
301 T *ptr() const noexcept { return _p; }
302
303 T *operator -> () const noexcept { return _p; }
304 operator Null_type const * () const noexcept
305 { return reinterpret_cast<Null_type const*>(_p); }
306
307private:
308 T *_p;
309};
310
311template<typename OT, typename T> inline
312Ref_ptr<OT> ref_ptr_static_cast(Ref_ptr<T> const &o)
313{ return ref_ptr(static_cast<OT*>(o.ptr())); }
314
315template< typename T >
316inline Ref_ptr<T> ref_ptr(T *t)
317{ return Ref_ptr<T>(t); }
318
319template< typename T >
320inline Weak_ptr<T> weak_ptr(T *t)
321{ return Weak_ptr<T>(t); }
322
323
324class Ref_obj
325{
326private:
327 mutable int _ref_cnt;
328
329public:
330 Ref_obj() : _ref_cnt(0) {}
331 void add_ref() const noexcept { ++_ref_cnt; }
332 int remove_ref() const noexcept { return --_ref_cnt; }
333};
334
335template< typename T, typename... Args >
336Ref_ptr<T>
337make_ref_obj(Args &&... args)
338{ return cxx::Ref_ptr<T>(new T(cxx::forward<Args>(args)...)); }
339
340template<typename T, typename U>
341Ref_ptr<T>
342dynamic_pointer_cast(Ref_ptr<U> const &p) noexcept
343{
344 // our constructor from a naked pointer increments the counter
345 return Ref_ptr<T>(dynamic_cast<T *>(p.get()));
346}
347
348template<typename T, typename U>
349Ref_ptr<T>
350static_pointer_cast(Ref_ptr<U> const &p) noexcept
351{
352 // our constructor from a naked pointer increments the counter
353 return Ref_ptr<T>(static_cast<T *>(p.get()));
354}
355
356}
A reference-counting pointer with automatic cleanup.
Definition ref_ptr:82
T * ptr() const noexcept)
Return a raw pointer to the object this shared pointer points to.
Definition ref_ptr:138
Ref_ptr(Wp const &o) noexcept
Create a shared pointer from a weak pointer.
Definition ref_ptr:99
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:103
T * get() const noexcept)
Return a raw pointer to the object this shared pointer points to.
Definition ref_ptr:132
T * release() noexcept
Release the shared pointer without removing the reference.
Definition ref_ptr:149
Ref_ptr(X *o) noexcept
Create a shared pointer from a raw pointer.
Definition ref_ptr:112
Ref_ptr(T *o, bool d) noexcept
Create a shared pointer from a raw pointer without creating a new reference.
Definition ref_ptr:125
L4 compiler related defines.
#define L4_DEPRECATED(s)
Mark symbol deprecated.
Definition compiler.h:301
Our C++ library.
Definition arith:22