boost_shared_ptr.h 31.4 KB
Newer Older
1
// <tr1_impl/boost_shared_ptr.h> -*- C++ -*-
Benjamin Kosnik committed
2

3
// Copyright (C) 2007 Free Software Foundation, Inc.
Benjamin Kosnik committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// 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,
Benjamin Kosnik committed
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

//  shared_count.hpp
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.

//  shared_ptr.hpp
//  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
//  Copyright (C) 2001, 2002, 2003 Peter Dimov

//  weak_ptr.hpp
//  Copyright (C) 2001, 2002, 2003 Peter Dimov

//  enable_shared_from_this.hpp
//  Copyright (C) 2002 Peter Dimov

// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// GCC Note:  based on version 1.32.0 of the Boost library.

49
/** @file tr1_impl/boost_shared_ptr.h
Benjamin Kosnik committed
50 51 52 53 54 55
 *  This is an internal header file, included by other library headers.
 *  You should not attempt to use it directly.
 */

namespace std
{
56
_GLIBCXX_BEGIN_NAMESPACE_TR1
Benjamin Kosnik committed
57

58 59 60 61 62 63 64
  class bad_weak_ptr : public std::exception
  {
  public:
    virtual char const*
    what() const throw()
    { return "tr1::bad_weak_ptr"; }
  };
Benjamin Kosnik committed
65

66
  // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
67 68 69
  inline void
  __throw_bad_weak_ptr()
  {
Benjamin Kosnik committed
70
#if __EXCEPTIONS
71
    throw bad_weak_ptr();
Benjamin Kosnik committed
72
#else
73
    __builtin_abort();
Benjamin Kosnik committed
74
#endif
75
  }
Benjamin Kosnik committed
76

77 78 79 80 81
  using __gnu_cxx::_Lock_policy;
  using __gnu_cxx::__default_lock_policy;
  using __gnu_cxx::_S_single;
  using __gnu_cxx::_S_mutex;
  using __gnu_cxx::_S_atomic;
Benjamin Kosnik committed
82

83 84 85 86 87
  template<typename _Tp>
    struct _Sp_deleter
    {
      typedef void result_type;
      typedef _Tp* argument_type;
Benjamin Kosnik committed
88

89
      void
90 91
      operator()(_Tp* __p) const
      { delete __p; }
92
    };
Benjamin Kosnik committed
93

94 95 96 97
  // Empty helper class except when the template argument is _S_mutex.
  template<_Lock_policy _Lp>
    class _Mutex_base
    { };
Benjamin Kosnik committed
98

99
  template<>
100 101
    class _Mutex_base<_S_mutex>
    : public __gnu_cxx::__mutex
102
    { };
Benjamin Kosnik committed
103

104
  template<_Lock_policy _Lp = __default_lock_policy>
105 106
    class _Sp_counted_base
    : public _Mutex_base<_Lp>
107
    {
108
    public:  
109 110
      _Sp_counted_base()
      : _M_use_count(1), _M_weak_count(1) { }
111 112 113 114
      
      virtual
      ~_Sp_counted_base() // nothrow 
      { }
115
  
116 117 118
      // Called when _M_use_count drops to zero, to release the resources
      // managed by *this.
      virtual void
119
      _M_dispose() = 0; // nothrow
120 121 122
      
      // Called when _M_weak_count drops to zero.
      virtual void
123
      _M_destroy() // nothrow
124 125 126
      { delete this; }
      
      virtual void*
127 128
      _M_get_deleter(const std::type_info&) = 0;

129
      void
130
      _M_add_ref_copy()
131
      { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
132
  
133
      void
134
      _M_add_ref_lock();
135 136
      
      void
137
      _M_release() // nothrow
138
      {
139 140
	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count,
						   -1) == 1)
141
	  {
142
	    _M_dispose();
143
#ifdef __GTHREADS
144 145
	    _GLIBCXX_READ_MEM_BARRIER;
	    _GLIBCXX_WRITE_MEM_BARRIER;
146
#endif
147 148
	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
						       -1) == 1)
149
	      _M_destroy();
150 151
	  }
      }
152
  
153
      void
154
      _M_weak_add_ref() // nothrow
155
      { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
156

157
      void
158
      _M_weak_release() // nothrow
159
      {
160
	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
161 162 163 164 165
	  {
#ifdef __GTHREADS
	    _GLIBCXX_READ_MEM_BARRIER;
	    _GLIBCXX_WRITE_MEM_BARRIER;
#endif
166
	    _M_destroy();
167
	  }
168
      }
169 170
  
      long
171
      _M_get_use_count() const // nothrow
172 173 174 175 176
      { return _M_use_count; }  // XXX is this MT safe? 
      
    private:  
      _Sp_counted_base(_Sp_counted_base const&);
      _Sp_counted_base& operator=(_Sp_counted_base const&);
177 178 179

      _Atomic_word  _M_use_count;     // #shared
      _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
180 181 182 183
    };

  template<>
    inline void
184 185
    _Sp_counted_base<_S_single>::
    _M_add_ref_lock()
186
    {
187
      if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
188 189 190 191 192
	{
	  _M_use_count = 0;
	  __throw_bad_weak_ptr();
	}
    }
193

194 195
  template<>
    inline void
196 197
    _Sp_counted_base<_S_mutex>::
    _M_add_ref_lock()
198 199
    {
      __gnu_cxx::__scoped_lock sentry(*this);
200
      if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
201 202 203 204 205
	{
	  _M_use_count = 0;
	  __throw_bad_weak_ptr();
	}
    }
Benjamin Kosnik committed
206

207 208
  template<> 
    inline void
209 210
    _Sp_counted_base<_S_atomic>::
    _M_add_ref_lock()
211
    {
212 213 214 215 216 217 218 219 220 221 222 223 224
      // Perform lock-free add-if-not-zero operation.
      _Atomic_word __count;
      do
	{
	  __count = _M_use_count;
	  if (__count == 0)
	    __throw_bad_weak_ptr();
	  
	  // Replace the current counter value with the old value + 1, as
	  // long as it's not changed meanwhile. 
	}
      while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
					   __count + 1));
225
    }
Benjamin Kosnik committed
226

227
  template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
228 229
    class _Sp_counted_base_impl
    : public _Sp_counted_base<_Lp>
230 231 232 233
    {
    public:
      /**
       *  @brief   
234
       *  @pre     __d(__p) must not throw.
235 236 237
       */
      _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
      : _M_ptr(__p), _M_del(__d) { }
238
    
239
      virtual void
240
      _M_dispose() // nothrow
241 242 243
      { _M_del(_M_ptr); }
      
      virtual void*
244
      _M_get_deleter(const std::type_info& __ti)
245 246 247 248 249 250
      { return __ti == typeid(_Deleter) ? &_M_del : 0; }
      
    private:
      _Sp_counted_base_impl(const _Sp_counted_base_impl&);
      _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
      
251 252
      _Ptr      _M_ptr;  // copy constructor must not throw
      _Deleter  _M_del;  // copy constructor must not throw
253
    };
Benjamin Kosnik committed
254

255
  template<_Lock_policy _Lp = __default_lock_policy>
256
    class __weak_count;
Benjamin Kosnik committed
257

258
  template<_Lock_policy _Lp = __default_lock_policy>
259
    class __shared_count
260
    {
261
    public: 
262 263
      __shared_count()
      : _M_pi(0) // nothrow
264
      { }
265
  
266
      template<typename _Ptr, typename _Deleter>
267
        __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
268 269 270 271 272 273 274 275 276 277 278
        {
	  try
	    {
	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
	    }
	  catch(...)
	    {
	      __d(__p); // Call _Deleter on __p.
	      __throw_exception_again;
	    }
	}
279

280 281 282
      // Special case for auto_ptr<_Tp> to provide the strong guarantee.
      template<typename _Tp>
        explicit
283
        __shared_count(std::auto_ptr<_Tp>& __r)
284 285 286
	: _M_pi(new _Sp_counted_base_impl<_Tp*,
		_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
        { __r.release(); }
287
  
288 289 290
      // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
      explicit
      __shared_count(const __weak_count<_Lp>& __r);
291
  
292
      ~__shared_count() // nothrow
293 294
      {
	if (_M_pi != 0)
295
	  _M_pi->_M_release();
296 297
      }
      
298
      __shared_count(const __shared_count& __r)
299 300 301
      : _M_pi(__r._M_pi) // nothrow
      {
	if (_M_pi != 0)
302
	  _M_pi->_M_add_ref_copy();
303
      }
304
  
305 306
      __shared_count&
      operator=(const __shared_count& __r) // nothrow
307 308 309 310 311
      {
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
	if (__tmp != _M_pi)
	  {
	    if (__tmp != 0)
312
	      __tmp->_M_add_ref_copy();
313
	    if (_M_pi != 0)
314
	      _M_pi->_M_release();
315 316 317 318
	    _M_pi = __tmp;
	  }
	return *this;
      }
319
  
320
      void
321
      _M_swap(__shared_count& __r) // nothrow
322 323 324 325 326
      {
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
	__r._M_pi = _M_pi;
	_M_pi = __tmp;
      }
327
  
328
      long
329 330 331
      _M_get_use_count() const // nothrow
      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }

332
      bool
333 334
      _M_unique() const // nothrow
      { return this->_M_get_use_count() == 1; }
335 336
      
      friend inline bool
337
      operator==(const __shared_count& __a, const __shared_count& __b)
338
      { return __a._M_pi == __b._M_pi; }
339
  
340
      friend inline bool
341
      operator<(const __shared_count& __a, const __shared_count& __b)
342
      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
343
  
344
      void*
345 346 347 348 349 350 351
      _M_get_deleter(const std::type_info& __ti) const
      { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }

    private:
      friend class __weak_count<_Lp>;

      _Sp_counted_base<_Lp>*  _M_pi;
352 353 354
    };

  template<_Lock_policy _Lp>
355
    class __weak_count
356
    {
357 358
    public:
      __weak_count()
359 360
      : _M_pi(0) // nothrow
      { }
361
  
362
      __weak_count(const __shared_count<_Lp>& __r)
363 364 365
      : _M_pi(__r._M_pi) // nothrow
      {
	if (_M_pi != 0)
366
	  _M_pi->_M_weak_add_ref();
367 368
      }
      
369
      __weak_count(const __weak_count<_Lp>& __r)
370 371 372
      : _M_pi(__r._M_pi) // nothrow
      {
	if (_M_pi != 0)
373
	  _M_pi->_M_weak_add_ref();
374 375
      }
      
376
      ~__weak_count() // nothrow
377 378
      {
	if (_M_pi != 0)
379
	  _M_pi->_M_weak_release();
380 381
      }
      
382 383
      __weak_count<_Lp>&
      operator=(const __shared_count<_Lp>& __r) // nothrow
384 385 386
      {
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
	if (__tmp != 0)
387
	  __tmp->_M_weak_add_ref();
388
	if (_M_pi != 0)
389
	  _M_pi->_M_weak_release();
390 391 392 393
	_M_pi = __tmp;  
	return *this;
      }
      
394 395
      __weak_count<_Lp>&
      operator=(const __weak_count<_Lp>& __r) // nothrow
396
      {
397
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
398
	if (__tmp != 0)
399
	  __tmp->_M_weak_add_ref();
400
	if (_M_pi != 0)
401
	  _M_pi->_M_weak_release();
402 403 404
	_M_pi = __tmp;
	return *this;
      }
405

406
      void
407
      _M_swap(__weak_count<_Lp>& __r) // nothrow
408
      {
409
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
410 411 412
	__r._M_pi = _M_pi;
	_M_pi = __tmp;
      }
413
  
414
      long
415 416 417
      _M_get_use_count() const // nothrow
      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }

418
      friend inline bool
419
      operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
420 421 422
      { return __a._M_pi == __b._M_pi; }
      
      friend inline bool
423
      operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
424
      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
425 426 427 428 429

    private:
      friend class __shared_count<_Lp>;

      _Sp_counted_base<_Lp>*  _M_pi;
430 431 432 433
    };

  template<_Lock_policy _Lp>
    inline
434 435
    __shared_count<_Lp>::
    __shared_count(const __weak_count<_Lp>& __r)
436
    : _M_pi(__r._M_pi)
437 438
    {
      if (_M_pi != 0)
439
	_M_pi->_M_add_ref_lock();
440 441
      else
	__throw_bad_weak_ptr();
442 443
    }
  
444

445
  // Forward declarations.
446 447
  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    class __shared_ptr;
448
  
449 450
  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    class __weak_ptr;
Benjamin Kosnik committed
451

452
  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
453
    class __enable_shared_from_this;
Benjamin Kosnik committed
454

455 456 457 458 459
  template<typename _Tp>
    class shared_ptr;
  
  template<typename _Tp>
    class weak_ptr;
460

461 462
  template<typename _Tp>
    class enable_shared_from_this;
Benjamin Kosnik committed
463

464
  // Support for enable_shared_from_this.
Benjamin Kosnik committed
465

466 467 468
  // Friend of __enable_shared_from_this.
  template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
    void
469
    __enable_shared_from_this_helper(const __shared_count<_Lp>&,
470 471
				     const __enable_shared_from_this<_Tp1,
				     _Lp>*, const _Tp2*);
Benjamin Kosnik committed
472

473 474 475 476 477 478 479
  // Friend of enable_shared_from_this.
  template<typename _Tp1, typename _Tp2>
    void
    __enable_shared_from_this_helper(const __shared_count<>&,
				     const enable_shared_from_this<_Tp1>*,
				     const _Tp2*);

480 481
  template<_Lock_policy _Lp>
    inline void
482
    __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
483
    { }
Benjamin Kosnik committed
484 485


486 487 488 489
  struct __static_cast_tag { };
  struct __const_cast_tag { };
  struct __dynamic_cast_tag { };

490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
  /**
   *  @class shared_ptr <tr1/memory>
   *
   *  A smart pointer with reference-counted copy semantics.
   *  The object pointed to is deleted when the last shared_ptr pointing to
   *  it is destroyed or reset.
   */
  template<typename _Tp, _Lock_policy _Lp>
    class __shared_ptr
    {
    public:
      typedef _Tp   element_type;
      
      /** @brief  Construct an empty %__shared_ptr.
       *  @post   use_count()==0 && get()==0
       */
      __shared_ptr()
      : _M_ptr(0), _M_refcount() // never throws
      { }
Benjamin Kosnik committed
509

510 511 512 513
      /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
       *  @param  __p  A pointer that is convertible to element_type*.
       *  @post   use_count() == 1 && get() == __p
       *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
514 515 516 517 518 519 520 521
       */
      template<typename _Tp1>
        explicit
        __shared_ptr(_Tp1* __p)
	: _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
        {
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
	  // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
522
	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
523
	}
Benjamin Kosnik committed
524

525
      //
526
      // Requirements: _Deleter' copy constructor and destructor must not throw
527
      //
528
      // __shared_ptr will release __p by calling __d(__p)
529
      //
530 531 532 533 534 535
      /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
       *          and the deleter @a __d.
       *  @param  __p  A pointer.
       *  @param  __d  A deleter.
       *  @post   use_count() == 1 && get() == __p
       *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
536 537 538 539 540 541
       */
      template<typename _Tp1, typename _Deleter>
        __shared_ptr(_Tp1* __p, _Deleter __d)
	: _M_ptr(__p), _M_refcount(__p, __d)
        {
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
542 543
	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
544 545 546 547
	}
      
      //  generated copy constructor, assignment, destructor are fine.
      
548
      /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
549
       *          otherwise construct a %__shared_ptr that shares ownership
550 551 552
       *          with @a __r.
       *  @param  __r  A %__shared_ptr.
       *  @post   get() == __r.get() && use_count() == __r.use_count()
553 554 555 556 557 558 559
       *  @throw  std::bad_alloc, in which case 
       */
      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }

560 561 562 563 564
      /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
       *          and stores a copy of the pointer stored in @a __r.
       *  @param  __r  A weak_ptr.
       *  @post   use_count() == __r.use_count()
       *  @throw  bad_weak_ptr when __r.expired(),
565 566 567 568 569 570 571 572
       *          in which case the constructor has no effect.
       */
      template<typename _Tp1>
        explicit
        __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
	: _M_refcount(__r._M_refcount) // may throw
        {
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
573
	  // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
574 575 576
	  // did not throw.
	  _M_ptr = __r._M_ptr;
	}
Paolo Carlini committed
577

578
      /**
579
       * @post use_count() == 1 and __r.get() == 0
580 581 582 583 584 585
       */
      template<typename _Tp1>
        explicit
        __shared_ptr(std::auto_ptr<_Tp1>& __r)
	: _M_ptr(__r.get()), _M_refcount()
        {
586 587 588 589 590
	  // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
	  // delete __r.release() well-formed
	  _Tp1* __tmp = __r.get();
	  _M_refcount = __shared_count<_Lp>(__r);
	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
591
	}
Benjamin Kosnik committed
592

593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
	: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
	  _M_refcount(__r._M_refcount)
        { }

      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
	: _M_ptr(const_cast<element_type*>(__r._M_ptr)),
	  _M_refcount(__r._M_refcount)
        { }

      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
	: _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
	  _M_refcount(__r._M_refcount)
        {
	  if (_M_ptr == 0) // need to allocate new counter -- the cast failed
611
	    _M_refcount = __shared_count<_Lp>();
612 613 614 615 616 617 618
	}
      
      template<typename _Tp1>
        __shared_ptr&
        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
        {
	  _M_ptr = __r._M_ptr;
619
	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
620 621
	  return *this;
	}
Benjamin Kosnik committed
622

623 624 625 626 627 628 629
      template<typename _Tp1>
        __shared_ptr&
        operator=(std::auto_ptr<_Tp1>& __r)
        {
	  __shared_ptr(__r).swap(*this);
	  return *this;
	}
Benjamin Kosnik committed
630

631 632 633
      void
      reset() // never throws
      { __shared_ptr().swap(*this); }
Benjamin Kosnik committed
634

635 636 637 638 639 640 641 642
      template<typename _Tp1>
        void
        reset(_Tp1* __p) // _Tp1 must be complete.
        {
	  // Catch self-reset errors.
	  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 
	  __shared_ptr(__p).swap(*this);
	}
Benjamin Kosnik committed
643

644 645
      template<typename _Tp1, typename _Deleter>
        void
646
        reset(_Tp1* __p, _Deleter __d)
647
        { __shared_ptr(__p, __d).swap(*this); }
Benjamin Kosnik committed
648

649
      // Allow class instantiation when _Tp is [cv-qual] void.
650 651 652 653 654
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
      typename std::add_lvalue_reference<_Tp>::type
#else
      typename std::tr1::add_reference<_Tp>::type
#endif
655
      operator*() const // never throws
Benjamin Kosnik committed
656
      {
657 658
	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
	return *_M_ptr;
Benjamin Kosnik committed
659 660
      }

661 662
      _Tp*
      operator->() const // never throws
Benjamin Kosnik committed
663
      {
664 665
	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
	return _M_ptr;
Benjamin Kosnik committed
666
      }
667 668 669 670
    
      _Tp*
      get() const // never throws
      { return _M_ptr; }
Benjamin Kosnik committed
671

672 673 674
      // Implicit conversion to "bool"
    private:
      typedef _Tp* __shared_ptr::*__unspecified_bool_type;
Benjamin Kosnik committed
675

676 677 678
    public:
      operator __unspecified_bool_type() const // never throws
      { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
Benjamin Kosnik committed
679

680 681
      bool
      unique() const // never throws
682
      { return _M_refcount._M_unique(); }
683 684 685

      long
      use_count() const // never throws
686
      { return _M_refcount._M_get_use_count(); }
Benjamin Kosnik committed
687 688

      void
689
      swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
Benjamin Kosnik committed
690
      {
691
	std::swap(_M_ptr, __other._M_ptr);
692
	_M_refcount._M_swap(__other._M_refcount);
Benjamin Kosnik committed
693 694
      }

695 696 697
    private:
      void*
      _M_get_deleter(const std::type_info& __ti) const
698
      { return _M_refcount._M_get_deleter(__ti); }
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726

      template<typename _Tp1, _Lock_policy _Lp1>
        bool
        _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
        { return _M_refcount < __rhs._M_refcount; }

      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;

      template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
        friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);

      // Friends injected into enclosing namespace and found by ADL:
      template<typename _Tp1>
        friend inline bool
        operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
        { return __a.get() == __b.get(); }

      template<typename _Tp1>
        friend inline bool
        operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
        { return __a.get() != __b.get(); }

      template<typename _Tp1>
        friend inline bool
        operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
        { return __a._M_less(__b); }

727 728
      _Tp*         	   _M_ptr;         // Contained pointer.
      __shared_count<_Lp>  _M_refcount;    // Reference counter.
729 730 731 732 733 734 735 736 737 738
    };

  // 2.2.3.8 shared_ptr specialized algorithms.
  template<typename _Tp, _Lock_policy _Lp>
    inline void
    swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
    { __a.swap(__b); }

  // 2.2.3.9 shared_ptr casts
  /** @warning The seemingly equivalent
739
   *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
740 741 742 743 744 745 746 747 748
   *           will eventually result in undefined behaviour,
   *           attempting to delete the same object twice.
   */
  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    __shared_ptr<_Tp, _Lp>
    static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }

  /** @warning The seemingly equivalent
749
   *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
750 751 752 753 754 755 756 757 758
   *           will eventually result in undefined behaviour,
   *           attempting to delete the same object twice.
   */
  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    __shared_ptr<_Tp, _Lp>
    const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }

  /** @warning The seemingly equivalent
759
   *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
760 761 762 763 764 765 766 767 768 769 770 771 772
   *           will eventually result in undefined behaviour,
   *           attempting to delete the same object twice.
   */
  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    __shared_ptr<_Tp, _Lp>
    dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }

  // 2.2.3.7 shared_ptr I/O
  template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
    std::basic_ostream<_Ch, _Tr>&
    operator<<(std::basic_ostream<_Ch, _Tr>& __os, 
	       const __shared_ptr<_Tp, _Lp>& __p)
Benjamin Kosnik committed
773
    {
774 775
      __os << __p.get();
      return __os;
Benjamin Kosnik committed
776 777
    }

778 779 780 781 782
  // 2.2.3.10 shared_ptr get_deleter (experimental)
  template<typename _Del, typename _Tp, _Lock_policy _Lp>
    inline _Del*
    get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
    { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
Benjamin Kosnik committed
783 784


785 786
  template<typename _Tp, _Lock_policy _Lp>
    class __weak_ptr
Benjamin Kosnik committed
787
    {
788 789 790
    public:
      typedef _Tp element_type;
      
791 792
      __weak_ptr()
      : _M_ptr(0), _M_refcount() // never throws
793
      { }
Benjamin Kosnik committed
794

795 796 797 798
      // Generated copy constructor, assignment, destructor are fine.
      
      // The "obvious" converting constructor implementation:
      //
799 800 801
      //  template<typename _Tp1>
      //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
      //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
802 803 804 805
      //    { }
      //
      // has a serious problem.
      //
806 807
      //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
      //  conversion may require access to *__r._M_ptr (virtual inheritance).
808 809
      //
      // It is not possible to avoid spurious access violations since
810
      // in multithreaded programs __r._M_ptr may be invalidated at any point.
811
      template<typename _Tp1>
812 813
        __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
	: _M_refcount(__r._M_refcount) // never throws
814 815
        {
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
816
	  _M_ptr = __r.lock().get();
817
	}
Benjamin Kosnik committed
818

819
      template<typename _Tp1>
820 821
        __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
822
        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
Benjamin Kosnik committed
823

824 825
      template<typename _Tp1>
        __weak_ptr&
826
        operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
827
        {
828 829
	  _M_ptr = __r.lock().get();
	  _M_refcount = __r._M_refcount;
830 831 832 833 834
	  return *this;
	}
      
      template<typename _Tp1>
        __weak_ptr&
835
        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
836
        {
837 838
	  _M_ptr = __r._M_ptr;
	  _M_refcount = __r._M_refcount;
839 840
	  return *this;
	}
Benjamin Kosnik committed
841

842 843
      __shared_ptr<_Tp, _Lp>
      lock() const // never throws
Benjamin Kosnik committed
844 845
      {
#ifdef __GTHREADS
846 847 848
	// Optimization: avoid throw overhead.
	if (expired())
	  return __shared_ptr<element_type, _Lp>();
849

850 851 852 853
	try
	  {
	    return __shared_ptr<element_type, _Lp>(*this);
	  }
854
	catch(const bad_weak_ptr&)
855 856 857 858
	  {
	    // Q: How can we get here?
	    // A: Another thread may have invalidated r after the
	    //    use_count test above.
859
	    return __shared_ptr<element_type, _Lp>();
860 861
	  }
	
Benjamin Kosnik committed
862
#else
863 864 865
	// Optimization: avoid try/catch overhead when single threaded.
	return expired() ? __shared_ptr<element_type, _Lp>()
	                 : __shared_ptr<element_type, _Lp>(*this);
Benjamin Kosnik committed
866 867

#endif
868
      } // XXX MT
Benjamin Kosnik committed
869

870 871
      long
      use_count() const // never throws
872
      { return _M_refcount._M_get_use_count(); }
Benjamin Kosnik committed
873 874

      bool
875
      expired() const // never throws
876
      { return _M_refcount._M_get_use_count() == 0; }
877 878 879 880
      
      void
      reset() // never throws
      { __weak_ptr().swap(*this); }
881

882 883 884 885
      void
      swap(__weak_ptr& __s) // never throws
      {
	std::swap(_M_ptr, __s._M_ptr);
886
	_M_refcount._M_swap(__s._M_refcount);
887
      }
Benjamin Kosnik committed
888

889 890 891
    private:
      // Used by __enable_shared_from_this.
      void
892
      _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
893 894 895 896
      {
	_M_ptr = __ptr;
	_M_refcount = __refcount;
      }
Benjamin Kosnik committed
897

898 899 900 901 902 903 904 905 906 907
      template<typename _Tp1>
        bool
        _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
        { return _M_refcount < __rhs._M_refcount; }

      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
      friend class __enable_shared_from_this<_Tp, _Lp>;
      friend class enable_shared_from_this<_Tp>;

908 909 910 911 912
      // Friend injected into namespace and found by ADL.
      template<typename _Tp1>
        friend inline bool
        operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
        { return __lhs._M_less(__rhs); }
913 914 915

      _Tp*       	 _M_ptr;         // Contained pointer.
      __weak_count<_Lp>  _M_refcount;    // Reference counter.
916
    };
Benjamin Kosnik committed
917

918 919
  // 2.2.4.7 weak_ptr specialized algorithms.
  template<typename _Tp, _Lock_policy _Lp>
920
    inline void
921 922
    swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
    { __a.swap(__b); }
Benjamin Kosnik committed
923 924


925
  template<typename _Tp, _Lock_policy _Lp>
926
    class __enable_shared_from_this
Benjamin Kosnik committed
927
    {
928 929 930 931 932 933 934 935
    protected:
      __enable_shared_from_this() { }
      
      __enable_shared_from_this(const __enable_shared_from_this&) { }
      
      __enable_shared_from_this&
      operator=(const __enable_shared_from_this&)
      { return *this; }
Benjamin Kosnik committed
936

937 938 939 940 941
      ~__enable_shared_from_this() { }
      
    public:
      __shared_ptr<_Tp, _Lp>
      shared_from_this()
942 943
      { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }

944 945
      __shared_ptr<const _Tp, _Lp>
      shared_from_this() const
946 947
      { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }

948 949 950
    private:
      template<typename _Tp1>
        void
951
        _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
952 953 954 955
        { _M_weak_this._M_assign(__p, __n); }

      template<typename _Tp1>
        friend void
956
        __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
957 958 959 960 961 962
					 const __enable_shared_from_this* __pe,
					 const _Tp1* __px)
        {
	  if (__pe != 0)
	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
	}
963

964
      mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
965
    };
966

967

968 969 970
  // The actual TR1 shared_ptr, with forwarding constructors and
  // assignment operators.
  template<typename _Tp>
971 972
    class shared_ptr
    : public __shared_ptr<_Tp>
973 974
    {
    public:
975 976 977
      shared_ptr()
      : __shared_ptr<_Tp>() { }

978 979 980 981
      template<typename _Tp1>
        explicit
        shared_ptr(_Tp1* __p)
	: __shared_ptr<_Tp>(__p) { }
982

983 984 985
      template<typename _Tp1, typename _Deleter>
        shared_ptr(_Tp1* __p, _Deleter __d)
	: __shared_ptr<_Tp>(__p, __d) { }
986

987
      template<typename _Tp1>
988
        shared_ptr(const shared_ptr<_Tp1>& __r)
989
	: __shared_ptr<_Tp>(__r) { }
990

991 992
      template<typename _Tp1>
        explicit
993
        shared_ptr(const weak_ptr<_Tp1>& __r)
994
	: __shared_ptr<_Tp>(__r) { }
995

996 997 998 999 1000 1001
      template<typename _Tp1>
        explicit
        shared_ptr(std::auto_ptr<_Tp1>& __r)
	: __shared_ptr<_Tp>(__r) { }

      template<typename _Tp1>
1002
        shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1003 1004 1005
	: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }

      template<typename _Tp1>
1006
        shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1007
	: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1008

1009
      template<typename _Tp1>
1010
        shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1011 1012 1013 1014
	: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }

      template<typename _Tp1>
        shared_ptr&
1015
        operator=(const shared_ptr<_Tp1>& __r) // never throws
1016 1017 1018 1019
        {
	  this->__shared_ptr<_Tp>::operator=(__r);
	  return *this;
	}
1020

1021 1022
      template<typename _Tp1>
        shared_ptr&
1023
        operator=(std::auto_ptr<_Tp1>& __r)
1024 1025 1026 1027 1028
        {
	  this->__shared_ptr<_Tp>::operator=(__r);
	  return *this;
	}
    };
Benjamin Kosnik committed
1029

1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
  template<typename _Tp, typename _Tp1>
    shared_ptr<_Tp>
    static_pointer_cast(const shared_ptr<_Tp1>& __r)
    { return shared_ptr<_Tp>(__r, __static_cast_tag()); }

  template<typename _Tp, typename _Tp1>
    shared_ptr<_Tp>
    const_pointer_cast(const shared_ptr<_Tp1>& __r)
    { return shared_ptr<_Tp>(__r, __const_cast_tag()); }

  template<typename _Tp, typename _Tp1>
    shared_ptr<_Tp>
    dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
    { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }


  // The actual TR1 weak_ptr, with forwarding constructors and
  // assignment operators.
  template<typename _Tp>
    class weak_ptr
    : public __weak_ptr<_Tp>
    {
    public:
      weak_ptr()
      : __weak_ptr<_Tp>() { }
      
      template<typename _Tp1>
        weak_ptr(const weak_ptr<_Tp1>& __r)
	: __weak_ptr<_Tp>(__r) { }

      template<typename _Tp1>
        weak_ptr(const shared_ptr<_Tp1>& __r)
	: __weak_ptr<_Tp>(__r) { }

      template<typename _Tp1>
        weak_ptr&
        operator=(const weak_ptr<_Tp1>& __r) // never throws
        {
	  this->__weak_ptr<_Tp>::operator=(__r);
	  return *this;
	}

      template<typename _Tp1>
        weak_ptr&
        operator=(const shared_ptr<_Tp1>& __r) // never throws
        {
	  this->__weak_ptr<_Tp>::operator=(__r);
	  return *this;
	}

      shared_ptr<_Tp>
      lock() const // never throws
      {
#ifdef __GTHREADS
	if (this->expired())
	  return shared_ptr<_Tp>();

	try
	  {
	    return shared_ptr<_Tp>(*this);
	  }
	catch(const bad_weak_ptr&)
	  {
	    return shared_ptr<_Tp>();
	  }
#else
	return this->expired() ? shared_ptr<_Tp>()
	                       : shared_ptr<_Tp>(*this);
#endif
      }
    };


1103
  template<typename _Tp>
1104
    class enable_shared_from_this
1105 1106
    {
    protected:
1107
      enable_shared_from_this() { }
1108
      
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
      enable_shared_from_this(const enable_shared_from_this&) { }

      enable_shared_from_this&
      operator=(const enable_shared_from_this&)
      { return *this; }

      ~enable_shared_from_this() { }

    public:
      shared_ptr<_Tp>
      shared_from_this()
      { return shared_ptr<_Tp>(this->_M_weak_this); }

      shared_ptr<const _Tp>
      shared_from_this() const
      { return shared_ptr<const _Tp>(this->_M_weak_this); }

    private:
      template<typename _Tp1>
        void
        _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
        { _M_weak_this._M_assign(__p, __n); }

      template<typename _Tp1>
        friend void
        __enable_shared_from_this_helper(const __shared_count<>& __pn,
					 const enable_shared_from_this* __pe,
					 const _Tp1* __px)
        {
	  if (__pe != 0)
	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
	}

      mutable weak_ptr<_Tp>  _M_weak_this;
1143
    };
1144

1145 1146
_GLIBCXX_END_NAMESPACE_TR1
}