Line data Source code
1 : /*
2 : * Distributed under the OpenDDS License.
3 : * See: http://www.opendds.org/license.html
4 : */
5 :
6 : #ifndef OPENDDS_DCPS_RCHANDLE_T_H
7 : #define OPENDDS_DCPS_RCHANDLE_T_H
8 :
9 : #include "dds/Versioned_Namespace.h"
10 : #include "Definitions.h"
11 : #include "unique_ptr.h"
12 :
13 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
14 :
15 : namespace OpenDDS {
16 : namespace DCPS {
17 :
18 : struct inc_count {};
19 : struct keep_count {};
20 :
21 : /// Templated Reference counted handle to a pointer.
22 : /// A non-DDS specific helper class.
23 : template <typename T>
24 : class RcHandle {
25 : public:
26 669 : RcHandle()
27 669 : : ptr_(0)
28 : {
29 669 : }
30 :
31 3282 : RcHandle(T* p, keep_count)
32 3282 : : ptr_(p)
33 : {
34 3282 : }
35 :
36 : template <typename U>
37 1 : RcHandle(unique_ptr<U> p)
38 1 : : ptr_(p.release())
39 : {
40 1 : }
41 :
42 2114 : RcHandle(T* p, inc_count)
43 2114 : : ptr_(p)
44 : {
45 2114 : this->bump_up();
46 2114 : }
47 :
48 : template <typename U>
49 2247 : RcHandle(const RcHandle<U>& other)
50 2247 : : ptr_(other.in())
51 : {
52 2247 : this->bump_up();
53 2247 : }
54 :
55 2293 : RcHandle(const RcHandle& b)
56 2293 : : ptr_(b.ptr_)
57 : {
58 2293 : this->bump_up();
59 2293 : }
60 :
61 10606 : ~RcHandle()
62 : {
63 10606 : this->bump_down();
64 10606 : }
65 :
66 32 : void reset()
67 : {
68 32 : RcHandle tmp;
69 32 : swap(tmp);
70 32 : }
71 :
72 : template <typename U>
73 3 : void reset(T* p, U counting_strategy)
74 : {
75 3 : RcHandle tmp(p, counting_strategy);
76 3 : swap(tmp);
77 3 : }
78 :
79 228 : RcHandle& operator=(const RcHandle& b)
80 : {
81 228 : RcHandle tmp(b);
82 228 : swap(tmp);
83 228 : return *this;
84 228 : }
85 :
86 : template <class U>
87 19 : RcHandle& operator=(const RcHandle<U>& b)
88 : {
89 19 : RcHandle<T> tmp(b);
90 19 : swap(tmp);
91 19 : return *this;
92 19 : }
93 :
94 : template <typename U>
95 1 : RcHandle& operator=(unique_ptr<U> b)
96 : {
97 1 : RcHandle<T> tmp(b.release(), keep_count());
98 1 : swap(tmp);
99 2 : return *this;
100 1 : }
101 :
102 328 : void swap(RcHandle& rhs)
103 : {
104 328 : T* t = this->ptr_;
105 328 : this->ptr_ = rhs.ptr_;
106 328 : rhs.ptr_ = t;
107 328 : }
108 :
109 10391 : T* operator->() const
110 : {
111 10391 : OPENDDS_ASSERT(ptr_);
112 10391 : return this->ptr_;
113 : }
114 :
115 2247 : T& operator*() const
116 : {
117 2247 : OPENDDS_ASSERT(ptr_);
118 2247 : return *this->ptr_;
119 : }
120 :
121 23 : bool is_nil() const
122 : {
123 23 : return this->ptr_ == 0;
124 : }
125 :
126 7563 : T* in() const
127 : {
128 7563 : return this->ptr_;
129 : }
130 :
131 23 : T* get() const
132 : {
133 23 : return this->ptr_;
134 : }
135 :
136 1 : T*& inout()
137 : {
138 1 : return this->ptr_;
139 : }
140 :
141 1 : T*& out()
142 : {
143 1 : this->bump_down();
144 1 : return this->ptr_;
145 : }
146 :
147 1 : T* _retn()
148 : {
149 1 : T* retval = this->ptr_;
150 1 : this->ptr_ = 0;
151 1 : return retval;
152 : }
153 :
154 4637 : operator bool() const
155 : {
156 4637 : return in() != 0;
157 : }
158 :
159 6 : bool operator==(const RcHandle& rhs) const
160 : {
161 6 : return in() == rhs.in();
162 : }
163 :
164 1 : bool operator!=(const RcHandle& rhs) const
165 : {
166 1 : return in() != rhs.in();
167 : }
168 :
169 1 : bool operator < (const RcHandle& rhs) const
170 : {
171 1 : return in() < rhs.in();
172 : }
173 :
174 : private:
175 6654 : void bump_up()
176 : {
177 6654 : if (ptr_ != 0) {
178 6651 : ptr_->_add_ref();
179 : }
180 6654 : }
181 :
182 10607 : void bump_down()
183 : {
184 10607 : if (ptr_ != 0) {
185 9934 : ptr_->_remove_ref();
186 9934 : ptr_ = 0;
187 : }
188 10607 : }
189 :
190 : /// The actual "unsmart" pointer to the T object.
191 : T* ptr_;
192 : };
193 :
194 :
195 : template <typename T>
196 1 : void swap(RcHandle<T>& lhs, RcHandle<T>& rhs)
197 : {
198 1 : lhs.swap(rhs);
199 1 : }
200 :
201 : template <typename T, typename U>
202 17 : RcHandle<T> static_rchandle_cast(const RcHandle<U>& h)
203 : {
204 17 : return RcHandle<T>(static_cast<T*>(h.in()), inc_count());
205 : }
206 :
207 : template <typename T, typename U>
208 1 : RcHandle<T> const_rchandle_cast(const RcHandle<U>& h)
209 : {
210 1 : return RcHandle<T>(const_cast<T*>(h.in()), inc_count());
211 : }
212 :
213 : template <typename T, typename U>
214 1 : RcHandle<T> dynamic_rchandle_cast(const RcHandle<U>& h)
215 : {
216 1 : return RcHandle<T>(dynamic_cast<T*>(h.in()), inc_count());
217 : }
218 :
219 :
220 : template< class T >
221 : class reference_wrapper{
222 : public:
223 : // types
224 : typedef T type;
225 :
226 : // construct/copy/destroy
227 5 : reference_wrapper(T& ref): _ptr(&ref) {}
228 : // access
229 : operator T& () const { return *_ptr; }
230 5 : T& get() const { return *_ptr; }
231 :
232 : private:
233 : T* _ptr;
234 : };
235 :
236 : template <typename T>
237 5 : reference_wrapper<T> ref(T& r)
238 : {
239 5 : return reference_wrapper<T>(r);
240 : }
241 :
242 : template <typename T>
243 3261 : T const& unwrap_reference(T const& t)
244 : {
245 3261 : return t;
246 : }
247 :
248 : template <typename T>
249 5 : T& unwrap_reference(reference_wrapper<T> const& t)
250 : {
251 5 : return t.get();
252 : }
253 :
254 :
255 : template <typename T>
256 315 : RcHandle<T> make_rch()
257 : {
258 315 : return RcHandle<T>(new T(), keep_count());
259 : }
260 :
261 : template <typename T, typename U>
262 168 : RcHandle<T> make_rch(U const& u)
263 : {
264 168 : return RcHandle<T>(new T(unwrap_reference(u)), keep_count());
265 : }
266 :
267 : template <typename T, typename U0, typename U1>
268 28 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1)
269 : {
270 28 : return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1)), keep_count());
271 : }
272 :
273 : template <typename T, typename U0, typename U1, typename U2>
274 14 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2)
275 : {
276 14 : return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2)), keep_count());
277 : }
278 :
279 : template <typename T, typename U0, typename U1, typename U2, typename U3>
280 0 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3)
281 : {
282 0 : return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3)), keep_count());
283 : }
284 :
285 : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4>
286 600 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4)
287 : {
288 600 : return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4)), keep_count());
289 : }
290 :
291 : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5>
292 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4, U5 const& u5)
293 : {
294 : return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4), unwrap_reference(u5)), keep_count());
295 : }
296 :
297 : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6>
298 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4, U5 const& u5, U6 const& u6)
299 : {
300 : return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4), unwrap_reference(u5), unwrap_reference(u6)), keep_count());
301 : }
302 :
303 : template <typename T, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6, typename U7>
304 0 : RcHandle<T> make_rch(U0 const& u0, U1 const& u1, U2 const& u2, U3 const& u3, U4 const& u4, U5 const& u5, U6 const& u6, U7 const& u7)
305 : {
306 0 : return RcHandle<T>(new T(unwrap_reference(u0), unwrap_reference(u1), unwrap_reference(u2), unwrap_reference(u3), unwrap_reference(u4), unwrap_reference(u5), unwrap_reference(u6), unwrap_reference(u7)), keep_count());
307 : }
308 :
309 : template<typename T>
310 2092 : RcHandle<T> rchandle_from(T* pointer)
311 : {
312 2092 : OPENDDS_ASSERT(pointer == 0 || pointer->ref_count() > 0);
313 2092 : return RcHandle<T>(pointer, inc_count());
314 : }
315 :
316 :
317 : } // namespace DCPS
318 : } // namespace OpenDDS
319 :
320 : OPENDDS_END_VERSIONED_NAMESPACE_DECL
321 :
322 : #endif /* OPENDDS_RCHANDLE_T_H */
|