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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [include/] [tr1/] [boost_shared_ptr.h] - Blame information for rev 17

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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