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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [tr1/] [shared_ptr.h] - Blame information for rev 424

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// <tr1/shared_ptr.h> -*- C++ -*-
2
 
3
// Copyright (C) 2007, 2008, 2009 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
 *  You should not attempt to use it directly.
47
 */
48
 
49
#ifndef _TR1_SHARED_PTR_H
50
#define _TR1_SHARED_PTR_H 1
51
 
52
#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
53
#  error TR1 header cannot be included from C++0x header
54
#endif
55
 
56
namespace std
57
{
58
namespace tr1
59
{
60
  template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
61
    class _Sp_counted_base_impl
62
    : public _Sp_counted_base<_Lp>
63
    {
64
    public:
65
      // Precondition: __d(__p) must not throw.
66
      _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
67
      : _M_ptr(__p), _M_del(__d) { }
68
 
69
      virtual void
70
      _M_dispose() // nothrow
71
      { _M_del(_M_ptr); }
72
 
73
      virtual void*
74
      _M_get_deleter(const std::type_info& __ti)
75
      {
76
#ifdef __GXX_RTTI
77
        return __ti == typeid(_Deleter) ? &_M_del : 0;
78
#else
79
        return 0;
80
#endif
81
      }
82
 
83
    private:
84
      _Sp_counted_base_impl(const _Sp_counted_base_impl&);
85
      _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
86
 
87
      _Ptr      _M_ptr;  // copy constructor must not throw
88
      _Deleter  _M_del;  // copy constructor must not throw
89
    };
90
 
91
  template<_Lock_policy _Lp = __default_lock_policy>
92
    class __weak_count;
93
 
94
  template<typename _Tp>
95
    struct _Sp_deleter
96
    {
97
      typedef void result_type;
98
      typedef _Tp* argument_type;
99
      void operator()(_Tp* __p) const { delete __p; }
100
    };
101
 
102
  template<_Lock_policy _Lp = __default_lock_policy>
103
    class __shared_count
104
    {
105
    public:
106
      __shared_count()
107
      : _M_pi(0) // nothrow
108
      { }
109
 
110
      template<typename _Ptr>
111
        __shared_count(_Ptr __p) : _M_pi(0)
112
        {
113
          __try
114
            {
115
              typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
116
              _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
117
                  __p, _Sp_deleter<_Tp>());
118
            }
119
          __catch(...)
120
            {
121
              delete __p;
122
              __throw_exception_again;
123
            }
124
        }
125
 
126
      template<typename _Ptr, typename _Deleter>
127
        __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
128
        {
129
          __try
130
            {
131
              _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
132
            }
133
          __catch(...)
134
            {
135
              __d(__p); // Call _Deleter on __p.
136
              __throw_exception_again;
137
            }
138
        }
139
 
140
      // Special case for auto_ptr<_Tp> to provide the strong guarantee.
141
      template<typename _Tp>
142
        explicit
143
        __shared_count(std::auto_ptr<_Tp>& __r)
144
        : _M_pi(new _Sp_counted_base_impl<_Tp*,
145
                _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
146
        { __r.release(); }
147
 
148
      // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
149
      explicit
150
      __shared_count(const __weak_count<_Lp>& __r);
151
 
152
      ~__shared_count() // nothrow
153
      {
154
        if (_M_pi != 0)
155
          _M_pi->_M_release();
156
      }
157
 
158
      __shared_count(const __shared_count& __r)
159
      : _M_pi(__r._M_pi) // nothrow
160
      {
161
        if (_M_pi != 0)
162
          _M_pi->_M_add_ref_copy();
163
      }
164
 
165
      __shared_count&
166
      operator=(const __shared_count& __r) // nothrow
167
      {
168
        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
169
        if (__tmp != _M_pi)
170
          {
171
            if (__tmp != 0)
172
              __tmp->_M_add_ref_copy();
173
            if (_M_pi != 0)
174
              _M_pi->_M_release();
175
            _M_pi = __tmp;
176
          }
177
        return *this;
178
      }
179
 
180
      void
181
      _M_swap(__shared_count& __r) // nothrow
182
      {
183
        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
184
        __r._M_pi = _M_pi;
185
        _M_pi = __tmp;
186
      }
187
 
188
      long
189
      _M_get_use_count() const // nothrow
190
      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
191
 
192
      bool
193
      _M_unique() const // nothrow
194
      { return this->_M_get_use_count() == 1; }
195
 
196
      friend inline bool
197
      operator==(const __shared_count& __a, const __shared_count& __b)
198
      { return __a._M_pi == __b._M_pi; }
199
 
200
      friend inline bool
201
      operator<(const __shared_count& __a, const __shared_count& __b)
202
      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
203
 
204
      void*
205
      _M_get_deleter(const std::type_info& __ti) const
206
      { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
207
 
208
    private:
209
      friend class __weak_count<_Lp>;
210
 
211
      _Sp_counted_base<_Lp>*  _M_pi;
212
    };
213
 
214
 
215
  template<_Lock_policy _Lp>
216
    class __weak_count
217
    {
218
    public:
219
      __weak_count()
220
      : _M_pi(0) // nothrow
221
      { }
222
 
223
      __weak_count(const __shared_count<_Lp>& __r)
224
      : _M_pi(__r._M_pi) // nothrow
225
      {
226
        if (_M_pi != 0)
227
          _M_pi->_M_weak_add_ref();
228
      }
229
 
230
      __weak_count(const __weak_count<_Lp>& __r)
231
      : _M_pi(__r._M_pi) // nothrow
232
      {
233
        if (_M_pi != 0)
234
          _M_pi->_M_weak_add_ref();
235
      }
236
 
237
      ~__weak_count() // nothrow
238
      {
239
        if (_M_pi != 0)
240
          _M_pi->_M_weak_release();
241
      }
242
 
243
      __weak_count<_Lp>&
244
      operator=(const __shared_count<_Lp>& __r) // nothrow
245
      {
246
        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
247
        if (__tmp != 0)
248
          __tmp->_M_weak_add_ref();
249
        if (_M_pi != 0)
250
          _M_pi->_M_weak_release();
251
        _M_pi = __tmp;
252
        return *this;
253
      }
254
 
255
      __weak_count<_Lp>&
256
      operator=(const __weak_count<_Lp>& __r) // nothrow
257
      {
258
        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
259
        if (__tmp != 0)
260
          __tmp->_M_weak_add_ref();
261
        if (_M_pi != 0)
262
          _M_pi->_M_weak_release();
263
        _M_pi = __tmp;
264
        return *this;
265
      }
266
 
267
      void
268
      _M_swap(__weak_count<_Lp>& __r) // nothrow
269
      {
270
        _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
271
        __r._M_pi = _M_pi;
272
        _M_pi = __tmp;
273
      }
274
 
275
      long
276
      _M_get_use_count() const // nothrow
277
      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
278
 
279
      friend inline bool
280
      operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
281
      { return __a._M_pi == __b._M_pi; }
282
 
283
      friend inline bool
284
      operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
285
      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
286
 
287
    private:
288
      friend class __shared_count<_Lp>;
289
 
290
      _Sp_counted_base<_Lp>*  _M_pi;
291
    };
292
 
293
  // now that __weak_count is defined we can define this constructor:
294
  template<_Lock_policy _Lp>
295
    inline
296
    __shared_count<_Lp>::
297
    __shared_count(const __weak_count<_Lp>& __r)
298
    : _M_pi(__r._M_pi)
299
    {
300
      if (_M_pi != 0)
301
        _M_pi->_M_add_ref_lock();
302
      else
303
        __throw_bad_weak_ptr();
304
    }
305
 
306
  // Forward declarations.
307
  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
308
    class __shared_ptr;
309
 
310
  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
311
    class __weak_ptr;
312
 
313
  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
314
    class __enable_shared_from_this;
315
 
316
  template<typename _Tp>
317
    class shared_ptr;
318
 
319
  template<typename _Tp>
320
    class weak_ptr;
321
 
322
  template<typename _Tp>
323
    class enable_shared_from_this;
324
 
325
  // Support for enable_shared_from_this.
326
 
327
  // Friend of __enable_shared_from_this.
328
  template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
329
    void
330
    __enable_shared_from_this_helper(const __shared_count<_Lp>&,
331
                                     const __enable_shared_from_this<_Tp1,
332
                                     _Lp>*, const _Tp2*);
333
 
334
  // Friend of enable_shared_from_this.
335
  template<typename _Tp1, typename _Tp2>
336
    void
337
    __enable_shared_from_this_helper(const __shared_count<>&,
338
                                     const enable_shared_from_this<_Tp1>*,
339
                                     const _Tp2*);
340
 
341
  template<_Lock_policy _Lp>
342
    inline void
343
    __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
344
    { }
345
 
346
 
347
  struct __static_cast_tag { };
348
  struct __const_cast_tag { };
349
  struct __dynamic_cast_tag { };
350
 
351
  // A smart pointer with reference-counted copy semantics.  The
352
  // object pointed to is deleted when the last shared_ptr pointing to
353
  // it is destroyed or reset.
354
  template<typename _Tp, _Lock_policy _Lp>
355
    class __shared_ptr
356
    {
357
    public:
358
      typedef _Tp   element_type;
359
 
360
      __shared_ptr()
361
      : _M_ptr(0), _M_refcount() // never throws
362
      { }
363
 
364
      template<typename _Tp1>
365
        explicit
366
        __shared_ptr(_Tp1* __p)
367
        : _M_ptr(__p), _M_refcount(__p)
368
        {
369
          __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
370
          // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
371
          __enable_shared_from_this_helper(_M_refcount, __p, __p);
372
        }
373
 
374
      template<typename _Tp1, typename _Deleter>
375
        __shared_ptr(_Tp1* __p, _Deleter __d)
376
        : _M_ptr(__p), _M_refcount(__p, __d)
377
        {
378
          __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
379
          // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
380
          __enable_shared_from_this_helper(_M_refcount, __p, __p);
381
        }
382
 
383
      //  generated copy constructor, assignment, destructor are fine.
384
 
385
      template<typename _Tp1>
386
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
387
        : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
388
        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
389
 
390
      template<typename _Tp1>
391
        explicit
392
        __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
393
        : _M_refcount(__r._M_refcount) // may throw
394
        {
395
          __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
396
          // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
397
          // did not throw.
398
          _M_ptr = __r._M_ptr;
399
        }
400
 
401
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
402
      // Postcondition: use_count() == 1 and __r.get() == 0
403
      template<typename _Tp1>
404
        explicit
405
        __shared_ptr(std::auto_ptr<_Tp1>& __r)
406
        : _M_ptr(__r.get()), _M_refcount()
407
        {
408
          __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
409
          // TODO requires _Tp1 is complete, delete __r.release() well-formed
410
          _Tp1* __tmp = __r.get();
411
          _M_refcount = __shared_count<_Lp>(__r);
412
          __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
413
        }
414
 
415
#endif
416
 
417
      template<typename _Tp1>
418
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
419
        : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
420
          _M_refcount(__r._M_refcount)
421
        { }
422
 
423
      template<typename _Tp1>
424
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
425
        : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
426
          _M_refcount(__r._M_refcount)
427
        { }
428
 
429
      template<typename _Tp1>
430
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
431
        : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
432
          _M_refcount(__r._M_refcount)
433
        {
434
          if (_M_ptr == 0) // need to allocate new counter -- the cast failed
435
            _M_refcount = __shared_count<_Lp>();
436
        }
437
 
438
      template<typename _Tp1>
439
        __shared_ptr&
440
        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
441
        {
442
          _M_ptr = __r._M_ptr;
443
          _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
444
          return *this;
445
        }
446
 
447
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
448
      template<typename _Tp1>
449
        __shared_ptr&
450
        operator=(std::auto_ptr<_Tp1>& __r)
451
        {
452
          __shared_ptr(__r).swap(*this);
453
          return *this;
454
        }
455
#endif
456
 
457
      void
458
      reset() // never throws
459
      { __shared_ptr().swap(*this); }
460
 
461
      template<typename _Tp1>
462
        void
463
        reset(_Tp1* __p) // _Tp1 must be complete.
464
        {
465
          // Catch self-reset errors.
466
          _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
467
          __shared_ptr(__p).swap(*this);
468
        }
469
 
470
      template<typename _Tp1, typename _Deleter>
471
        void
472
        reset(_Tp1* __p, _Deleter __d)
473
        { __shared_ptr(__p, __d).swap(*this); }
474
 
475
      // Allow class instantiation when _Tp is [cv-qual] void.
476
      typename std::tr1::add_reference<_Tp>::type
477
      operator*() const // never throws
478
      {
479
        _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
480
        return *_M_ptr;
481
      }
482
 
483
      _Tp*
484
      operator->() const // never throws
485
      {
486
        _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
487
        return _M_ptr;
488
      }
489
 
490
      _Tp*
491
      get() const // never throws
492
      { return _M_ptr; }
493
 
494
      // Implicit conversion to "bool"
495
    private:
496
      typedef _Tp* __shared_ptr::*__unspecified_bool_type;
497
 
498
    public:
499
      operator __unspecified_bool_type() const // never throws
500
      { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
501
 
502
      bool
503
      unique() const // never throws
504
      { return _M_refcount._M_unique(); }
505
 
506
      long
507
      use_count() const // never throws
508
      { return _M_refcount._M_get_use_count(); }
509
 
510
      void
511
      swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
512
      {
513
        std::swap(_M_ptr, __other._M_ptr);
514
        _M_refcount._M_swap(__other._M_refcount);
515
      }
516
 
517
    private:
518
      void*
519
      _M_get_deleter(const std::type_info& __ti) const
520
      { return _M_refcount._M_get_deleter(__ti); }
521
 
522
      template<typename _Tp1, _Lock_policy _Lp1>
523
        bool
524
        _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
525
        { return _M_refcount < __rhs._M_refcount; }
526
 
527
      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
528
      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
529
 
530
      template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
531
        friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
532
 
533
      // Friends injected into enclosing namespace and found by ADL:
534
      template<typename _Tp1>
535
        friend inline bool
536
        operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
537
        { return __a.get() == __b.get(); }
538
 
539
      template<typename _Tp1>
540
        friend inline bool
541
        operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
542
        { return __a.get() != __b.get(); }
543
 
544
      template<typename _Tp1>
545
        friend inline bool
546
        operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
547
        { return __a._M_less(__b); }
548
 
549
      _Tp*                 _M_ptr;         // Contained pointer.
550
      __shared_count<_Lp>  _M_refcount;    // Reference counter.
551
    };
552
 
553
  // 2.2.3.8 shared_ptr specialized algorithms.
554
  template<typename _Tp, _Lock_policy _Lp>
555
    inline void
556
    swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
557
    { __a.swap(__b); }
558
 
559
  // 2.2.3.9 shared_ptr casts
560
  /*  The seemingly equivalent
561
   *           shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
562
   *  will eventually result in undefined behaviour,
563
   *  attempting to delete the same object twice.
564
   */
565
  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
566
    inline __shared_ptr<_Tp, _Lp>
567
    static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
568
    { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
569
 
570
  /*  The seemingly equivalent
571
   *           shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
572
   *  will eventually result in undefined behaviour,
573
   *  attempting to delete the same object twice.
574
   */
575
  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
576
    inline __shared_ptr<_Tp, _Lp>
577
    const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
578
    { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
579
 
580
  /*  The seemingly equivalent
581
   *           shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
582
   *  will eventually result in undefined behaviour,
583
   *  attempting to delete the same object twice.
584
   */
585
  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
586
    inline __shared_ptr<_Tp, _Lp>
587
    dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
588
    { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
589
 
590
  // 2.2.3.7 shared_ptr I/O
591
  template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
592
    std::basic_ostream<_Ch, _Tr>&
593
    operator<<(std::basic_ostream<_Ch, _Tr>& __os,
594
               const __shared_ptr<_Tp, _Lp>& __p)
595
    {
596
      __os << __p.get();
597
      return __os;
598
    }
599
 
600
  // 2.2.3.10 shared_ptr get_deleter (experimental)
601
  template<typename _Del, typename _Tp, _Lock_policy _Lp>
602
    inline _Del*
603
    get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
604
    {
605
#ifdef __GXX_RTTI
606
      return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
607
#else
608
      return 0;
609
#endif
610
    }
611
 
612
 
613
  template<typename _Tp, _Lock_policy _Lp>
614
    class __weak_ptr
615
    {
616
    public:
617
      typedef _Tp element_type;
618
 
619
      __weak_ptr()
620
      : _M_ptr(0), _M_refcount() // never throws
621
      { }
622
 
623
      // Generated copy constructor, assignment, destructor are fine.
624
 
625
      // The "obvious" converting constructor implementation:
626
      //
627
      //  template<typename _Tp1>
628
      //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
629
      //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
630
      //    { }
631
      //
632
      // has a serious problem.
633
      //
634
      //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
635
      //  conversion may require access to *__r._M_ptr (virtual inheritance).
636
      //
637
      // It is not possible to avoid spurious access violations since
638
      // in multithreaded programs __r._M_ptr may be invalidated at any point.
639
      template<typename _Tp1>
640
        __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
641
        : _M_refcount(__r._M_refcount) // never throws
642
        {
643
          __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
644
          _M_ptr = __r.lock().get();
645
        }
646
 
647
      template<typename _Tp1>
648
        __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
649
        : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
650
        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
651
 
652
      template<typename _Tp1>
653
        __weak_ptr&
654
        operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
655
        {
656
          _M_ptr = __r.lock().get();
657
          _M_refcount = __r._M_refcount;
658
          return *this;
659
        }
660
 
661
      template<typename _Tp1>
662
        __weak_ptr&
663
        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
664
        {
665
          _M_ptr = __r._M_ptr;
666
          _M_refcount = __r._M_refcount;
667
          return *this;
668
        }
669
 
670
      __shared_ptr<_Tp, _Lp>
671
      lock() const // never throws
672
      {
673
#ifdef __GTHREADS
674
        // Optimization: avoid throw overhead.
675
        if (expired())
676
          return __shared_ptr<element_type, _Lp>();
677
 
678
        __try
679
          {
680
            return __shared_ptr<element_type, _Lp>(*this);
681
          }
682
        __catch(const bad_weak_ptr&)
683
          {
684
            // Q: How can we get here?
685
            // A: Another thread may have invalidated r after the
686
            //    use_count test above.
687
            return __shared_ptr<element_type, _Lp>();
688
          }
689
 
690
#else
691
        // Optimization: avoid try/catch overhead when single threaded.
692
        return expired() ? __shared_ptr<element_type, _Lp>()
693
                         : __shared_ptr<element_type, _Lp>(*this);
694
 
695
#endif
696
      } // XXX MT
697
 
698
      long
699
      use_count() const // never throws
700
      { return _M_refcount._M_get_use_count(); }
701
 
702
      bool
703
      expired() const // never throws
704
      { return _M_refcount._M_get_use_count() == 0; }
705
 
706
      void
707
      reset() // never throws
708
      { __weak_ptr().swap(*this); }
709
 
710
      void
711
      swap(__weak_ptr& __s) // never throws
712
      {
713
        std::swap(_M_ptr, __s._M_ptr);
714
        _M_refcount._M_swap(__s._M_refcount);
715
      }
716
 
717
    private:
718
      // Used by __enable_shared_from_this.
719
      void
720
      _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
721
      {
722
        _M_ptr = __ptr;
723
        _M_refcount = __refcount;
724
      }
725
 
726
      template<typename _Tp1>
727
        bool
728
        _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
729
        { return _M_refcount < __rhs._M_refcount; }
730
 
731
      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
732
      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
733
      friend class __enable_shared_from_this<_Tp, _Lp>;
734
      friend class enable_shared_from_this<_Tp>;
735
 
736
      // Friend injected into namespace and found by ADL.
737
      template<typename _Tp1>
738
        friend inline bool
739
        operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
740
        { return __lhs._M_less(__rhs); }
741
 
742
      _Tp*               _M_ptr;         // Contained pointer.
743
      __weak_count<_Lp>  _M_refcount;    // Reference counter.
744
    };
745
 
746
  // 2.2.4.7 weak_ptr specialized algorithms.
747
  template<typename _Tp, _Lock_policy _Lp>
748
    inline void
749
    swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
750
    { __a.swap(__b); }
751
 
752
 
753
  template<typename _Tp, _Lock_policy _Lp>
754
    class __enable_shared_from_this
755
    {
756
    protected:
757
      __enable_shared_from_this() { }
758
 
759
      __enable_shared_from_this(const __enable_shared_from_this&) { }
760
 
761
      __enable_shared_from_this&
762
      operator=(const __enable_shared_from_this&)
763
      { return *this; }
764
 
765
      ~__enable_shared_from_this() { }
766
 
767
    public:
768
      __shared_ptr<_Tp, _Lp>
769
      shared_from_this()
770
      { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
771
 
772
      __shared_ptr<const _Tp, _Lp>
773
      shared_from_this() const
774
      { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
775
 
776
    private:
777
      template<typename _Tp1>
778
        void
779
        _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
780
        { _M_weak_this._M_assign(__p, __n); }
781
 
782
      template<typename _Tp1>
783
        friend void
784
        __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
785
                                         const __enable_shared_from_this* __pe,
786
                                         const _Tp1* __px)
787
        {
788
          if (__pe != 0)
789
            __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
790
        }
791
 
792
      mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
793
    };
794
 
795
 
796
  // The actual shared_ptr, with forwarding constructors and
797
  // assignment operators.
798
  template<typename _Tp>
799
    class shared_ptr
800
    : public __shared_ptr<_Tp>
801
    {
802
    public:
803
      shared_ptr()
804
      : __shared_ptr<_Tp>() { }
805
 
806
      template<typename _Tp1>
807
        explicit
808
        shared_ptr(_Tp1* __p)
809
        : __shared_ptr<_Tp>(__p) { }
810
 
811
      template<typename _Tp1, typename _Deleter>
812
        shared_ptr(_Tp1* __p, _Deleter __d)
813
        : __shared_ptr<_Tp>(__p, __d) { }
814
 
815
      template<typename _Tp1>
816
        shared_ptr(const shared_ptr<_Tp1>& __r)
817
        : __shared_ptr<_Tp>(__r) { }
818
 
819
      template<typename _Tp1>
820
        explicit
821
        shared_ptr(const weak_ptr<_Tp1>& __r)
822
        : __shared_ptr<_Tp>(__r) { }
823
 
824
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
825
      template<typename _Tp1>
826
        explicit
827
        shared_ptr(std::auto_ptr<_Tp1>& __r)
828
        : __shared_ptr<_Tp>(__r) { }
829
#endif
830
 
831
      template<typename _Tp1>
832
        shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
833
        : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
834
 
835
      template<typename _Tp1>
836
        shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
837
        : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
838
 
839
      template<typename _Tp1>
840
        shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
841
        : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
842
 
843
      template<typename _Tp1>
844
        shared_ptr&
845
        operator=(const shared_ptr<_Tp1>& __r) // never throws
846
        {
847
          this->__shared_ptr<_Tp>::operator=(__r);
848
          return *this;
849
        }
850
 
851
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
852
      template<typename _Tp1>
853
        shared_ptr&
854
        operator=(std::auto_ptr<_Tp1>& __r)
855
        {
856
          this->__shared_ptr<_Tp>::operator=(__r);
857
          return *this;
858
        }
859
#endif
860
    };
861
 
862
  // 2.2.3.8 shared_ptr specialized algorithms.
863
  template<typename _Tp>
864
    inline void
865
    swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
866
    { __a.swap(__b); }
867
 
868
  template<typename _Tp, typename _Tp1>
869
    inline shared_ptr<_Tp>
870
    static_pointer_cast(const shared_ptr<_Tp1>& __r)
871
    { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
872
 
873
  template<typename _Tp, typename _Tp1>
874
    inline shared_ptr<_Tp>
875
    const_pointer_cast(const shared_ptr<_Tp1>& __r)
876
    { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
877
 
878
  template<typename _Tp, typename _Tp1>
879
    inline shared_ptr<_Tp>
880
    dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
881
    { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
882
 
883
 
884
  // The actual weak_ptr, with forwarding constructors and
885
  // assignment operators.
886
  template<typename _Tp>
887
    class weak_ptr
888
    : public __weak_ptr<_Tp>
889
    {
890
    public:
891
      weak_ptr()
892
      : __weak_ptr<_Tp>() { }
893
 
894
      template<typename _Tp1>
895
        weak_ptr(const weak_ptr<_Tp1>& __r)
896
        : __weak_ptr<_Tp>(__r) { }
897
 
898
      template<typename _Tp1>
899
        weak_ptr(const shared_ptr<_Tp1>& __r)
900
        : __weak_ptr<_Tp>(__r) { }
901
 
902
      template<typename _Tp1>
903
        weak_ptr&
904
        operator=(const weak_ptr<_Tp1>& __r) // never throws
905
        {
906
          this->__weak_ptr<_Tp>::operator=(__r);
907
          return *this;
908
        }
909
 
910
      template<typename _Tp1>
911
        weak_ptr&
912
        operator=(const shared_ptr<_Tp1>& __r) // never throws
913
        {
914
          this->__weak_ptr<_Tp>::operator=(__r);
915
          return *this;
916
        }
917
 
918
      shared_ptr<_Tp>
919
      lock() const // never throws
920
      {
921
#ifdef __GTHREADS
922
        if (this->expired())
923
          return shared_ptr<_Tp>();
924
 
925
        __try
926
          {
927
            return shared_ptr<_Tp>(*this);
928
          }
929
        __catch(const bad_weak_ptr&)
930
          {
931
            return shared_ptr<_Tp>();
932
          }
933
#else
934
        return this->expired() ? shared_ptr<_Tp>()
935
                               : shared_ptr<_Tp>(*this);
936
#endif
937
      }
938
    };
939
 
940
  template<typename _Tp>
941
    class enable_shared_from_this
942
    {
943
    protected:
944
      enable_shared_from_this() { }
945
 
946
      enable_shared_from_this(const enable_shared_from_this&) { }
947
 
948
      enable_shared_from_this&
949
      operator=(const enable_shared_from_this&)
950
      { return *this; }
951
 
952
      ~enable_shared_from_this() { }
953
 
954
    public:
955
      shared_ptr<_Tp>
956
      shared_from_this()
957
      { return shared_ptr<_Tp>(this->_M_weak_this); }
958
 
959
      shared_ptr<const _Tp>
960
      shared_from_this() const
961
      { return shared_ptr<const _Tp>(this->_M_weak_this); }
962
 
963
    private:
964
      template<typename _Tp1>
965
        void
966
        _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
967
        { _M_weak_this._M_assign(__p, __n); }
968
 
969
      template<typename _Tp1>
970
        friend void
971
        __enable_shared_from_this_helper(const __shared_count<>& __pn,
972
                                         const enable_shared_from_this* __pe,
973
                                         const _Tp1* __px)
974
        {
975
          if (__pe != 0)
976
            __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
977
        }
978
 
979
      mutable weak_ptr<_Tp>  _M_weak_this;
980
    };
981
}
982
}
983
 
984
#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.