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