Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_smartptr.h
Go to the documentation of this file.
1// -*- C++ -*-
2
30#ifndef _RWSTD_SMARTPTR_INCLUDED
31#define _RWSTD_SMARTPTR_INCLUDED
32
33
34#include <rw/_autoptr.h>
35#include <rw/_exception.h>
36#include <rw/_mutex.h>
37#include <rw/_defs.h>
38
39
41
42
43struct __rw_ptr_base
44{
45 __rw_ptr_base ()
46 : _C_ref (1), _C_weak_ref (0) { }
47
48 virtual ~__rw_ptr_base () {
49#ifdef _RWSTDDEBUG
50 _C_ref = 0xdeadbeefL;
51 _C_weak_ref = 0xdeadbeefL;
52#endif // _RWSTDDEBUG
53 }
54
55 virtual void* _C_get_deleter () const {
56 return 0;
57 }
58
59 long _C_get_ref () {
60 _RWSTD_ATOMIC_PREINCREMENT (_C_ref, false);
61 return _RWSTD_ATOMIC_PREDECREMENT (_C_ref, false);
62 }
63
64 void _C_inc_ref () {
65 _RWSTD_ATOMIC_PREINCREMENT (_C_ref, false);
66 }
67
68 void _C_inc_ref_weak () {
69 _RWSTD_ATOMIC_PREINCREMENT (_C_weak_ref, false);
70 }
71
72 void _C_unref () {
73 const long __ref = _RWSTD_ATOMIC_PREDECREMENT (_C_ref, false);
74 if (0 == __ref)
75 _C_delete ();
76
77 if (__ref <= 0) {
78 if (0 > _RWSTD_ATOMIC_PREDECREMENT (_C_weak_ref, false))
79 delete this;
80 else
81 _RWSTD_ATOMIC_PREINCREMENT (_C_weak_ref, false);
82 }
83 }
84
85 void _C_unref_weak () {
86 if (0 >= _RWSTD_ATOMIC_PREDECREMENT (_C_weak_ref, false)) {
87 if (0 > _RWSTD_ATOMIC_PREDECREMENT (_C_ref, false))
88 delete this;
89 else
90 _RWSTD_ATOMIC_PREINCREMENT (_C_ref, false);
91 }
92 }
93
94private:
95
96 virtual void _C_delete () = 0;
97
98 long _C_ref;
99 long _C_weak_ref;
100};
101
102
103template <class _TypeU>
104struct __rw_ptr_body: __rw_ptr_base
105{
106 __rw_ptr_body (_TypeU *__ptr)
107 : __rw_ptr_base (), _C_ptr (__ptr) { }
108
109protected:
110
111 _TypeU* const _C_ptr;
112
113private:
114
115 virtual void _C_delete () {
116 delete _C_ptr;
117 }
118};
119
120
121template <class _TypeU, class _Deleter>
122struct __rw_ptr_deleter: __rw_ptr_body<_TypeU>
123{
124 __rw_ptr_deleter (_TypeU *__ptr, const _Deleter &__del)
125 : __rw_ptr_body<_TypeU>(__ptr), _C_del (__del) { }
126
127private:
128
129 virtual void _C_delete () {
130 _C_del (this->_C_ptr);
131 }
132
133 virtual void* _C_get_deleter () const {
134 return _RWSTD_CONST_CAST (_Deleter*, &_C_del);
135 }
136
137 _Deleter _C_del;
138};
139
140
141} // namespace __rw
142
143
145
146
147// [util.smartptr.weakptr] - class bad_weak_ptr
148struct bad_weak_ptr: _RW::__rw_exception
149{
150 bad_weak_ptr (): _RW::__rw_exception () { }
151};
152
153
154template <class _TypeT>
155class weak_ptr;
156
157
158// [util.smartptr.shared] - class template shared_ptr
159template <class _TypeT>
160class shared_ptr
161{
162 // declare every specialization a friend and grant
163 // template members access to _C_ptr
164 template <class _TypeU>
165 friend class shared_ptr;
166
167 template <class _TypeU>
168 friend class weak_ptr;
169
170 template <class _TypeU, class _TypeV>
171 friend shared_ptr<_TypeU>
172 dynamic_pointer_cast (const shared_ptr<_TypeV>&);
173
174 typedef _RW::__rw_ptr_base _C_base;
175
176 _C_base *_C_pbody;
177 _TypeT *_C_ptr;
178
179 template <class _TypeU>
180 explicit
181 shared_ptr (const shared_ptr<_TypeU> &__rhs, const _TypeT*)
182 : _C_pbody (__rhs._C_pbody) {
183 if (_C_pbody)
184 _C_pbody->_C_inc_ref ();
185 }
186
187public:
188
189 typedef _TypeT element_type;
190
191 // [util.smartptr.shared.const] constructors
192
193 shared_ptr (): _C_pbody (0), _C_ptr (0) { }
194
195 template <class _TypeU>
196 explicit
197 shared_ptr (_TypeU *__ptr)
198 : _C_pbody (__ptr ? new _RW::__rw_ptr_body<_TypeU>(__ptr) : 0),
199 _C_ptr (__ptr) { /* empty */ }
200
201 template <class _TypeU, class _Deleter>
202 shared_ptr (_TypeU *__ptr, _Deleter __del)
203 : _C_pbody (new _RW::__rw_ptr_deleter<_TypeU, _Deleter>(__ptr, __del)),
204 _C_ptr (__ptr) { /* empty */ }
205
206 shared_ptr (const shared_ptr &__rhs)
207 : _C_pbody (__rhs._C_pbody), _C_ptr (__rhs._C_ptr) {
208 if (_C_pbody)
209 _C_pbody->_C_inc_ref ();
210 }
211
212 template <class _TypeU>
213 shared_ptr (const shared_ptr<_TypeU> &__rhs)
214 : _C_pbody (__rhs._C_pbody), _C_ptr (__rhs._C_ptr) {
215 if (_C_pbody)
216 _C_pbody->_C_inc_ref ();
217 }
218
219 template <class _TypeU>
220 explicit
221 shared_ptr (const weak_ptr<_TypeU> &__rhs)
222 : _C_pbody (__rhs._C_pbody), _C_ptr (__rhs._C_ptr) {
223 if (_C_pbody) {
224 if (0 >= _C_pbody->_C_get_ref ())
225 throw bad_weak_ptr ();
226 _C_pbody->_C_inc_ref ();
227 }
228 }
229
230 template <class _TypeU>
231 explicit
232 shared_ptr (auto_ptr<_TypeU>&);
233
234 // [util.smartptr.shared.dest] destructor
235 ~shared_ptr () {
236 if (_C_pbody)
237 _C_pbody->_C_unref ();
238
239#ifdef _RWSTDDEBUG
240 _C_pbody = (_C_base*)0xdeadbeefL;
241 _C_ptr = (element_type*)0xdeadbeefL;
242#endif // _RWSTDDEBUG
243 }
244
245 // [util.smartptr.shared.assign] assignment
246
247 shared_ptr& operator= (const shared_ptr &__rhs) {
248 if (__rhs._C_pbody)
249 __rhs._C_pbody->_C_inc_ref ();
250 if (_C_pbody)
251 _C_pbody->_C_unref ();
252 _C_pbody = __rhs._C_pbody;
253 _C_ptr = __rhs._C_ptr;
254 return *this;
255 }
256
257 template <class _TypeU>
258 shared_ptr& operator= (const shared_ptr<_TypeU> &__rhs) {
259 _C_is_convertible ((_TypeU*)0);
260 if (__rhs._C_pbody)
261 __rhs._C_pbody->_C_inc_ref ();
262 if (_C_pbody)
263 _C_pbody->_C_unref ();
264 _C_pbody = __rhs._C_pbody;
265 _C_ptr = __rhs._C_ptr;
266 return *this;
267 }
268
269 template <class _TypeU>
270 shared_ptr& operator= (auto_ptr<_TypeU> &__rhs) {
271 _RW::__rw_ptr_body<_TypeU>* const __tmp =
272 new _RW::__rw_ptr_body<_TypeU>(__rhs.get ());
273 if (_C_pbody)
274 _C_pbody->_C_unref ();
275 _C_pbody = __tmp;
276 _C_ptr = __rhs.release ();
277 return *this;
278 }
279
280 // [util.smartptr.shared.mod] modifiers
281
282 void swap (shared_ptr &__other) {
283 _C_base* const __body = _C_pbody;
284 element_type* const __ptr = _C_ptr;
285 _C_pbody = __other._C_pbody;
286 _C_ptr = __other._C_ptr;
287 __other._C_pbody = __body;
288 __other._C_ptr = __ptr;
289 }
290
291 void reset () {
292 if (_C_pbody) {
293 _C_pbody->_C_unref ();
294 _C_pbody = 0;
295 _C_ptr = 0;
296 }
297 }
298
299 template <class _TypeU>
300 void reset (_TypeU *__ptr) {
301 shared_ptr<_TypeU>(__ptr).swap (*this);
302 }
303
304 template <class _TypeU, class _Deleter>
305 void reset (_TypeU *__ptr, _Deleter __del) {
306 shared_ptr<_TypeU>(__ptr, __del).swap (*this);
307 }
308
309 // [util.smartptr.shared.obs] observers
310
311 element_type* get () const {
312 return _C_ptr;
313 }
314
315 typename _RW::__rw_nonvoid_ref<element_type>::_C_ref
316 operator*() const {
317 _RWSTD_ASSERT (0 != get ());
318 return *get ();
319 }
320
321 element_type* operator->() const {
322 return &**this;
323 }
324
325 long use_count () const {
326 return _C_pbody ? _C_pbody->_C_get_ref () : 0;
327 }
328
329 bool unique () const {
330 return 1 == use_count ();
331 }
332
333 operator bool () const {
334 return 0 != get ();
335 }
336
337 template <class _Deleter>
338 _Deleter* _C_get_deleter () const {
339 return _RWSTD_STATIC_CAST (_Deleter*,
340 _C_pbody ? _C_pbody->_C_get_deleter () : 0);
341 }
342
343 template <class _TypeU>
344 bool _C_less (const shared_ptr<_TypeU> &__rhs) const {
345 return _C_pbody < __rhs._C_pbody;
346 }
347
348private:
349
350 // helper to check whether one pointer is convertible to another
351 // and to enforce the convertibility requirements
352 static void _C_is_convertible (element_type*) { }
353};
354
355
356// [util.smartptr.shared.cmp] - shared_ptr comparisons
357template <class _TypeT, class _TypeU>
358inline bool
359operator== (const shared_ptr<_TypeT> &__lhs, const shared_ptr<_TypeU> &__rhs)
360{
361 return __lhs.get () == __rhs.get ();
362}
363
364
365template <class _TypeT, class _TypeU>
366inline bool
367operator!= (const shared_ptr<_TypeT> &__lhs, const shared_ptr<_TypeU> &__rhs)
368{
369 return __lhs.get () != __rhs.get ();
370}
371
372
373template <class _TypeT, class _TypeU>
374inline bool
375operator< (const shared_ptr<_TypeT> &__lhs, const shared_ptr<_TypeU> &__rhs)
376{
377 return __lhs._C_less (__rhs);
378}
379
380
381// [util.smartptr.shared.spec] - shared_ptr specialized algorithms
382template <class _TypeT>
383inline void
384swap (shared_ptr<_TypeT> &__lhs, shared_ptr<_TypeT> &__rhs)
385{
386 __lhs.swap (__rhs);
387}
388
389
390// [util.smartptr.shared.cast] - shared_ptr casts
391template <class _TypeT, class _TypeU>
393static_pointer_cast (const shared_ptr<_TypeU> &__src)
394{
395 _TypeT* const __ptr = _RWSTD_STATIC_CAST (_TypeT*, __src.get ());
396 if (__ptr)
397 return shared_ptr<_TypeT>(__src, __ptr);
398
399 return shared_ptr<_TypeT>();
400}
401
402
403template <class _TypeT, class _TypeU>
405dynamic_pointer_cast (const shared_ptr<_TypeU> &__src)
406{
407 _TypeT* const __ptr = _RWSTD_DYNAMIC_CAST (_TypeT*, __src.get ());
408 if (__ptr)
409 return shared_ptr<_TypeT>(__src, __ptr);
410
411 return shared_ptr<_TypeT>();
412}
413
414
415template <class _TypeT, class _TypeU>
417const_pointer_cast (const shared_ptr<_TypeU> &__src)
418{
419 _TypeT* const __ptr = _RWSTD_CONST_CAST (_TypeT*, __src.get ());
420 if (__ptr)
421 return shared_ptr<_TypeT>(__src, __ptr);
422
423 return shared_ptr<_TypeT>();
424}
425
426
427#if 0 // NOT IMPLEMENTED YET
428
429// [util.smartptr.shared.io] - shared_ptr I/O
430template <class _CharT, class _Traits, class _TypeT>
431inline basic_ostream<_CharT, _TypeT>&
432operator<< (basic_ostream<_CharT, _Traits>&, const shared_ptr<_TypeT>&);
433
434#endif // 0/1
435
436
437// [util.smartptr.shared.getdeleter] - shared_ptr get_deleter
438template <class _Deleter, class _TypeT>
439_Deleter*
440get_deleter (const shared_ptr<_TypeT> &__ptr)
441{
442 return __ptr._C_get_deleter ();
443}
444
445
446// [util.smartptr.weak] - class template weak_ptr
447template <class _TypeT>
448class weak_ptr
449{
450 // declare every specialization a friend and grant
451 // template members access to _C_pbody
452 template <class _TypeU>
453 friend class weak_ptr;
454
455 template <class _TypeU>
456 friend class shared_ptr;
457
458 typedef _RW::__rw_ptr_base _C_base;
459
460 _C_base *_C_pbody;
461 _TypeT *_C_ptr;
462
463public:
464
465 typedef _TypeT element_type;
466
467 // constructors
468 weak_ptr (): _C_pbody (0), _C_ptr (0) { }
469
470 template <class _TypeU>
471 weak_ptr (const shared_ptr<_TypeU> &__ptr)
472 : _C_pbody (__ptr._C_pbody), _C_ptr (__ptr._C_ptr) {
473 if (_C_pbody)
474 _C_pbody->_C_inc_ref_weak ();
475 }
476
477 weak_ptr (const weak_ptr &__rhs)
478 : _C_pbody (__rhs._C_pbody), _C_ptr (__rhs._C_ptr) {
479 if (_C_pbody)
480 _C_pbody->_C_inc_ref_weak ();
481 }
482
483 template <class _TypeU>
484 weak_ptr (const weak_ptr<_TypeU> &__rhs)
485 : _C_pbody (__rhs._C_pbody), _C_ptr (__rhs._C_ptr) {
486 if (_C_pbody)
487 _C_pbody->_C_inc_ref_weak ();
488 }
489
490 // destructor
491 ~weak_ptr () {
492 if (_C_pbody)
493 _C_pbody->_C_unref_weak ();
494
495#ifdef _RWSTDDEBUG
496 _C_pbody = (_C_base*)0xdeadbeefL;
497 _C_ptr = (element_type*)0xdeadbeefL;
498#endif // _RWSTDDEBUG
499 }
500
501 // assignment
502 weak_ptr& operator= (const weak_ptr &__rhs) {
503 if (_C_pbody)
504 _C_pbody->_C_unref_weak ();
505 if ((_C_pbody = __rhs._C_pbody))
506 _C_pbody->_C_inc_ref_weak ();
507 _C_ptr = __rhs._C_ptr;
508 return *this;
509 }
510
511 template <class _TypeU>
512 weak_ptr& operator= (const weak_ptr<_TypeU> &__rhs) {
513 _C_is_convertible ((_TypeU*)0);
514 if (_C_pbody)
515 _C_pbody->_C_unref_weak ();
516 if ((_C_pbody = __rhs._C_pbody))
517 _C_pbody->_C_inc_ref_weak ();
518 _C_ptr = __rhs._C_ptr;
519 return *this;
520 }
521
522 template<class _TypeU>
523 weak_ptr& operator=(const shared_ptr<_TypeU> &__rhs) {
524 _C_is_convertible ((_TypeU*)0);
525 if (_C_pbody)
526 _C_pbody->_C_unref_weak ();
527 if ((_C_pbody = __rhs._C_pbody))
528 _C_pbody->_C_inc_ref_weak ();
529 _C_ptr = __rhs._C_ptr;
530 return *this;
531 }
532
533 // modifiers
534
535 void swap (weak_ptr &__other) {
536 _C_base* const __body = _C_pbody;
537 element_type* const __ptr = _C_ptr;
538 _C_pbody = __other._C_pbody;
539 _C_ptr = __other._C_ptr;
540 __other._C_pbody = __body;
541 __other._C_ptr = __ptr;
542 }
543
544 void reset () {
545 if (_C_pbody) {
546 _C_pbody->_C_unref_weak ();
547 _C_pbody = 0;
548 _C_ptr = 0;
549 }
550 }
551
552 // observers
553 long use_count () const {
554 return _C_pbody ? _C_pbody->_C_get_ref () : 0;
555 }
556
557 bool expired () const {
558 return 0 == use_count ();
559 }
560
562 lock () const {
563 return expired () ? shared_ptr<element_type>()
565 }
566
567 // implements 20.6.12.3.6 - non-member template operator<
568 template <class _TypeU>
569 bool operator< (const weak_ptr<_TypeU> __rhs) const {
570 return _C_pbody < __rhs._C_pbody;
571 }
572
573private:
574
575 // helper to check whether one pointer is convertible to another
576 // and to enforce the convertibility requirements
577 static void _C_is_convertible (element_type*) { }
578};
579
580
581// [util.smartptr.weak.cmp] - weak_ptr comparison
582template <class _TypeT, class _TypeU>
583inline bool
584operator< (const weak_ptr<_TypeT> &__lhs, const weak_ptr<_TypeU> &__rhs)
585{
586 return __lhs.operator< (__rhs);
587}
588
589
590// [util.smartptr.weak.spec] - weak_ptr specialized algorithms
591template <class _TypeT>
592inline void
593swap (weak_ptr<_TypeT> &__lhs, weak_ptr<_TypeT> &__rhs)
594{
595 __lhs.swap (__rhs);
596}
597
598
599// [util.smartptr.enab] - class enable_shared_from_this
600template <class _TypeT>
601class enable_shared_from_this;
602
603
604} // namespace std
605
606
607#endif // _RWSTD_SMARTPTR_INCLUDED
const plus_asgn< T > & operator*(const plus_asgn< T > &lhs, const plus_asgn< T > &rhs)
#define _RWSTD_ATOMIC_PREINCREMENT(x, ignore)
Definition _defs.h:699
#define _RWSTD_DYNAMIC_CAST(T, x)
Definition _defs.h:544
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_ATOMIC_PREDECREMENT(x, ignore)
Definition _defs.h:700
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
std::basic_ostream< Char > & operator<<(std::basic_ostream< Char > &lhs, node_type rhs)
Pretty-prints the value of a node_type to a stream.
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14737
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14762
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14787
Definition json.h:5363
#define bool
Definition stdbool.h:24