OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [tr1/] [shared_ptr.h] - Blame information for rev 35

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.