Changeset 51581


Ignore:
Timestamp:
Mar 3, 2009, 7:25:26 PM (9 years ago)
Author:
Peter Dimov
Message:

Fix enable_shared_from_this-related tickets in trunk. Refs #2126. Refs #2584.

Location:
trunk
Files:
4 added
2 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/boost/smart_ptr/enable_shared_from_this.hpp

    r51509 r51581  
    55//  enable_shared_from_this.hpp
    66//
    7 //  Copyright (c) 2002 Peter Dimov
     7//  Copyright 2002, 2009 Peter Dimov
    88//
    9 // Distributed under the Boost Software License, Version 1.0. (See
    10 // accompanying file LICENSE_1_0.txt or copy at
    11 // http://www.boost.org/LICENSE_1_0.txt)
     9//  Distributed under the Boost Software License, Version 1.0.
     10//  See accompanying file LICENSE_1_0.txt or copy at
     11//  http://www.boost.org/LICENSE_1_0.txt
    1212//
    1313//  http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
     
    4747    shared_ptr<T> shared_from_this()
    4848    {
    49         shared_ptr<T> p(_internal_weak_this);
    50         BOOST_ASSERT(p.get() == this);
     49        shared_ptr<T> p( weak_this_ );
     50        BOOST_ASSERT( p.get() == this );
    5151        return p;
    5252    }
     
    5454    shared_ptr<T const> shared_from_this() const
    5555    {
    56         shared_ptr<T const> p(_internal_weak_this);
    57         BOOST_ASSERT(p.get() == this);
     56        shared_ptr<T const> p( weak_this_ );
     57        BOOST_ASSERT( p.get() == this );
    5858        return p;
    5959    }
    6060
    61 //  Note: No, you don't need to initialize _internal_weak_this
    62 //
    63 //  Please read the documentation, not the code
    64 //
    65 //  http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
     61public: // actually private, but avoids compiler template friendship issues
    6662
    67     typedef T _internal_element_type; // for bcc 5.5.1
    68     mutable weak_ptr<_internal_element_type> _internal_weak_this;
     63    // Note: invoked automatically by shared_ptr; do not call
     64    template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
     65    {
     66        if( weak_this_.expired() )
     67        {
     68            weak_this_ = shared_ptr<T>( *ppx, py );
     69        }
     70    }
     71
     72private:
     73
     74    mutable weak_ptr<T> weak_this_;
    6975};
    7076
  • trunk/boost/smart_ptr/make_shared.hpp

    r51516 r51581  
    106106    void * pv = pd->address();
    107107
    108     new( pv ) T();
    109     pd->set_initialized();
    110 
    111     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     108    ::new( pv ) T();
     109    pd->set_initialized();
     110
     111    T * pt2 = static_cast< T* >( pv );
     112
     113    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     114    return boost::shared_ptr< T >( pt, pt2 );
    112115}
    113116
     
    120123    void * pv = pd->address();
    121124
    122     new( pv ) T();
    123     pd->set_initialized();
    124 
    125     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     125    ::new( pv ) T();
     126    pd->set_initialized();
     127
     128    T * pt2 = static_cast< T* >( pv );
     129
     130    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     131    return boost::shared_ptr< T >( pt, pt2 );
    126132}
    127133
     
    138144    void * pv = pd->address();
    139145
    140     new( pv ) T( detail::forward<Args>( args )... );
    141     pd->set_initialized();
    142 
    143     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     146    ::new( pv ) T( detail::forward<Args>( args )... );
     147    pd->set_initialized();
     148
     149    T * pt2 = static_cast< T* >( pv );
     150
     151    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     152    return boost::shared_ptr< T >( pt, pt2 );
    144153}
    145154
     
    152161    void * pv = pd->address();
    153162
    154     new( pv ) T( detail::forward<Args>( args )... );
    155     pd->set_initialized();
    156 
    157     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     163    ::new( pv ) T( detail::forward<Args>( args )... );
     164    pd->set_initialized();
     165
     166    T * pt2 = static_cast< T* >( pv );
     167
     168    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     169    return boost::shared_ptr< T >( pt, pt2 );
    158170}
    159171
     
    171183    void * pv = pd->address();
    172184
    173     new( pv ) T( a1 );
    174     pd->set_initialized();
    175 
    176     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     185    ::new( pv ) T( a1 );
     186    pd->set_initialized();
     187
     188    T * pt2 = static_cast< T* >( pv );
     189
     190    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     191    return boost::shared_ptr< T >( pt, pt2 );
    177192}
    178193
     
    186201    void * pv = pd->address();
    187202
    188     new( pv ) T( a1 );
    189     pd->set_initialized();
    190 
    191     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     203    ::new( pv ) T( a1 );
     204    pd->set_initialized();
     205
     206    T * pt2 = static_cast< T* >( pv );
     207
     208    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     209    return boost::shared_ptr< T >( pt, pt2 );
    192210}
    193211
     
    201219    void * pv = pd->address();
    202220
    203     new( pv ) T( a1, a2 );
    204     pd->set_initialized();
    205 
    206     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     221    ::new( pv ) T( a1, a2 );
     222    pd->set_initialized();
     223
     224    T * pt2 = static_cast< T* >( pv );
     225
     226    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     227    return boost::shared_ptr< T >( pt, pt2 );
    207228}
    208229
     
    216237    void * pv = pd->address();
    217238
    218     new( pv ) T( a1, a2 );
    219     pd->set_initialized();
    220 
    221     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     239    ::new( pv ) T( a1, a2 );
     240    pd->set_initialized();
     241
     242    T * pt2 = static_cast< T* >( pv );
     243
     244    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     245    return boost::shared_ptr< T >( pt, pt2 );
    222246}
    223247
     
    231255    void * pv = pd->address();
    232256
    233     new( pv ) T( a1, a2, a3 );
    234     pd->set_initialized();
    235 
    236     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     257    ::new( pv ) T( a1, a2, a3 );
     258    pd->set_initialized();
     259
     260    T * pt2 = static_cast< T* >( pv );
     261
     262    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     263    return boost::shared_ptr< T >( pt, pt2 );
    237264}
    238265
     
    246273    void * pv = pd->address();
    247274
    248     new( pv ) T( a1, a2, a3 );
    249     pd->set_initialized();
    250 
    251     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     275    ::new( pv ) T( a1, a2, a3 );
     276    pd->set_initialized();
     277
     278    T * pt2 = static_cast< T* >( pv );
     279
     280    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     281    return boost::shared_ptr< T >( pt, pt2 );
    252282}
    253283
     
    261291    void * pv = pd->address();
    262292
    263     new( pv ) T( a1, a2, a3, a4 );
    264     pd->set_initialized();
    265 
    266     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     293    ::new( pv ) T( a1, a2, a3, a4 );
     294    pd->set_initialized();
     295
     296    T * pt2 = static_cast< T* >( pv );
     297
     298    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     299    return boost::shared_ptr< T >( pt, pt2 );
    267300}
    268301
     
    276309    void * pv = pd->address();
    277310
    278     new( pv ) T( a1, a2, a3, a4 );
    279     pd->set_initialized();
    280 
    281     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     311    ::new( pv ) T( a1, a2, a3, a4 );
     312    pd->set_initialized();
     313
     314    T * pt2 = static_cast< T* >( pv );
     315
     316    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     317    return boost::shared_ptr< T >( pt, pt2 );
    282318}
    283319
     
    291327    void * pv = pd->address();
    292328
    293     new( pv ) T( a1, a2, a3, a4, a5 );
    294     pd->set_initialized();
    295 
    296     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     329    ::new( pv ) T( a1, a2, a3, a4, a5 );
     330    pd->set_initialized();
     331
     332    T * pt2 = static_cast< T* >( pv );
     333
     334    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     335    return boost::shared_ptr< T >( pt, pt2 );
    297336}
    298337
     
    306345    void * pv = pd->address();
    307346
    308     new( pv ) T( a1, a2, a3, a4, a5 );
    309     pd->set_initialized();
    310 
    311     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     347    ::new( pv ) T( a1, a2, a3, a4, a5 );
     348    pd->set_initialized();
     349
     350    T * pt2 = static_cast< T* >( pv );
     351
     352    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     353    return boost::shared_ptr< T >( pt, pt2 );
    312354}
    313355
     
    321363    void * pv = pd->address();
    322364
    323     new( pv ) T( a1, a2, a3, a4, a5, a6 );
    324     pd->set_initialized();
    325 
    326     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     365    ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
     366    pd->set_initialized();
     367
     368    T * pt2 = static_cast< T* >( pv );
     369
     370    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     371    return boost::shared_ptr< T >( pt, pt2 );
    327372}
    328373
     
    336381    void * pv = pd->address();
    337382
    338     new( pv ) T( a1, a2, a3, a4, a5, a6 );
    339     pd->set_initialized();
    340 
    341     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     383    ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
     384    pd->set_initialized();
     385
     386    T * pt2 = static_cast< T* >( pv );
     387
     388    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     389    return boost::shared_ptr< T >( pt, pt2 );
    342390}
    343391
     
    351399    void * pv = pd->address();
    352400
    353     new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
    354     pd->set_initialized();
    355 
    356     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     401    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
     402    pd->set_initialized();
     403
     404    T * pt2 = static_cast< T* >( pv );
     405
     406    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     407    return boost::shared_ptr< T >( pt, pt2 );
    357408}
    358409
     
    366417    void * pv = pd->address();
    367418
    368     new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
    369     pd->set_initialized();
    370 
    371     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     419    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
     420    pd->set_initialized();
     421
     422    T * pt2 = static_cast< T* >( pv );
     423
     424    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     425    return boost::shared_ptr< T >( pt, pt2 );
    372426}
    373427
     
    381435    void * pv = pd->address();
    382436
    383     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
    384     pd->set_initialized();
    385 
    386     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     437    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
     438    pd->set_initialized();
     439
     440    T * pt2 = static_cast< T* >( pv );
     441
     442    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     443    return boost::shared_ptr< T >( pt, pt2 );
    387444}
    388445
     
    396453    void * pv = pd->address();
    397454
    398     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
    399     pd->set_initialized();
    400 
    401     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     455    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
     456    pd->set_initialized();
     457
     458    T * pt2 = static_cast< T* >( pv );
     459
     460    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     461    return boost::shared_ptr< T >( pt, pt2 );
    402462}
    403463
     
    411471    void * pv = pd->address();
    412472
    413     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
    414     pd->set_initialized();
    415 
    416     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     473    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
     474    pd->set_initialized();
     475
     476    T * pt2 = static_cast< T* >( pv );
     477
     478    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     479    return boost::shared_ptr< T >( pt, pt2 );
    417480}
    418481
     
    426489    void * pv = pd->address();
    427490
    428     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
    429     pd->set_initialized();
    430 
    431     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
     491    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
     492    pd->set_initialized();
     493
     494    T * pt2 = static_cast< T* >( pv );
     495
     496    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
     497    return boost::shared_ptr< T >( pt, pt2 );
    432498}
    433499
  • trunk/boost/smart_ptr/shared_ptr.hpp

    r51518 r51581  
    5959{
    6060
     61template<class T> class shared_ptr;
    6162template<class T> class weak_ptr;
    6263template<class T> class enable_shared_from_this;
     
    101102// enable_shared_from_this support
    102103
    103 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 )
    104 {
    105     if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
     104template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
     105{
     106    if( pe != 0 )
     107    {
     108        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
     109    }
    106110}
    107111
     
    115119};
    116120
    117 inline void sp_enable_shared_from_this( shared_count const & /*pn*/, sp_any_pointer, sp_any_pointer )
     121inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
    118122{
    119123}
     
    121125#else // _MANAGED
    122126
    123 #ifdef sgi
    124 // Turn off: the last argument of the varargs function "sp_enable_shared_from_this" is unnamed
    125 # pragma set woff 3506
    126 #endif
    127 
    128 inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
    129 {
    130 }
    131 
    132 #ifdef sgi
    133 # pragma reset woff 3506
    134 #endif
     127inline void sp_enable_shared_from_this( ... )
     128{
     129}
    135130
    136131#endif // _MANAGED
     
    183178    explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
    184179    {
    185         boost::detail::sp_enable_shared_from_this( pn, p, p );
     180        boost::detail::sp_enable_shared_from_this( this, p, p );
    186181    }
    187182
     
    194189    template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
    195190    {
    196         boost::detail::sp_enable_shared_from_this( pn, p, p );
     191        boost::detail::sp_enable_shared_from_this( this, p, p );
    197192    }
    198193
     
    201196    template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
    202197    {
    203         boost::detail::sp_enable_shared_from_this( pn, p, p );
     198        boost::detail::sp_enable_shared_from_this( this, p, p );
    204199    }
    205200
     
    289284        Y * tmp = r.get();
    290285        pn = boost::detail::shared_count(r);
    291         boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
     286        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
    292287    }
    293288
     
    299294        typename Ap::element_type * tmp = r.get();
    300295        pn = boost::detail::shared_count( r );
    301         boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
     296        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
    302297    }
    303298
  • trunk/libs/smart_ptr/test/Jamfile.v2

    r51486 r51581  
    4949          [ run allocate_shared_test.cpp ]
    5050          [ run sp_atomic_test.cpp ]
     51          [ run esft_void_test.cpp ]
     52          [ run esft_second_ptr_test.cpp ]
     53          [ run make_shared_esft_test.cpp ]
     54          [ run allocate_shared_esft_test.cpp ]
    5155        ;
    5256}
  • trunk/libs/smart_ptr/test/allocate_shared_test.cpp

    r45085 r51581  
    1111#include <boost/shared_ptr.hpp>
    1212#include <boost/weak_ptr.hpp>
     13#include <cstddef>
    1314
    1415class X
     
    1819    X( X const & );
    1920    X & operator=( X const & );
     21
     22    void * operator new( std::size_t );
     23
     24    void operator delete( void * p )
     25    {
     26        // lack of this definition causes link errors on MSVC
     27        ::operator delete( p );
     28    }
    2029
    2130public:
  • trunk/libs/smart_ptr/test/make_shared_test.cpp

    r45085 r51581  
    1111#include <boost/shared_ptr.hpp>
    1212#include <boost/weak_ptr.hpp>
     13#include <cstddef>
    1314
    1415class X
     
    1819    X( X const & );
    1920    X & operator=( X const & );
     21
     22    void * operator new( std::size_t );
     23
     24    void operator delete( void * p )
     25    {
     26        // lack of this definition causes link errors on MSVC
     27        ::operator delete( p );
     28    }
    2029
    2130public:
  • trunk/libs/smart_ptr/test/shared_from_this_test.cpp

    r43782 r51581  
    5656    BOOST_TEST(py.use_count() == 1);
    5757
    58     boost::shared_ptr<X> px = py->getX();
    59     BOOST_TEST(px.get() != 0);
    60     BOOST_TEST(py.use_count() == 2);
     58    try
     59    {
     60        boost::shared_ptr<X> px = py->getX();
     61        BOOST_TEST(px.get() != 0);
     62        BOOST_TEST(py.use_count() == 2);
    6163
    62     px->f();
     64        px->f();
    6365
    64     boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px);
    65     BOOST_TEST(py.get() == py2.get());
    66     BOOST_TEST(!(py < py2 || py2 < py));
    67     BOOST_TEST(py.use_count() == 3);
     66        boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px);
     67        BOOST_TEST(py.get() == py2.get());
     68        BOOST_TEST(!(py < py2 || py2 < py));
     69        BOOST_TEST(py.use_count() == 3);
     70    }
     71    catch( boost::bad_weak_ptr const& )
     72    {
     73        BOOST_ERROR( "py->getX() failed" );
     74    }
    6875}
    6976
     
    125132    boost::shared_ptr<V> p(new V);
    126133
    127     boost::shared_ptr<V> q = p->shared_from_this();
    128     BOOST_TEST(p == q);
    129     BOOST_TEST(!(p < q) && !(q < p));
     134    try
     135    {
     136        boost::shared_ptr<V> q = p->shared_from_this();
     137        BOOST_TEST(p == q);
     138        BOOST_TEST(!(p < q) && !(q < p));
     139    }
     140    catch( boost::bad_weak_ptr const & )
     141    {
     142        BOOST_ERROR( "p->shared_from_this() failed" );
     143    }
    130144
    131145    V v2(*p);
     
    134148    {
    135149        boost::shared_ptr<V> r = v2.shared_from_this();
    136         BOOST_TEST( p < r || r < p );
    137         BOOST_TEST( r.get() == &v2 );
     150        BOOST_ERROR("v2.shared_from_this() failed to throw");
    138151    }
    139     catch(boost::bad_weak_ptr const &)
     152    catch( boost::bad_weak_ptr const & )
    140153    {
    141154    }
     
    148161        BOOST_TEST(!(p < r) && !(r < p));
    149162    }
    150     catch(boost::bad_weak_ptr const &)
     163    catch( boost::bad_weak_ptr const & )
    151164    {
    152165        BOOST_ERROR("p->shared_from_this() threw bad_weak_ptr after *p = V()");
  • trunk/libs/smart_ptr/test/shared_ptr_move_test.cpp

    r37526 r51581  
    88// http://www.boost.org/LICENSE_1_0.txt
    99//
     10
     11#if defined( BOOST_HAS_RVALUE_REFS )
    1012
    1113#include <boost/shared_ptr.hpp>
     
    9496    return boost::report_errors();
    9597}
     98
     99#else // !defined( BOOST_HAS_RVALUE_REFS )
     100
     101int main()
     102{
     103    return 0;
     104}
     105
     106#endif
Note: See TracChangeset for help on using the changeset viewer.