OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [bits/] [shared_ptr_base.h] - Blame information for rev 628

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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