1 // <tr1/boost_shared_ptr.h> -*- C++ -*-
2
3 // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 // shared_count.hpp
31 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
32
33 // shared_ptr.hpp
34 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
35 // Copyright (C) 2001, 2002, 2003 Peter Dimov
36
37 // weak_ptr.hpp
38 // Copyright (C) 2001, 2002, 2003 Peter Dimov
39
40 // enable_shared_from_this.hpp
41 // Copyright (C) 2002 Peter Dimov
42
43 // Distributed under the Boost Software License, Version 1.0. (See
44 // accompanying file LICENSE_1_0.txt or copy at
45 // http://www.boost.org/LICENSE_1_0.txt)
46
47 // GCC Note: based on version 1.32.0 of the Boost library.
48
49 /** @file tr1/boost_shared_ptr.h
50 * This is an internal header file, included by other library headers.
51 * You should not attempt to use it directly.
52 */
53
54 #ifndef _BOOST_SHARED_PTR_H
55 #define _BOOST_SHARED_PTR_H 1
56
57 namespace std
58 {
_GLIBCXX_BEGIN_NAMESPACE(tr1)59 _GLIBCXX_BEGIN_NAMESPACE(tr1)
60
61 class bad_weak_ptr : public std::exception
62 {
63 public:
64 virtual char const*
65 what() const throw()
66 { return "tr1::bad_weak_ptr"; }
67 };
68
69 // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
70 inline void
__throw_bad_weak_ptr()71 __throw_bad_weak_ptr()
72 {
73 #if __EXCEPTIONS
74 throw bad_weak_ptr();
75 #else
76 std::abort();
77 #endif
78 }
79
80 using __gnu_cxx::_Lock_policy;
81 using __gnu_cxx::__default_lock_policy;
82 using __gnu_cxx::_S_single;
83 using __gnu_cxx::_S_mutex;
84 using __gnu_cxx::_S_atomic;
85
86 template<typename _Tp>
87 struct _Sp_deleter
88 {
89 typedef void result_type;
90 typedef _Tp* argument_type;
91
92 void
operator_Sp_deleter93 operator()(_Tp* __p) const
94 { delete __p; }
95 };
96
97 // Empty helper class except when the template argument is _S_mutex.
98 template<_Lock_policy _Lp>
99 class _Mutex_base
100 { };
101
102 template<>
103 class _Mutex_base<_S_mutex>
104 : public __gnu_cxx::__mutex
105 { };
106
107 template<_Lock_policy _Lp = __default_lock_policy>
108 class _Sp_counted_base
109 : public _Mutex_base<_Lp>
110 {
111 public:
_Sp_counted_base()112 _Sp_counted_base()
113 : _M_use_count(1), _M_weak_count(1) { }
114
115 virtual
~_Sp_counted_base()116 ~_Sp_counted_base() // nothrow
117 { }
118
119 // Called when _M_use_count drops to zero, to release the resources
120 // managed by *this.
121 virtual void
122 _M_dispose() = 0; // nothrow
123
124 // Called when _M_weak_count drops to zero.
125 virtual void
_M_destroy()126 _M_destroy() // nothrow
127 { delete this; }
128
129 virtual void*
130 _M_get_deleter(const std::type_info&) = 0;
131
132 void
_M_add_ref_copy()133 _M_add_ref_copy()
134 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
135
136 void
137 _M_add_ref_lock();
138
139 void
_M_release()140 _M_release() // nothrow
141 {
142 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count,
143 -1) == 1)
144 {
145 _M_dispose();
146 #ifdef __GTHREADS
147 _GLIBCXX_READ_MEM_BARRIER;
148 _GLIBCXX_WRITE_MEM_BARRIER;
149 #endif
150 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
151 -1) == 1)
152 _M_destroy();
153 }
154 }
155
156 void
_M_weak_add_ref()157 _M_weak_add_ref() // nothrow
158 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
159
160 void
_M_weak_release()161 _M_weak_release() // nothrow
162 {
163 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
164 {
165 #ifdef __GTHREADS
166 _GLIBCXX_READ_MEM_BARRIER;
167 _GLIBCXX_WRITE_MEM_BARRIER;
168 #endif
169 _M_destroy();
170 }
171 }
172
173 long
_M_get_use_count()174 _M_get_use_count() const // nothrow
175 { return _M_use_count; } // XXX is this MT safe?
176
177 private:
178 _Sp_counted_base(_Sp_counted_base const&);
179 _Sp_counted_base& operator=(_Sp_counted_base const&);
180
181 _Atomic_word _M_use_count; // #shared
182 _Atomic_word _M_weak_count; // #weak + (#shared != 0)
183 };
184
185 template<>
186 inline void
187 _Sp_counted_base<_S_single>::
_M_add_ref_lock()188 _M_add_ref_lock()
189 {
190 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
191 {
192 _M_use_count = 0;
193 __throw_bad_weak_ptr();
194 }
195 }
196
197 #ifdef __GTHREADS
198 template<>
199 inline void
200 _Sp_counted_base<_S_mutex>::
_M_add_ref_lock()201 _M_add_ref_lock()
202 {
203 __gnu_cxx::__scoped_lock sentry(*this);
204 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
205 {
206 _M_use_count = 0;
207 __throw_bad_weak_ptr();
208 }
209 }
210 #endif
211
212 template<>
213 inline void
214 _Sp_counted_base<_S_atomic>::
_M_add_ref_lock()215 _M_add_ref_lock()
216 {
217 // Perform lock-free add-if-not-zero operation.
218 _Atomic_word __count;
219 do
220 {
221 __count = _M_use_count;
222 if (__count == 0)
223 __throw_bad_weak_ptr();
224
225 // Replace the current counter value with the old value + 1, as
226 // long as it's not changed meanwhile.
227 }
228 while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
229 __count + 1));
230 }
231
232 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
233 class _Sp_counted_base_impl
234 : public _Sp_counted_base<_Lp>
235 {
236 public:
237 /**
238 * @brief
239 * @pre __d(__p) must not throw.
240 */
_Sp_counted_base_impl(_Ptr __p,_Deleter __d)241 _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
242 : _M_ptr(__p), _M_del(__d) { }
243
244 virtual void
_M_dispose()245 _M_dispose() // nothrow
246 { _M_del(_M_ptr); }
247
248 virtual void*
_M_get_deleter(const std::type_info & __ti)249 _M_get_deleter(const std::type_info& __ti)
250 { return __ti == typeid(_Deleter) ? &_M_del : 0; }
251
252 private:
253 _Sp_counted_base_impl(const _Sp_counted_base_impl&);
254 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
255
256 _Ptr _M_ptr; // copy constructor must not throw
257 _Deleter _M_del; // copy constructor must not throw
258 };
259
260 template<_Lock_policy _Lp = __default_lock_policy>
261 class __weak_count;
262
263 template<_Lock_policy _Lp = __default_lock_policy>
264 class __shared_count
265 {
266 public:
__shared_count()267 __shared_count()
268 : _M_pi(0) // nothrow
269 { }
270
271 template<typename _Ptr, typename _Deleter>
__shared_count(_Ptr __p,_Deleter __d)272 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
273 {
274 try
275 {
276 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
277 }
278 catch(...)
279 {
280 __d(__p); // Call _Deleter on __p.
281 __throw_exception_again;
282 }
283 }
284
285 // Special case for auto_ptr<_Tp> to provide the strong guarantee.
286 template<typename _Tp>
287 explicit
__shared_count(std::auto_ptr<_Tp> & __r)288 __shared_count(std::auto_ptr<_Tp>& __r)
289 : _M_pi(new _Sp_counted_base_impl<_Tp*,
290 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
291 { __r.release(); }
292
293 // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
294 explicit
295 __shared_count(const __weak_count<_Lp>& __r);
296
~__shared_count()297 ~__shared_count() // nothrow
298 {
299 if (_M_pi != 0)
300 _M_pi->_M_release();
301 }
302
__shared_count(const __shared_count & __r)303 __shared_count(const __shared_count& __r)
304 : _M_pi(__r._M_pi) // nothrow
305 {
306 if (_M_pi != 0)
307 _M_pi->_M_add_ref_copy();
308 }
309
310 __shared_count&
311 operator=(const __shared_count& __r) // nothrow
312 {
313 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
314 if (__tmp != _M_pi)
315 {
316 if (__tmp != 0)
317 __tmp->_M_add_ref_copy();
318 if (_M_pi != 0)
319 _M_pi->_M_release();
320 _M_pi = __tmp;
321 }
322 return *this;
323 }
324
325 void
_M_swap(__shared_count & __r)326 _M_swap(__shared_count& __r) // nothrow
327 {
328 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
329 __r._M_pi = _M_pi;
330 _M_pi = __tmp;
331 }
332
333 long
_M_get_use_count()334 _M_get_use_count() const // nothrow
335 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
336
337 bool
_M_unique()338 _M_unique() const // nothrow
339 { return this->_M_get_use_count() == 1; }
340
341 friend inline bool
342 operator==(const __shared_count& __a, const __shared_count& __b)
343 { return __a._M_pi == __b._M_pi; }
344
345 friend inline bool
346 operator<(const __shared_count& __a, const __shared_count& __b)
347 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
348
349 void*
_M_get_deleter(const std::type_info & __ti)350 _M_get_deleter(const std::type_info& __ti) const
351 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
352
353 private:
354 friend class __weak_count<_Lp>;
355
356 _Sp_counted_base<_Lp>* _M_pi;
357 };
358
359 template<_Lock_policy _Lp>
360 class __weak_count
361 {
362 public:
__weak_count()363 __weak_count()
364 : _M_pi(0) // nothrow
365 { }
366
__weak_count(const __shared_count<_Lp> & __r)367 __weak_count(const __shared_count<_Lp>& __r)
368 : _M_pi(__r._M_pi) // nothrow
369 {
370 if (_M_pi != 0)
371 _M_pi->_M_weak_add_ref();
372 }
373
__weak_count(const __weak_count<_Lp> & __r)374 __weak_count(const __weak_count<_Lp>& __r)
375 : _M_pi(__r._M_pi) // nothrow
376 {
377 if (_M_pi != 0)
378 _M_pi->_M_weak_add_ref();
379 }
380
~__weak_count()381 ~__weak_count() // nothrow
382 {
383 if (_M_pi != 0)
384 _M_pi->_M_weak_release();
385 }
386
387 __weak_count<_Lp>&
388 operator=(const __shared_count<_Lp>& __r) // nothrow
389 {
390 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
391 if (__tmp != 0)
392 __tmp->_M_weak_add_ref();
393 if (_M_pi != 0)
394 _M_pi->_M_weak_release();
395 _M_pi = __tmp;
396 return *this;
397 }
398
399 __weak_count<_Lp>&
400 operator=(const __weak_count<_Lp>& __r) // nothrow
401 {
402 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
403 if (__tmp != 0)
404 __tmp->_M_weak_add_ref();
405 if (_M_pi != 0)
406 _M_pi->_M_weak_release();
407 _M_pi = __tmp;
408 return *this;
409 }
410
411 void
_M_swap(__weak_count<_Lp> & __r)412 _M_swap(__weak_count<_Lp>& __r) // nothrow
413 {
414 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
415 __r._M_pi = _M_pi;
416 _M_pi = __tmp;
417 }
418
419 long
_M_get_use_count()420 _M_get_use_count() const // nothrow
421 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
422
423 friend inline bool
424 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
425 { return __a._M_pi == __b._M_pi; }
426
427 friend inline bool
428 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
429 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
430
431 private:
432 friend class __shared_count<_Lp>;
433
434 _Sp_counted_base<_Lp>* _M_pi;
435 };
436
437 template<_Lock_policy _Lp>
438 inline
439 __shared_count<_Lp>::
__shared_count(const __weak_count<_Lp> & __r)440 __shared_count(const __weak_count<_Lp>& __r)
441 : _M_pi(__r._M_pi)
442 {
443 if (_M_pi != 0)
444 _M_pi->_M_add_ref_lock();
445 else
446 __throw_bad_weak_ptr();
447 }
448
449
450 // Forward declarations.
451 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
452 class __shared_ptr;
453
454 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
455 class __weak_ptr;
456
457 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
458 class __enable_shared_from_this;
459
460 template<typename _Tp>
461 class shared_ptr;
462
463 template<typename _Tp>
464 class weak_ptr;
465
466 template<typename _Tp>
467 class enable_shared_from_this;
468
469 // Support for enable_shared_from_this.
470
471 // Friend of __enable_shared_from_this.
472 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
473 void
474 __enable_shared_from_this_helper(const __shared_count<_Lp>&,
475 const __enable_shared_from_this<_Tp1,
476 _Lp>*, const _Tp2*);
477
478 // Friend of enable_shared_from_this.
479 template<typename _Tp1, typename _Tp2>
480 void
481 __enable_shared_from_this_helper(const __shared_count<>&,
482 const enable_shared_from_this<_Tp1>*,
483 const _Tp2*);
484
485 template<_Lock_policy _Lp>
486 inline void
__enable_shared_from_this_helper(const __shared_count<_Lp> &,...)487 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
488 { }
489
490
491 struct __static_cast_tag { };
492 struct __const_cast_tag { };
493 struct __dynamic_cast_tag { };
494
495 /**
496 * @class shared_ptr <tr1/memory>
497 *
498 * A smart pointer with reference-counted copy semantics.
499 * The object pointed to is deleted when the last shared_ptr pointing to
500 * it is destroyed or reset.
501 */
502 template<typename _Tp, _Lock_policy _Lp>
503 class __shared_ptr
504 {
505 public:
506 typedef _Tp element_type;
507
508 /** @brief Construct an empty %__shared_ptr.
509 * @post use_count()==0 && get()==0
510 */
__shared_ptr()511 __shared_ptr()
512 : _M_ptr(0), _M_refcount() // never throws
513 { }
514
515 /** @brief Construct a %__shared_ptr that owns the pointer @a __p.
516 * @param __p A pointer that is convertible to element_type*.
517 * @post use_count() == 1 && get() == __p
518 * @throw std::bad_alloc, in which case @c delete @a __p is called.
519 */
520 template<typename _Tp1>
521 explicit
__shared_ptr(_Tp1 * __p)522 __shared_ptr(_Tp1* __p)
523 : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
524 {
525 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
526 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
527 __enable_shared_from_this_helper(_M_refcount, __p, __p);
528 }
529
530 //
531 // Requirements: _Deleter' copy constructor and destructor must not throw
532 //
533 // __shared_ptr will release __p by calling __d(__p)
534 //
535 /** @brief Construct a %__shared_ptr that owns the pointer @a __p
536 * and the deleter @a __d.
537 * @param __p A pointer.
538 * @param __d A deleter.
539 * @post use_count() == 1 && get() == __p
540 * @throw std::bad_alloc, in which case @a __d(__p) is called.
541 */
542 template<typename _Tp1, typename _Deleter>
__shared_ptr(_Tp1 * __p,_Deleter __d)543 __shared_ptr(_Tp1* __p, _Deleter __d)
544 : _M_ptr(__p), _M_refcount(__p, __d)
545 {
546 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
547 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
548 __enable_shared_from_this_helper(_M_refcount, __p, __p);
549 }
550
551 // generated copy constructor, assignment, destructor are fine.
552
553 /** @brief If @a __r is empty, constructs an empty %__shared_ptr;
554 * otherwise construct a %__shared_ptr that shares ownership
555 * with @a __r.
556 * @param __r A %__shared_ptr.
557 * @post get() == __r.get() && use_count() == __r.use_count()
558 * @throw std::bad_alloc, in which case
559 */
560 template<typename _Tp1>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r)561 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
562 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
563 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
564
565 /** @brief Constructs a %__shared_ptr that shares ownership with @a __r
566 * and stores a copy of the pointer stored in @a __r.
567 * @param __r A weak_ptr.
568 * @post use_count() == __r.use_count()
569 * @throw bad_weak_ptr when __r.expired(),
570 * in which case the constructor has no effect.
571 */
572 template<typename _Tp1>
573 explicit
__shared_ptr(const __weak_ptr<_Tp1,_Lp> & __r)574 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
575 : _M_refcount(__r._M_refcount) // may throw
576 {
577 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
578 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
579 // did not throw.
580 _M_ptr = __r._M_ptr;
581 }
582
583 /**
584 * @post use_count() == 1 and __r.get() == 0
585 */
586 template<typename _Tp1>
587 explicit
__shared_ptr(std::auto_ptr<_Tp1> & __r)588 __shared_ptr(std::auto_ptr<_Tp1>& __r)
589 : _M_ptr(__r.get()), _M_refcount()
590 {
591 // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
592 // delete __r.release() well-formed
593 _Tp1* __tmp = __r.get();
594 _M_refcount = __shared_count<_Lp>(__r);
595 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
596 }
597
598 template<typename _Tp1>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r,__static_cast_tag)599 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
600 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
601 _M_refcount(__r._M_refcount)
602 { }
603
604 template<typename _Tp1>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r,__const_cast_tag)605 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
606 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
607 _M_refcount(__r._M_refcount)
608 { }
609
610 template<typename _Tp1>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r,__dynamic_cast_tag)611 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
612 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
613 _M_refcount(__r._M_refcount)
614 {
615 if (_M_ptr == 0) // need to allocate new counter -- the cast failed
616 _M_refcount = __shared_count<_Lp>();
617 }
618
619 template<typename _Tp1>
620 __shared_ptr&
621 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
622 {
623 _M_ptr = __r._M_ptr;
624 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
625 return *this;
626 }
627
628 template<typename _Tp1>
629 __shared_ptr&
630 operator=(std::auto_ptr<_Tp1>& __r)
631 {
632 __shared_ptr(__r).swap(*this);
633 return *this;
634 }
635
636 void
reset()637 reset() // never throws
638 { __shared_ptr().swap(*this); }
639
640 template<typename _Tp1>
641 void
reset(_Tp1 * __p)642 reset(_Tp1* __p) // _Tp1 must be complete.
643 {
644 // Catch self-reset errors.
645 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
646 __shared_ptr(__p).swap(*this);
647 }
648
649 template<typename _Tp1, typename _Deleter>
650 void
reset(_Tp1 * __p,_Deleter __d)651 reset(_Tp1* __p, _Deleter __d)
652 { __shared_ptr(__p, __d).swap(*this); }
653
654 // Allow class instantiation when _Tp is [cv-qual] void.
655 typename add_reference<_Tp>::type
656 operator*() const // never throws
657 {
658 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
659 return *_M_ptr;
660 }
661
662 _Tp*
663 operator->() const // never throws
664 {
665 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
666 return _M_ptr;
667 }
668
669 _Tp*
get()670 get() const // never throws
671 { return _M_ptr; }
672
673 // Implicit conversion to "bool"
674 private:
675 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
676
677 public:
__unspecified_bool_type()678 operator __unspecified_bool_type() const // never throws
679 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
680
681 bool
unique()682 unique() const // never throws
683 { return _M_refcount._M_unique(); }
684
685 long
use_count()686 use_count() const // never throws
687 { return _M_refcount._M_get_use_count(); }
688
689 void
swap(__shared_ptr<_Tp,_Lp> & __other)690 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
691 {
692 std::swap(_M_ptr, __other._M_ptr);
693 _M_refcount._M_swap(__other._M_refcount);
694 }
695
696 private:
697 void*
_M_get_deleter(const std::type_info & __ti)698 _M_get_deleter(const std::type_info& __ti) const
699 { return _M_refcount._M_get_deleter(__ti); }
700
701 template<typename _Tp1, _Lock_policy _Lp1>
702 bool
_M_less(const __shared_ptr<_Tp1,_Lp1> & __rhs)703 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
704 { return _M_refcount < __rhs._M_refcount; }
705
706 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
707 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
708
709 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
710 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
711
712 // Friends injected into enclosing namespace and found by ADL:
713 template<typename _Tp1>
714 friend inline bool
715 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
716 { return __a.get() == __b.get(); }
717
718 template<typename _Tp1>
719 friend inline bool
720 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
721 { return __a.get() != __b.get(); }
722
723 template<typename _Tp1>
724 friend inline bool
725 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
726 { return __a._M_less(__b); }
727
728 _Tp* _M_ptr; // Contained pointer.
729 __shared_count<_Lp> _M_refcount; // Reference counter.
730 };
731
732 // 2.2.3.8 shared_ptr specialized algorithms.
733 template<typename _Tp, _Lock_policy _Lp>
734 inline void
swap(__shared_ptr<_Tp,_Lp> & __a,__shared_ptr<_Tp,_Lp> & __b)735 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
736 { __a.swap(__b); }
737
738 // 2.2.3.9 shared_ptr casts
739 /** @warning The seemingly equivalent
740 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
741 * will eventually result in undefined behaviour,
742 * attempting to delete the same object twice.
743 */
744 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
745 __shared_ptr<_Tp, _Lp>
static_pointer_cast(const __shared_ptr<_Tp1,_Lp> & __r)746 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
747 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
748
749 /** @warning The seemingly equivalent
750 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
751 * will eventually result in undefined behaviour,
752 * attempting to delete the same object twice.
753 */
754 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
755 __shared_ptr<_Tp, _Lp>
const_pointer_cast(const __shared_ptr<_Tp1,_Lp> & __r)756 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
757 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
758
759 /** @warning The seemingly equivalent
760 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
761 * will eventually result in undefined behaviour,
762 * attempting to delete the same object twice.
763 */
764 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
765 __shared_ptr<_Tp, _Lp>
dynamic_pointer_cast(const __shared_ptr<_Tp1,_Lp> & __r)766 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
767 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
768
769 // 2.2.3.7 shared_ptr I/O
770 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
771 std::basic_ostream<_Ch, _Tr>&
772 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
773 const __shared_ptr<_Tp, _Lp>& __p)
774 {
775 __os << __p.get();
776 return __os;
777 }
778
779 // 2.2.3.10 shared_ptr get_deleter (experimental)
780 template<typename _Del, typename _Tp, _Lock_policy _Lp>
781 inline _Del*
get_deleter(const __shared_ptr<_Tp,_Lp> & __p)782 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
783 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
784
785
786 template<typename _Tp, _Lock_policy _Lp>
787 class __weak_ptr
788 {
789 public:
790 typedef _Tp element_type;
791
__weak_ptr()792 __weak_ptr()
793 : _M_ptr(0), _M_refcount() // never throws
794 { }
795
796 // Generated copy constructor, assignment, destructor are fine.
797
798 // The "obvious" converting constructor implementation:
799 //
800 // template<typename _Tp1>
801 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
802 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
803 // { }
804 //
805 // has a serious problem.
806 //
807 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
808 // conversion may require access to *__r._M_ptr (virtual inheritance).
809 //
810 // It is not possible to avoid spurious access violations since
811 // in multithreaded programs __r._M_ptr may be invalidated at any point.
812 template<typename _Tp1>
__weak_ptr(const __weak_ptr<_Tp1,_Lp> & __r)813 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
814 : _M_refcount(__r._M_refcount) // never throws
815 {
816 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
817 _M_ptr = __r.lock().get();
818 }
819
820 template<typename _Tp1>
__weak_ptr(const __shared_ptr<_Tp1,_Lp> & __r)821 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
822 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
823 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
824
825 template<typename _Tp1>
826 __weak_ptr&
827 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
828 {
829 _M_ptr = __r.lock().get();
830 _M_refcount = __r._M_refcount;
831 return *this;
832 }
833
834 template<typename _Tp1>
835 __weak_ptr&
836 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
837 {
838 _M_ptr = __r._M_ptr;
839 _M_refcount = __r._M_refcount;
840 return *this;
841 }
842
843 __shared_ptr<_Tp, _Lp>
lock()844 lock() const // never throws
845 {
846 #ifdef __GTHREADS
847 // Optimization: avoid throw overhead.
848 if (expired())
849 return __shared_ptr<element_type, _Lp>();
850
851 try
852 {
853 return __shared_ptr<element_type, _Lp>(*this);
854 }
855 catch(const bad_weak_ptr&)
856 {
857 // Q: How can we get here?
858 // A: Another thread may have invalidated r after the
859 // use_count test above.
860 return __shared_ptr<element_type>();
861 }
862
863 #else
864 // Optimization: avoid try/catch overhead when single threaded.
865 return expired() ? __shared_ptr<element_type, _Lp>()
866 : __shared_ptr<element_type, _Lp>(*this);
867
868 #endif
869 } // XXX MT
870
871 long
use_count()872 use_count() const // never throws
873 { return _M_refcount._M_get_use_count(); }
874
875 bool
expired()876 expired() const // never throws
877 { return _M_refcount._M_get_use_count() == 0; }
878
879 void
reset()880 reset() // never throws
881 { __weak_ptr().swap(*this); }
882
883 void
swap(__weak_ptr & __s)884 swap(__weak_ptr& __s) // never throws
885 {
886 std::swap(_M_ptr, __s._M_ptr);
887 _M_refcount._M_swap(__s._M_refcount);
888 }
889
890 private:
891 // Used by __enable_shared_from_this.
892 void
_M_assign(_Tp * __ptr,const __shared_count<_Lp> & __refcount)893 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
894 {
895 _M_ptr = __ptr;
896 _M_refcount = __refcount;
897 }
898
899 template<typename _Tp1>
900 bool
_M_less(const __weak_ptr<_Tp1,_Lp> & __rhs)901 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
902 { return _M_refcount < __rhs._M_refcount; }
903
904 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
905 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
906 friend class __enable_shared_from_this<_Tp, _Lp>;
907 friend class enable_shared_from_this<_Tp>;
908
909 // Friend injected into namespace and found by ADL.
910 template<typename _Tp1>
911 friend inline bool
912 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
913 { return __lhs._M_less(__rhs); }
914
915 _Tp* _M_ptr; // Contained pointer.
916 __weak_count<_Lp> _M_refcount; // Reference counter.
917 };
918
919 // 2.2.4.7 weak_ptr specialized algorithms.
920 template<typename _Tp, _Lock_policy _Lp>
921 inline void
swap(__weak_ptr<_Tp,_Lp> & __a,__weak_ptr<_Tp,_Lp> & __b)922 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
923 { __a.swap(__b); }
924
925
926 template<typename _Tp, _Lock_policy _Lp>
927 class __enable_shared_from_this
928 {
929 protected:
__enable_shared_from_this()930 __enable_shared_from_this() { }
931
__enable_shared_from_this(const __enable_shared_from_this &)932 __enable_shared_from_this(const __enable_shared_from_this&) { }
933
934 __enable_shared_from_this&
935 operator=(const __enable_shared_from_this&)
936 { return *this; }
937
~__enable_shared_from_this()938 ~__enable_shared_from_this() { }
939
940 public:
941 __shared_ptr<_Tp, _Lp>
shared_from_this()942 shared_from_this()
943 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
944
945 __shared_ptr<const _Tp, _Lp>
shared_from_this()946 shared_from_this() const
947 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
948
949 private:
950 template<typename _Tp1>
951 void
_M_weak_assign(_Tp1 * __p,const __shared_count<_Lp> & __n)952 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
953 { _M_weak_this._M_assign(__p, __n); }
954
955 template<typename _Tp1>
956 friend void
__enable_shared_from_this_helper(const __shared_count<_Lp> & __pn,const __enable_shared_from_this * __pe,const _Tp1 * __px)957 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
958 const __enable_shared_from_this* __pe,
959 const _Tp1* __px)
960 {
961 if (__pe != 0)
962 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
963 }
964
965 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
966 };
967
968
969 // The actual TR1 shared_ptr, with forwarding constructors and
970 // assignment operators.
971 template<typename _Tp>
972 class shared_ptr
973 : public __shared_ptr<_Tp>
974 {
975 public:
shared_ptr()976 shared_ptr()
977 : __shared_ptr<_Tp>() { }
978
979 template<typename _Tp1>
980 explicit
shared_ptr(_Tp1 * __p)981 shared_ptr(_Tp1* __p)
982 : __shared_ptr<_Tp>(__p) { }
983
984 template<typename _Tp1, typename _Deleter>
shared_ptr(_Tp1 * __p,_Deleter __d)985 shared_ptr(_Tp1* __p, _Deleter __d)
986 : __shared_ptr<_Tp>(__p, __d) { }
987
988 template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r)989 shared_ptr(const shared_ptr<_Tp1>& __r)
990 : __shared_ptr<_Tp>(__r) { }
991
992 template<typename _Tp1>
993 explicit
shared_ptr(const weak_ptr<_Tp1> & __r)994 shared_ptr(const weak_ptr<_Tp1>& __r)
995 : __shared_ptr<_Tp>(__r) { }
996
997 template<typename _Tp1>
998 explicit
shared_ptr(std::auto_ptr<_Tp1> & __r)999 shared_ptr(std::auto_ptr<_Tp1>& __r)
1000 : __shared_ptr<_Tp>(__r) { }
1001
1002 template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r,__static_cast_tag)1003 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1004 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1005
1006 template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r,__const_cast_tag)1007 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1008 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1009
1010 template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r,__dynamic_cast_tag)1011 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1012 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1013
1014 template<typename _Tp1>
1015 shared_ptr&
1016 operator=(const shared_ptr<_Tp1>& __r) // never throws
1017 {
1018 this->__shared_ptr<_Tp>::operator=(__r);
1019 return *this;
1020 }
1021
1022 template<typename _Tp1>
1023 shared_ptr&
1024 operator=(std::auto_ptr<_Tp1>& __r)
1025 {
1026 this->__shared_ptr<_Tp>::operator=(__r);
1027 return *this;
1028 }
1029 };
1030
1031 template<typename _Tp, typename _Tp1>
1032 shared_ptr<_Tp>
static_pointer_cast(const shared_ptr<_Tp1> & __r)1033 static_pointer_cast(const shared_ptr<_Tp1>& __r)
1034 { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
1035
1036 template<typename _Tp, typename _Tp1>
1037 shared_ptr<_Tp>
const_pointer_cast(const shared_ptr<_Tp1> & __r)1038 const_pointer_cast(const shared_ptr<_Tp1>& __r)
1039 { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
1040
1041 template<typename _Tp, typename _Tp1>
1042 shared_ptr<_Tp>
dynamic_pointer_cast(const shared_ptr<_Tp1> & __r)1043 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
1044 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
1045
1046
1047 // The actual TR1 weak_ptr, with forwarding constructors and
1048 // assignment operators.
1049 template<typename _Tp>
1050 class weak_ptr
1051 : public __weak_ptr<_Tp>
1052 {
1053 public:
weak_ptr()1054 weak_ptr()
1055 : __weak_ptr<_Tp>() { }
1056
1057 template<typename _Tp1>
weak_ptr(const weak_ptr<_Tp1> & __r)1058 weak_ptr(const weak_ptr<_Tp1>& __r)
1059 : __weak_ptr<_Tp>(__r) { }
1060
1061 template<typename _Tp1>
weak_ptr(const shared_ptr<_Tp1> & __r)1062 weak_ptr(const shared_ptr<_Tp1>& __r)
1063 : __weak_ptr<_Tp>(__r) { }
1064
1065 template<typename _Tp1>
1066 weak_ptr&
1067 operator=(const weak_ptr<_Tp1>& __r) // never throws
1068 {
1069 this->__weak_ptr<_Tp>::operator=(__r);
1070 return *this;
1071 }
1072
1073 template<typename _Tp1>
1074 weak_ptr&
1075 operator=(const shared_ptr<_Tp1>& __r) // never throws
1076 {
1077 this->__weak_ptr<_Tp>::operator=(__r);
1078 return *this;
1079 }
1080
1081 shared_ptr<_Tp>
lock()1082 lock() const // never throws
1083 {
1084 #ifdef __GTHREADS
1085 if (this->expired())
1086 return shared_ptr<_Tp>();
1087
1088 try
1089 {
1090 return shared_ptr<_Tp>(*this);
1091 }
1092 catch(const bad_weak_ptr&)
1093 {
1094 return shared_ptr<_Tp>();
1095 }
1096 #else
1097 return this->expired() ? shared_ptr<_Tp>()
1098 : shared_ptr<_Tp>(*this);
1099 #endif
1100 }
1101 };
1102
1103
1104 template<typename _Tp>
1105 class enable_shared_from_this
1106 {
1107 protected:
enable_shared_from_this()1108 enable_shared_from_this() { }
1109
enable_shared_from_this(const enable_shared_from_this &)1110 enable_shared_from_this(const enable_shared_from_this&) { }
1111
1112 enable_shared_from_this&
1113 operator=(const enable_shared_from_this&)
1114 { return *this; }
1115
~enable_shared_from_this()1116 ~enable_shared_from_this() { }
1117
1118 public:
1119 shared_ptr<_Tp>
shared_from_this()1120 shared_from_this()
1121 { return shared_ptr<_Tp>(this->_M_weak_this); }
1122
1123 shared_ptr<const _Tp>
shared_from_this()1124 shared_from_this() const
1125 { return shared_ptr<const _Tp>(this->_M_weak_this); }
1126
1127 private:
1128 template<typename _Tp1>
1129 void
_M_weak_assign(_Tp1 * __p,const __shared_count<> & __n)1130 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1131 { _M_weak_this._M_assign(__p, __n); }
1132
1133 template<typename _Tp1>
1134 friend void
__enable_shared_from_this_helper(const __shared_count<> & __pn,const enable_shared_from_this * __pe,const _Tp1 * __px)1135 __enable_shared_from_this_helper(const __shared_count<>& __pn,
1136 const enable_shared_from_this* __pe,
1137 const _Tp1* __px)
1138 {
1139 if (__pe != 0)
1140 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1141 }
1142
1143 mutable weak_ptr<_Tp> _M_weak_this;
1144 };
1145
1146 _GLIBCXX_END_NAMESPACE
1147 } // namespace std
1148
1149 #endif
1150