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) : _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
256private:
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
273template<typename T, template< typename X > class CNT>
274class Weak_ptr
275{
276private:
277 struct Null_type;
278 typedef Ref_ptr<T, CNT> Rp;
279
280public:
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
306private:
307 T *_p;
308};
309
310template<typename OT, typename T> inline
311Ref_ptr<OT> ref_ptr_static_cast(Ref_ptr<T> const &o)
312{ return ref_ptr(static_cast<OT*>(o.ptr())); }
313
314template< typename T >
315inline Ref_ptr<T> ref_ptr(T *t)
316{ return Ref_ptr<T>(t); }
317
318template< typename T >
319inline Weak_ptr<T> weak_ptr(T *t)
320{ return Weak_ptr<T>(t); }
321
322
323class Ref_obj
324{
325private:
326 mutable int _ref_cnt;
327
328public:
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
334template< typename T, typename... Args >
335Ref_ptr<T>
336make_ref_obj(Args &&... args)
337{ return cxx::Ref_ptr<T>(new T(cxx::forward<Args>(args)...)); }
338
339template<typename T, typename U>
340Ref_ptr<T>
341dynamic_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
347template<typename T, typename U>
348Ref_ptr<T>
349static_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:290
Our C++ library.
Definition arith:22