~ubuntu-branches/ubuntu/trusty/aegisub/trusty

« back to all changes in this revision

Viewing changes to src/boost/shared_ptr.hpp

  • Committer: Package Import Robot
  • Author(s): Sebastian Reichel
  • Date: 2012-03-16 22:58:00 UTC
  • Revision ID: package-import@ubuntu.com-20120316225800-yfb8h9e5n04rk46a
Tags: upstream-2.1.9
ImportĀ upstreamĀ versionĀ 2.1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
 
2
#define BOOST_SHARED_PTR_HPP_INCLUDED
 
3
 
 
4
//
 
5
//  shared_ptr.hpp
 
6
//
 
7
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 
8
//  Copyright (c) 2001, 2002, 2003 Peter Dimov
 
9
//
 
10
//  Distributed under the Boost Software License, Version 1.0. (See
 
11
//  accompanying file LICENSE_1_0.txt or copy at
 
12
//  http://www.boost.org/LICENSE_1_0.txt)
 
13
//
 
14
//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
 
15
//
 
16
 
 
17
#include "assert.hpp"
 
18
#include "checked_delete.hpp"
 
19
#include "throw_exception.hpp"
 
20
#include "shared_count.hpp"
 
21
#include "workaround.hpp"
 
22
 
 
23
#include <memory>               // for std::auto_ptr
 
24
#include <algorithm>            // for std::swap
 
25
#include <functional>           // for std::less
 
26
#include <typeinfo>             // for std::bad_cast
 
27
#include <iosfwd>               // for std::basic_ostream
 
28
 
 
29
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
 
30
# pragma warning(push)
 
31
# pragma warning(disable:4284) // odd return type for operator->
 
32
#endif
 
33
 
 
34
namespace boost
 
35
{
 
36
 
 
37
template<class T> class weak_ptr;
 
38
template<class T> class enable_shared_from_this;
 
39
 
 
40
namespace detail
 
41
{
 
42
 
 
43
struct static_cast_tag {};
 
44
struct const_cast_tag {};
 
45
struct dynamic_cast_tag {};
 
46
struct polymorphic_cast_tag {};
 
47
 
 
48
template<class T> struct shared_ptr_traits
 
49
{
 
50
    typedef T & reference;
 
51
};
 
52
 
 
53
template<> struct shared_ptr_traits<void>
 
54
{
 
55
    typedef void reference;
 
56
};
 
57
 
 
58
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
 
59
 
 
60
template<> struct shared_ptr_traits<void const>
 
61
{
 
62
    typedef void reference;
 
63
};
 
64
 
 
65
template<> struct shared_ptr_traits<void volatile>
 
66
{
 
67
    typedef void reference;
 
68
};
 
69
 
 
70
template<> struct shared_ptr_traits<void const volatile>
 
71
{
 
72
    typedef void reference;
 
73
};
 
74
 
 
75
// enable_shared_from_this support
 
76
 
 
77
template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, boost::enable_shared_from_this<T> const * pe, Y const * px )
 
78
{
 
79
    if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
 
80
}
 
81
 
 
82
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
 
83
{
 
84
}
 
85
 
 
86
} // namespace detail
 
87
 
 
88
 
 
89
//
 
90
//  shared_ptr
 
91
//
 
92
//  An enhanced relative of scoped_ptr with reference counted copy semantics.
 
93
//  The object pointed to is deleted when the last shared_ptr pointing to it
 
94
//  is destroyed or reset.
 
95
//
 
96
 
 
97
template<class T> class shared_ptr
 
98
{
 
99
private:
 
100
 
 
101
    // Borland 5.5.1 specific workaround
 
102
    typedef shared_ptr<T> this_type;
 
103
 
 
104
public:
 
105
 
 
106
    typedef T element_type;
 
107
    typedef T value_type;
 
108
    typedef T * pointer;
 
109
    typedef typename detail::shared_ptr_traits<T>::reference reference;
 
110
 
 
111
    shared_ptr(): px(0), pn() // never throws in 1.30+
 
112
    {
 
113
    }
 
114
 
 
115
    template<class Y>
 
116
    explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete
 
117
    {
 
118
        detail::sp_enable_shared_from_this( pn, p, p );
 
119
    }
 
120
 
 
121
    //
 
122
    // Requirements: D's copy constructor must not throw
 
123
    //
 
124
    // shared_ptr will release p by calling d(p)
 
125
    //
 
126
 
 
127
    template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
 
128
    {
 
129
        detail::sp_enable_shared_from_this( pn, p, p );
 
130
    }
 
131
 
 
132
//  generated copy constructor, assignment, destructor are fine...
 
133
 
 
134
//  except that Borland C++ has a bug, and g++ with -Wsynth warns
 
135
#if defined(__BORLANDC__) || defined(__GNUC__)
 
136
 
 
137
    shared_ptr & operator=(shared_ptr const & r) // never throws
 
138
    {
 
139
        px = r.px;
 
140
        pn = r.pn; // shared_count::op= doesn't throw
 
141
        return *this;
 
142
    }
 
143
 
 
144
#endif
 
145
 
 
146
    template<class Y>
 
147
    explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
 
148
    {
 
149
        // it is now safe to copy r.px, as pn(r.pn) did not throw
 
150
        px = r.px;
 
151
    }
 
152
 
 
153
    template<class Y>
 
154
    shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
 
155
    {
 
156
    }
 
157
 
 
158
    template<class Y>
 
159
    shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
 
160
    {
 
161
    }
 
162
 
 
163
    template<class Y>
 
164
    shared_ptr(shared_ptr<Y> const & r, detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
 
165
    {
 
166
    }
 
167
 
 
168
    template<class Y>
 
169
    shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 
170
    {
 
171
        if(px == 0) // need to allocate new counter -- the cast failed
 
172
        {
 
173
            pn = detail::shared_count();
 
174
        }
 
175
    }
 
176
 
 
177
    template<class Y>
 
178
    shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 
179
    {
 
180
        if(px == 0)
 
181
        {
 
182
            boost::throw_exception(std::bad_cast());
 
183
        }
 
184
    }
 
185
 
 
186
#ifndef BOOST_NO_AUTO_PTR
 
187
 
 
188
    template<class Y>
 
189
    explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
 
190
    {
 
191
        Y * tmp = r.get();
 
192
        pn = detail::shared_count(r);
 
193
        detail::sp_enable_shared_from_this( pn, tmp, tmp );
 
194
    }
 
195
 
 
196
#endif
 
197
 
 
198
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
 
199
 
 
200
    template<class Y>
 
201
    shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
 
202
    {
 
203
        px = r.px;
 
204
        pn = r.pn; // shared_count::op= doesn't throw
 
205
        return *this;
 
206
    }
 
207
 
 
208
#endif
 
209
 
 
210
#ifndef BOOST_NO_AUTO_PTR
 
211
 
 
212
    template<class Y>
 
213
    shared_ptr & operator=(std::auto_ptr<Y> & r)
 
214
    {
 
215
        this_type(r).swap(*this);
 
216
        return *this;
 
217
    }
 
218
 
 
219
#endif
 
220
 
 
221
    void reset() // never throws in 1.30+
 
222
    {
 
223
        this_type().swap(*this);
 
224
    }
 
225
 
 
226
    template<class Y> void reset(Y * p) // Y must be complete
 
227
    {
 
228
        BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
 
229
        this_type(p).swap(*this);
 
230
    }
 
231
 
 
232
    template<class Y, class D> void reset(Y * p, D d)
 
233
    {
 
234
        this_type(p, d).swap(*this);
 
235
    }
 
236
 
 
237
    reference operator* () const // never throws
 
238
    {
 
239
        BOOST_ASSERT(px != 0);
 
240
        return *px;
 
241
    }
 
242
 
 
243
    T * operator-> () const // never throws
 
244
    {
 
245
        BOOST_ASSERT(px != 0);
 
246
        return px;
 
247
    }
 
248
    
 
249
    T * get() const // never throws
 
250
    {
 
251
        return px;
 
252
    }
 
253
 
 
254
    // implicit conversion to "bool"
 
255
 
 
256
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
 
257
 
 
258
    operator bool () const
 
259
    {
 
260
        return px != 0;
 
261
    }
 
262
 
 
263
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
 
264
    typedef T * (this_type::*unspecified_bool_type)() const;
 
265
    
 
266
    operator unspecified_bool_type() const // never throws
 
267
    {
 
268
        return px == 0? 0: &this_type::get;
 
269
    }
 
270
 
 
271
#else 
 
272
 
 
273
    typedef T * this_type::*unspecified_bool_type;
 
274
 
 
275
    operator unspecified_bool_type() const // never throws
 
276
    {
 
277
        return px == 0? 0: &this_type::px;
 
278
    }
 
279
 
 
280
#endif
 
281
 
 
282
    // operator! is redundant, but some compilers need it
 
283
 
 
284
    bool operator! () const // never throws
 
285
    {
 
286
        return px == 0;
 
287
    }
 
288
 
 
289
    bool unique() const // never throws
 
290
    {
 
291
        return pn.unique();
 
292
    }
 
293
 
 
294
    long use_count() const // never throws
 
295
    {
 
296
        return pn.use_count();
 
297
    }
 
298
 
 
299
    void swap(shared_ptr<T> & other) // never throws
 
300
    {
 
301
        std::swap(px, other.px);
 
302
        pn.swap(other.pn);
 
303
    }
 
304
 
 
305
    template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
 
306
    {
 
307
        return pn < rhs.pn;
 
308
    }
 
309
 
 
310
    void * _internal_get_deleter(std::type_info const & ti) const
 
311
    {
 
312
        return pn.get_deleter(ti);
 
313
    }
 
314
 
 
315
// Tasteless as this may seem, making all members public allows member templates
 
316
// to work in the absence of member template friends. (Matthew Langston)
 
317
 
 
318
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 
319
 
 
320
private:
 
321
 
 
322
    template<class Y> friend class shared_ptr;
 
323
    template<class Y> friend class weak_ptr;
 
324
 
 
325
 
 
326
#endif
 
327
 
 
328
    T * px;                     // contained pointer
 
329
    detail::shared_count pn;    // reference counter
 
330
 
 
331
};  // shared_ptr
 
332
 
 
333
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
 
334
{
 
335
    return a.get() == b.get();
 
336
}
 
337
 
 
338
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
 
339
{
 
340
    return a.get() != b.get();
 
341
}
 
342
 
 
343
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
 
344
 
 
345
// Resolve the ambiguity between our op!= and the one in rel_ops
 
346
 
 
347
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
 
348
{
 
349
    return a.get() != b.get();
 
350
}
 
351
 
 
352
#endif
 
353
 
 
354
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
 
355
{
 
356
    return a._internal_less(b);
 
357
}
 
358
 
 
359
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
 
360
{
 
361
    a.swap(b);
 
362
}
 
363
 
 
364
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
 
365
{
 
366
    return shared_ptr<T>(r, detail::static_cast_tag());
 
367
}
 
368
 
 
369
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
 
370
{
 
371
    return shared_ptr<T>(r, detail::const_cast_tag());
 
372
}
 
373
 
 
374
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
 
375
{
 
376
    return shared_ptr<T>(r, detail::dynamic_cast_tag());
 
377
}
 
378
 
 
379
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
 
380
 
 
381
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
 
382
{
 
383
    return shared_ptr<T>(r, detail::static_cast_tag());
 
384
}
 
385
 
 
386
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
 
387
{
 
388
    return shared_ptr<T>(r, detail::dynamic_cast_tag());
 
389
}
 
390
 
 
391
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
 
392
{
 
393
    return shared_ptr<T>(r, detail::polymorphic_cast_tag());
 
394
}
 
395
 
 
396
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
 
397
{
 
398
    BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
 
399
    return shared_static_cast<T>(r);
 
400
}
 
401
 
 
402
// get_pointer() enables boost::mem_fn to recognize shared_ptr
 
403
 
 
404
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
 
405
{
 
406
    return p.get();
 
407
}
 
408
 
 
409
// operator<<
 
410
 
 
411
#if defined(__GNUC__) &&  (__GNUC__ < 3)
 
412
 
 
413
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
 
414
{
 
415
    os << p.get();
 
416
    return os;
 
417
}
 
418
 
 
419
#else
 
420
 
 
421
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
 
422
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
 
423
using std::basic_ostream;
 
424
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
 
425
# else
 
426
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
 
427
# endif 
 
428
{
 
429
    os << p.get();
 
430
    return os;
 
431
}
 
432
 
 
433
#endif
 
434
 
 
435
// get_deleter (experimental)
 
436
 
 
437
#if (defined(__GNUC__) &&  (__GNUC__ < 3)) || (defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238))
 
438
 
 
439
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
 
440
// apparently EDG 2.38 also doesn't accept it
 
441
 
 
442
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 
443
{
 
444
    void const * q = p._internal_get_deleter(typeid(D));
 
445
    return const_cast<D *>(static_cast<D const *>(q));
 
446
}
 
447
 
 
448
#else
 
449
 
 
450
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 
451
{
 
452
    return static_cast<D *>(p._internal_get_deleter(typeid(D)));
 
453
}
 
454
 
 
455
#endif
 
456
 
 
457
} // namespace boost
 
458
 
 
459
#ifdef BOOST_MSVC
 
460
# pragma warning(pop)
 
461
#endif    
 
462
 
 
463
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 
464
 
 
465
#endif  // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED