]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/cxx/lib/tl/include/ref_ptr
update
[l4.git] / l4 / pkg / cxx / lib / tl / include / ref_ptr
1 // vim:ft=cpp
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 namespace cxx {
23
24 template< typename T >
25 struct Default_ref_counter
26 {
27   void h_drop_ref(T *p) throw()
28   {
29     if (p->remove_ref() == 0)
30       delete p;
31   }
32
33   void h_take_ref(T *p) throw()
34   {
35     p->add_ref();
36   }
37 };
38
39 struct Ref_ptr_base
40 {
41   enum Default_value
42   { Nil = 0 };
43 };
44
45 template<typename T, template< typename X > class CNT = Default_ref_counter>
46 class Weak_ptr;
47
48 template <
49   typename T = void,
50   template< typename X > class CNT = Default_ref_counter
51 >
52 class Ref_ptr : public Ref_ptr_base, private CNT<T>
53 {
54 private:
55   struct Null_type;
56   typedef Weak_ptr<T, CNT> Wp;
57
58 public:
59   Ref_ptr() throw() : _p(0) {}
60
61   Ref_ptr(Ref_ptr_base::Default_value v) : _p((T*)v) {}
62
63   Ref_ptr(Wp const &o) throw() : _p(o.ptr())
64   { __take_ref(); }
65
66   explicit Ref_ptr(T *o) throw() : _p(o)
67   { __take_ref(); }
68
69   /** The couterpart to release (does not create a new reference).
70    */
71   Ref_ptr(T *o, bool) throw() : _p(o) {}
72
73   T *get() const throw()
74   {
75     return _p;
76   }
77
78   T *ptr() const throw()
79   {
80     return _p;
81   }
82
83   T *release() throw()
84   {
85     T *p = _p;
86     _p = 0;
87     return p;
88   }
89
90   ~Ref_ptr() throw()
91   { __drop_ref(); }
92
93   template<typename OT>
94   Ref_ptr(Ref_ptr<OT, CNT> const &o) throw()
95   {
96     _p = o.ptr();
97     __take_ref();
98   }
99
100   Ref_ptr(Ref_ptr<T> const &o) throw()
101   {
102     _p = o._p;
103     __take_ref();
104   }
105
106   template< typename OT >
107   void operator = (Ref_ptr<OT> const &o) throw()
108   {
109     __drop_ref();
110     _p = o.ptr();
111     __take_ref();
112   }
113
114   void operator = (Ref_ptr<T> const &o) throw()
115   {
116     if (&o == this)
117       return;
118
119     __drop_ref();
120     _p = o._p;
121     __take_ref();
122   }
123
124   void operator = (T *o) throw()
125   {
126     __drop_ref();
127     _p = o;
128     __take_ref();
129   }
130
131   T *operator -> () const throw ()
132   { return _p; }
133
134   operator Null_type const * () const throw()
135   { return reinterpret_cast<Null_type const*>(_p); }
136
137 private:
138   void __drop_ref() throw()
139   {
140     if (_p)
141       this->h_drop_ref(_p);
142   }
143
144   void __take_ref() throw()
145   {
146     if (_p)
147       this->h_take_ref(_p);
148   }
149
150   T *_p;
151 };
152
153
154 template<typename T, template< typename X > class CNT>
155 class Weak_ptr
156 {
157 private:
158   struct Null_type;
159   typedef Ref_ptr<T, CNT> Rp;
160
161 public:
162   Weak_ptr() throw() {}
163   Weak_ptr(Rp const &o) throw() : _p(o.ptr()) {}
164   explicit Weak_ptr(T *o) throw() : _p(o) {}
165
166   T *get() const throw() { return _p; }
167   T *ptr() const throw() { return _p; }
168
169   T *operator -> () const throw () { return _p; }
170   operator Null_type const * () const throw()
171   { return reinterpret_cast<Null_type const*>(_p); }
172
173 private:
174   T *_p;
175 };
176
177 template<typename OT, typename T> inline
178 Ref_ptr<OT> ref_ptr_static_cast(Ref_ptr<T> const &o)
179 { return ref_ptr(static_cast<OT*>(o.ptr())); }
180
181 template< typename T >
182 inline Ref_ptr<T> ref_ptr(T *t)
183 { return Ref_ptr<T>(t); }
184
185 template< typename T >
186 inline Weak_ptr<T> weak_ptr(T *t)
187 { return Weak_ptr<T>(t); }
188
189
190 class Ref_obj
191 {
192 private:
193   mutable int _ref_cnt;
194
195 public:
196   Ref_obj() : _ref_cnt(0)  {}
197   void add_ref() const throw() { ++_ref_cnt; }
198   int remove_ref() const throw() { return --_ref_cnt; }
199 };
200
201 }