mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-10-05 04:01:04 +02:00
Compare commits
56 Commits
boost-1.56
...
boost-1.60
Author | SHA1 | Date | |
---|---|---|---|
|
4db7219c32 | ||
|
3f17244225 | ||
|
ca93749614 | ||
|
a06123eb87 | ||
|
df90496583 | ||
|
20ead68473 | ||
|
79cde147c9 | ||
|
abbe975e8f | ||
|
8ba0730686 | ||
|
686efe100b | ||
|
acb880d8c2 | ||
|
1712b87cb6 | ||
|
f8943703f8 | ||
|
a42dda0af4 | ||
|
9b9b6d3ca6 | ||
|
d875a68ceb | ||
|
8cb2c56556 | ||
|
290fe82a43 | ||
|
94824c807f | ||
|
0ab0e6eecc | ||
|
effc9f73d6 | ||
|
99762e7dde | ||
|
add539142b | ||
|
e067fd2cfd | ||
|
212528860a | ||
|
711c36958a | ||
|
7104e7dc7e | ||
|
254bda34b7 | ||
|
3fd53ced83 | ||
|
75de3dbcf1 | ||
|
7faec4265b | ||
|
c81d0806e4 | ||
|
a74329794c | ||
|
71756350d9 | ||
|
f65c57d9d2 | ||
|
b1fc261fe6 | ||
|
aedcf3ccda | ||
|
a1a5999a38 | ||
|
8afd3bee69 | ||
|
2a56c73924 | ||
|
720ce12a25 | ||
|
2be09db523 | ||
|
de10be8560 | ||
|
7b71068b52 | ||
|
6b562cb5b1 | ||
|
3d2c230623 | ||
|
553c7994ba | ||
|
280aadfcdb | ||
|
59ac922a1c | ||
|
8de3e84021 | ||
|
bd4f9c239a | ||
|
528195233b | ||
|
8c49f5a637 | ||
|
88f0a98d71 | ||
|
96d82e0275 | ||
|
40387ef654 |
@@ -2,21 +2,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>enable_shared_from_this</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0">enable_shared_from_this</h1>
|
||||
width="277" align="middle" border="0" />enable_shared_from_this</h1>
|
||||
<h2><a name="Purpose">Purpose</a></h2>
|
||||
<p>
|
||||
The header <STRONG><boost/enable_shared_from_this.hpp></STRONG> defines
|
||||
the class template <STRONG>enable_shared_from_this</STRONG>. It is used as a
|
||||
base class that allows a <A href="shared_ptr.htm">shared_ptr</A> to the current
|
||||
object to be obtained from within a member function.
|
||||
The header <code><boost/enable_shared_from_this.hpp></code> defines
|
||||
the class template <code>enable_shared_from_this</code>. It is used as a
|
||||
base class that allows a <a href="shared_ptr.htm">shared_ptr</a> or
|
||||
a <a href="weak_ptr.htm">weak_ptr</a> to the current object to be obtained
|
||||
from within a member function.
|
||||
</p>
|
||||
<p><code>enable_shared_from_this<T></code> defines two member functions
|
||||
called <code>shared_from_this</code> that return a <code>shared_ptr<T></code>
|
||||
and <code>shared_ptr<T const></code>, depending on constness, to <code>this</code>.
|
||||
It also defines two member functions called <code>weak_from_this</code> that return
|
||||
a corresponding <code>weak_ptr</code>.
|
||||
</p>
|
||||
<P><STRONG>enable_shared_from_this<T></STRONG> defines two member functions
|
||||
called <STRONG>shared_from_this</STRONG> that return a <STRONG>shared_ptr<T></STRONG>
|
||||
and <STRONG>shared_ptr<T const></STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
|
||||
<h2><a name="Example">Example</a></h2>
|
||||
<pre>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
@@ -41,7 +45,7 @@ int main()
|
||||
assert(!(p < q || q < p)); // p and q must share ownership
|
||||
}
|
||||
</pre>
|
||||
<h3><a name="Synopsis">Synopsis</a></h3>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<pre>
|
||||
namespace boost
|
||||
{
|
||||
@@ -52,34 +56,55 @@ public:
|
||||
|
||||
shared_ptr<T> shared_from_this();
|
||||
shared_ptr<T const> shared_from_this() const;
|
||||
|
||||
weak_ptr<T> weak_from_this() noexcept;
|
||||
weak_ptr<T const> weak_from_this() const noexcept;
|
||||
}
|
||||
|
||||
}
|
||||
</pre>
|
||||
<h4>template<class T> shared_ptr<T>
|
||||
enable_shared_from_this<T>::shared_from_this();</h4>
|
||||
<h4>template<class T> shared_ptr<T const>
|
||||
enable_shared_from_this<T>::shared_from_this() const;</h4>
|
||||
<h4><code>template<class T> shared_ptr<T>
|
||||
enable_shared_from_this<T>::shared_from_this();</code></h4>
|
||||
<h4><code>template<class T> shared_ptr<T const>
|
||||
enable_shared_from_this<T>::shared_from_this() const;</code></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Requires:</b> <STRONG>enable_shared_from_this<T></STRONG> must be an
|
||||
accessible base class of <b>T</b>. <STRONG>*this</STRONG> must be a subobject
|
||||
of an instance <STRONG>t</STRONG> of type <STRONG>T</STRONG> . There must exist
|
||||
at least one <STRONG>shared_ptr</STRONG> instance <STRONG>p</STRONG> that <EM>owns</EM>
|
||||
<STRONG>t</STRONG>.
|
||||
<b>Requires:</b> <code>enable_shared_from_this<T></code> must be an
|
||||
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
|
||||
of an instance <code>t</code> of type <code>T</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Returns:</b> A <b>shared_ptr<T></b> instance <b>r</b> that shares
|
||||
ownership with <b>p</b>.
|
||||
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
|
||||
<code>t</code> exists, a <code>shared_ptr<T></code> instance <code>r</code> that shares
|
||||
ownership with <code>p</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Postconditions:</b> <tt>r.get() == this</tt>.
|
||||
<b>Postconditions:</b> <code>r.get() == this</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Throws:</b> <code>bad_weak_ptr</code> when no <code>shared_ptr</code> <em>owns</em> <code>*this</code>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<p>$Date$</p>
|
||||
<h4><code>template<class T> weak_ptr<T>
|
||||
enable_shared_from_this<T>::weak_from_this() noexcept;</code></h4>
|
||||
<h4><code>template<class T> weak_ptr<T const>
|
||||
enable_shared_from_this<T>::weak_from_this() const noexcept;</code></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Requires:</b> <code>enable_shared_from_this<T></code> must be an
|
||||
accessible base class of <code>T</code>. <code>*this</code> must be a subobject
|
||||
of an instance <code>t</code> of type <code>T</code>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Returns:</b> If a <code>shared_ptr</code> instance <code>p</code> that <em>owns</em>
|
||||
<code>t</code> exists or has existed in the past, a <code>weak_ptr<T></code> instance
|
||||
<code>r</code> that shares ownership with <code>p</code>. Otherwise, an empty <code>weak_ptr</code>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<hr />
|
||||
<p>
|
||||
<small>Copyright © 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
<small>Copyright © 2002, 2003, 2015 by Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
|
||||
copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -213,7 +213,7 @@ namespace boost {
|
||||
typedef Y* pointer;
|
||||
typedef const Y* const_pointer;
|
||||
typedef std::size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Y& reference;
|
||||
typedef const Y& const_reference;
|
||||
|
||||
|
@@ -6,7 +6,8 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\
|
||||
&& !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
|
||||
|
||||
explicit operator bool () const BOOST_NOEXCEPT
|
||||
{
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include <boost/smart_ptr/bad_weak_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
// In order to avoid circular dependencies with Boost.TR1
|
||||
// we make sure that our include of <memory> doesn't try to
|
||||
@@ -40,13 +41,23 @@
|
||||
# include <new> // std::bad_alloc
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||
# include <boost/utility/addressof.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace movelib
|
||||
{
|
||||
|
||||
template< class T, class D > class unique_ptr;
|
||||
|
||||
} // namespace movelib
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -63,8 +74,6 @@ template< class D > struct sp_inplace_tag
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||
|
||||
template< class T > class sp_reference_wrapper
|
||||
{
|
||||
public:
|
||||
@@ -93,8 +102,6 @@ template< class D > struct sp_convert_reference< D& >
|
||||
typedef sp_reference_wrapper< D > type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class weak_count;
|
||||
|
||||
class shared_count
|
||||
@@ -438,6 +445,29 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y, class D>
|
||||
explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
typedef typename sp_convert_reference<D>::type D2;
|
||||
|
||||
D2 d2( r.get_deleter() );
|
||||
pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
~shared_count() // nothrow
|
||||
{
|
||||
if( pi_ != 0 ) pi_->release();
|
||||
@@ -668,6 +698,10 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_(
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8027 // Functions containing try are not expanded inline
|
||||
#endif
|
||||
|
@@ -16,6 +16,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
|
@@ -20,6 +20,12 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
||||
|
||||
#if defined( __clang__ ) && defined( __has_extension )
|
||||
# if __has_extension( __c_atomic__ )
|
||||
# define BOOST_SP_HAS_CLANG_C11_ATOMICS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_THREADS )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
@@ -35,6 +41,9 @@
|
||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_clang.hpp>
|
||||
|
||||
#elif defined( __SNC__ )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
|
||||
|
||||
@@ -79,4 +88,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_SP_HAS_CLANG_C11_ATOMICS
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||
|
140
include/boost/smart_ptr/detail/sp_counted_base_clang.hpp
Normal file
140
include/boost/smart_ptr/detail/sp_counted_base_clang.hpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_clang.hpp - __c11 clang intrinsics
|
||||
//
|
||||
// Copyright (c) 2007, 2013, 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
|
||||
|
||||
inline void atomic_increment( atomic_int_least32_t * pw )
|
||||
{
|
||||
__c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
|
||||
}
|
||||
|
||||
inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw )
|
||||
{
|
||||
return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
|
||||
}
|
||||
|
||||
inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
atomic_int_least32_t use_count_; // #shared
|
||||
atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base()
|
||||
{
|
||||
__c11_atomic_init( &use_count_, 1 );
|
||||
__c11_atomic_init( &weak_count_, 1 );
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
|
@@ -78,7 +78,7 @@ public:
|
||||
boost::checked_delete( px_ );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( detail::sp_typeinfo const & )
|
||||
virtual void * get_deleter( sp_typeinfo const & )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -153,7 +153,7 @@ public:
|
||||
del( ptr );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( detail::sp_typeinfo const & ti )
|
||||
virtual void * get_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public:
|
||||
a2.deallocate( this, 1 );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( detail::sp_typeinfo const & ti )
|
||||
virtual void * get_deleter( sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||
}
|
||||
|
40
include/boost/smart_ptr/detail/sp_disable_deprecated.hpp
Normal file
40
include/boost/smart_ptr/detail/sp_disable_deprecated.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/smart_ptr/detail/sp_disable_deprecated.hpp
|
||||
//
|
||||
// Copyright 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( __GNUC__ ) && ( defined( __GXX_EXPERIMENTAL_CXX0X__ ) || ( __cplusplus >= 201103L ) )
|
||||
|
||||
# if defined( BOOST_GCC )
|
||||
|
||||
# if BOOST_GCC >= 40600
|
||||
# define BOOST_SP_DISABLE_DEPRECATED
|
||||
# endif
|
||||
|
||||
# elif defined( __clang__ ) && defined( __has_warning )
|
||||
|
||||
# if __has_warning( "-Wdeprecated-declarations" )
|
||||
# define BOOST_SP_DISABLE_DEPRECATED
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
|
@@ -25,6 +25,17 @@ namespace detail
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
#if defined( BOOST_GCC ) && __GNUC__ * 100 + __GNUC_MINOR__ <= 404
|
||||
|
||||
// GCC 4.4 supports an outdated version of rvalue references and creates a copy of the forwarded object.
|
||||
// This results in warnings 'returning reference to temporary'. Therefore we use a special version similar to std::forward.
|
||||
template< class T > T&& sp_forward( T && t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< T&& >( t );
|
||||
@@ -32,6 +43,8 @@ template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
@@ -111,6 +111,17 @@ extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
# if defined( BOOST_MSVC ) && BOOST_MSVC == 1310
|
||||
//From MSDN, Visual Studio .NET 2003 spedific: To declare one of the interlocked functions
|
||||
//for use as an intrinsic, the function must be declared with the leading underscore and
|
||||
//the new function must appear in a #pragma intrinsic statement.
|
||||
# pragma intrinsic( _InterlockedIncrement )
|
||||
# pragma intrinsic( _InterlockedDecrement )
|
||||
# pragma intrinsic( _InterlockedCompareExchange )
|
||||
# pragma intrinsic( _InterlockedExchange )
|
||||
# pragma intrinsic( _InterlockedExchangeAdd )
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
|
@@ -26,7 +26,7 @@ namespace boost
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE )
|
||||
#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
|
||||
|
||||
typedef decltype(nullptr) sp_nullptr_t;
|
||||
|
||||
|
@@ -82,6 +82,7 @@ public:
|
||||
{
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
*const_cast< int volatile* >( &v_ ) = 0;
|
||||
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||
}
|
||||
|
||||
public:
|
||||
|
@@ -31,7 +31,7 @@ namespace boost
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< int I > class spinlock_pool
|
||||
template< int M > class spinlock_pool
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
|
||||
template< int M > spinlock spinlock_pool< M >::pool_[ 41 ] =
|
||||
{
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
|
@@ -60,7 +60,16 @@ namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
#if !BOOST_COMP_CLANG || !defined __MINGW32__
|
||||
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||
#else
|
||||
#include <_mingw.h>
|
||||
#if !defined __MINGW64_VERSION_MAJOR
|
||||
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void __stdcall Sleep( unsigned long ms );
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void yield( unsigned k )
|
||||
@@ -98,7 +107,13 @@ inline void yield( unsigned k )
|
||||
|
||||
#elif defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
#ifndef _AIX
|
||||
#include <sched.h>
|
||||
#else
|
||||
// AIX's sched.h defines ::var which sometimes conflicts with Lambda's var
|
||||
extern "C" int sched_yield(void);
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
namespace boost
|
||||
|
@@ -4,7 +4,7 @@
|
||||
//
|
||||
// enable_shared_from_raw.hpp
|
||||
//
|
||||
// Copyright 2002, 2009 Peter Dimov
|
||||
// Copyright 2002, 2009, 2014 Peter Dimov
|
||||
// Copyright 2008-2009 Frank Mori Hess
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -53,7 +53,7 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
void init_weak_once() const
|
||||
void init_if_expired() const
|
||||
{
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
@@ -62,6 +62,15 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void init_if_empty() const
|
||||
{
|
||||
if( weak_this_._empty() )
|
||||
{
|
||||
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
||||
weak_this_ = shared_this_;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
@@ -72,16 +81,26 @@ private:
|
||||
template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
#endif
|
||||
|
||||
shared_ptr<void> shared_from_this()
|
||||
shared_ptr<void const volatile> shared_from_this() const
|
||||
{
|
||||
init_weak_once();
|
||||
return shared_ptr<void>( weak_this_ );
|
||||
init_if_expired();
|
||||
return shared_ptr<void const volatile>( weak_this_ );
|
||||
}
|
||||
|
||||
shared_ptr<const void> shared_from_this() const
|
||||
shared_ptr<void const volatile> shared_from_this() const volatile
|
||||
{
|
||||
init_weak_once();
|
||||
return shared_ptr<const void>( weak_this_ );
|
||||
return const_cast< enable_shared_from_raw const * >( this )->shared_from_this();
|
||||
}
|
||||
|
||||
weak_ptr<void const volatile> weak_from_this() const
|
||||
{
|
||||
init_if_empty();
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
weak_ptr<void const volatile> weak_from_this() const volatile
|
||||
{
|
||||
return const_cast< enable_shared_from_raw const * >( this )->weak_from_this();
|
||||
}
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
@@ -107,9 +126,11 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
mutable weak_ptr<void> weak_this_;
|
||||
mutable weak_ptr<void const volatile> weak_this_;
|
||||
|
||||
private:
|
||||
mutable shared_ptr<void> shared_this_;
|
||||
|
||||
mutable shared_ptr<void const volatile> shared_this_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -124,7 +145,7 @@ boost::weak_ptr<T> weak_from_raw(T *p)
|
||||
{
|
||||
BOOST_ASSERT(p != 0);
|
||||
boost::weak_ptr<T> result;
|
||||
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p);
|
||||
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_from_this(), p);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -58,6 +58,16 @@ public:
|
||||
return p;
|
||||
}
|
||||
|
||||
weak_ptr<T> weak_from_this() BOOST_NOEXCEPT
|
||||
{
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
weak_ptr<T const> weak_from_this() const BOOST_NOEXCEPT
|
||||
{
|
||||
return weak_this_;
|
||||
}
|
||||
|
||||
public: // actually private, but avoids compiler template friendship issues
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
|
@@ -15,12 +15,18 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
# include <memory> // for std::auto_ptr
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
@@ -154,4 +160,8 @@ template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
|
||||
|
||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
|
||||
@@ -47,6 +48,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
@@ -55,6 +61,13 @@ template<class T> class weak_ptr;
|
||||
template<class T> class enable_shared_from_this;
|
||||
class enable_shared_from_raw;
|
||||
|
||||
namespace movelib
|
||||
{
|
||||
|
||||
template< class T, class D > class unique_ptr;
|
||||
|
||||
} // namespace movelib
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -495,6 +508,17 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
template< class Y, class D >
|
||||
shared_ptr( boost::movelib::unique_ptr< Y, D > r ): px( r.get() ), pn()
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get();
|
||||
pn = boost::detail::shared_count( r );
|
||||
|
||||
boost::detail::sp_deleter_construct( this, tmp );
|
||||
}
|
||||
|
||||
// assignment
|
||||
|
||||
shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
|
||||
@@ -556,6 +580,27 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y, class D>
|
||||
shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r )
|
||||
{
|
||||
// this_type( static_cast< unique_ptr<Y, D> && >( r ) ).swap( *this );
|
||||
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
typename boost::movelib::unique_ptr< Y, D >::pointer p = r.get();
|
||||
|
||||
shared_ptr tmp;
|
||||
|
||||
tmp.px = p;
|
||||
tmp.pn = boost::detail::shared_count( r );
|
||||
|
||||
boost::detail::sp_deleter_construct( &tmp, p );
|
||||
|
||||
tmp.swap( *this );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move support
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
@@ -655,7 +700,7 @@ public:
|
||||
BOOST_ASSERT( px != 0 );
|
||||
BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
|
||||
|
||||
return px[ i ];
|
||||
return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
|
||||
}
|
||||
|
||||
element_type * get() const BOOST_NOEXCEPT
|
||||
@@ -893,7 +938,7 @@ class esft2_deleter_wrapper
|
||||
{
|
||||
private:
|
||||
|
||||
shared_ptr<void> deleter_;
|
||||
shared_ptr<void const volatile> deleter_;
|
||||
|
||||
public:
|
||||
|
||||
@@ -1025,4 +1070,8 @@ template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOO
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_DEPRECATED )
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
|
||||
|
22
meta/libraries.json
Normal file
22
meta/libraries.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"key": "smart_ptr",
|
||||
"name": "Smart Ptr",
|
||||
"authors": [
|
||||
"Greg Colvin",
|
||||
"Beman Dawes",
|
||||
"Peter Dimov",
|
||||
"Darin Adler",
|
||||
"Glen Fernandes"
|
||||
],
|
||||
"description": "Smart pointer class templates.",
|
||||
"documentation": "smart_ptr.htm",
|
||||
"std": [
|
||||
"tr1"
|
||||
],
|
||||
"category": [
|
||||
"Memory"
|
||||
],
|
||||
"maintainers": [
|
||||
"Peter Dimov <pdimov -at- pdimov.com>"
|
||||
]
|
||||
}
|
@@ -60,8 +60,6 @@ import testing ;
|
||||
[ run sp_recursive_assign2_test.cpp ]
|
||||
[ run sp_recursive_assign_rv_test.cpp ]
|
||||
[ run sp_recursive_assign2_rv_test.cpp ]
|
||||
[ run esft_constructor_test.cpp ]
|
||||
[ run enable_shared_from_raw_test.cpp ]
|
||||
[ compile-fail auto_ptr_lv_fail.cpp ]
|
||||
[ run atomic_count_test2.cpp ]
|
||||
[ run sp_typeinfo_test.cpp ]
|
||||
@@ -163,5 +161,25 @@ import testing ;
|
||||
[ run make_unique_array_test.cpp ]
|
||||
[ run make_unique_array_noinit_test.cpp ]
|
||||
[ run make_unique_array_throws_test.cpp ]
|
||||
|
||||
[ run shared_from_raw_test.cpp ]
|
||||
[ run shared_from_raw_test2.cpp ]
|
||||
[ run shared_from_raw_test3.cpp ]
|
||||
[ run shared_from_raw_test4.cpp ]
|
||||
[ run shared_from_raw_test5.cpp ]
|
||||
[ run shared_from_raw_test6.cpp ]
|
||||
|
||||
[ run weak_from_raw_test.cpp ]
|
||||
[ run weak_from_raw_test2.cpp ]
|
||||
[ run weak_from_raw_test3.cpp ]
|
||||
[ run weak_from_raw_test4.cpp ]
|
||||
[ run weak_from_raw_test5.cpp ]
|
||||
|
||||
[ compile sp_explicit_inst_test.cpp ]
|
||||
|
||||
[ run weak_from_this_test.cpp ]
|
||||
[ run weak_from_this_test2.cpp ]
|
||||
|
||||
[ run sp_bml_unique_ptr_test.cpp ]
|
||||
;
|
||||
}
|
||||
|
@@ -12,8 +12,12 @@ struct X
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> void f( T & /*t*/ )
|
||||
{
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<X> px( new X );
|
||||
px[ 0 ];
|
||||
f( px[ 0 ] );
|
||||
}
|
||||
|
170
test/shared_from_raw_test.cpp
Normal file
170
test/shared_from_raw_test.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// shared_from_raw_test - based on shared_from_this_test
|
||||
//
|
||||
// Copyright (c) 2002, 2003, 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
class X
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void f() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
~X() {}
|
||||
};
|
||||
|
||||
class Y
|
||||
{
|
||||
public:
|
||||
|
||||
virtual boost::shared_ptr<X> getX() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
~Y() {}
|
||||
};
|
||||
|
||||
boost::shared_ptr<Y> createY();
|
||||
|
||||
void test()
|
||||
{
|
||||
boost::shared_ptr<Y> py = createY();
|
||||
BOOST_TEST(py.get() != 0);
|
||||
BOOST_TEST(py.use_count() == 1);
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<X> px = py->getX();
|
||||
BOOST_TEST(px.get() != 0);
|
||||
BOOST_TEST(py.use_count() == 2);
|
||||
|
||||
px->f();
|
||||
|
||||
#if !defined( BOOST_NO_RTTI )
|
||||
boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px);
|
||||
BOOST_TEST(py.get() == py2.get());
|
||||
BOOST_TEST(!(py < py2 || py2 < py));
|
||||
BOOST_TEST(py.use_count() == 3);
|
||||
#endif
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "py->getX() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
void test2();
|
||||
void test3();
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
test2();
|
||||
test3();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
// virtual inheritance to stress the implementation
|
||||
// (prevents Y* -> impl*, enable_shared_from_raw* -> impl* casts)
|
||||
|
||||
class impl: public X, public virtual Y, public virtual boost::enable_shared_from_raw
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void f()
|
||||
{
|
||||
}
|
||||
|
||||
virtual boost::shared_ptr<X> getX()
|
||||
{
|
||||
boost::shared_ptr<impl> pi = boost::shared_from_raw( this );
|
||||
BOOST_TEST( pi.get() == this );
|
||||
return pi;
|
||||
}
|
||||
};
|
||||
|
||||
// intermediate impl2 to stress the implementation
|
||||
|
||||
class impl2: public impl
|
||||
{
|
||||
};
|
||||
|
||||
boost::shared_ptr<Y> createY()
|
||||
{
|
||||
boost::shared_ptr<Y> pi(new impl2);
|
||||
return pi;
|
||||
}
|
||||
|
||||
void test2()
|
||||
{
|
||||
boost::shared_ptr<Y> pi(static_cast<impl2*>(0));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
struct V: public boost::enable_shared_from_raw
|
||||
{
|
||||
};
|
||||
|
||||
void test3()
|
||||
{
|
||||
boost::shared_ptr<V> p( new V );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<V> q = boost::shared_from_raw( p.get() );
|
||||
BOOST_TEST( p == q );
|
||||
BOOST_TEST( !(p < q) && !(q < p) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const & )
|
||||
{
|
||||
BOOST_ERROR( "shared_from_this( p.get() ) failed" );
|
||||
}
|
||||
|
||||
V v2( *p );
|
||||
|
||||
try
|
||||
{
|
||||
// shared_from_raw differs from shared_from_this;
|
||||
// it will not throw here and will create a shared_ptr
|
||||
|
||||
boost::shared_ptr<V> r = boost::shared_from_raw( &v2 );
|
||||
|
||||
// check if the shared_ptr is correct and that it does
|
||||
// not share ownership with p
|
||||
|
||||
BOOST_TEST( r.get() == &v2 );
|
||||
BOOST_TEST( p != r );
|
||||
BOOST_TEST( (p < r) || (r < p) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const & )
|
||||
{
|
||||
BOOST_ERROR("shared_from_raw( &v2 ) failed");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
*p = V();
|
||||
boost::shared_ptr<V> r = boost::shared_from_raw( p.get() );
|
||||
BOOST_TEST( p == r );
|
||||
BOOST_TEST( !(p < r) && !(r < p) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const & )
|
||||
{
|
||||
BOOST_ERROR("shared_from_raw( p.get() ) threw bad_weak_ptr after *p = V()");
|
||||
}
|
||||
}
|
219
test/shared_from_raw_test2.cpp
Normal file
219
test/shared_from_raw_test2.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
//
|
||||
// shared_from_raw_test2.cpp - based on esft_regtest.cpp
|
||||
//
|
||||
// Copyright (c) 2008, 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
private:
|
||||
|
||||
int destroyed_;
|
||||
int deleted_;
|
||||
int expected_;
|
||||
|
||||
private:
|
||||
|
||||
X( X const& );
|
||||
X& operator=( X const& );
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
public:
|
||||
|
||||
explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
BOOST_TEST( deleted_ == expected_ );
|
||||
BOOST_TEST( destroyed_ == 0 );
|
||||
++destroyed_;
|
||||
--instances;
|
||||
}
|
||||
|
||||
typedef void (*deleter_type)( X* );
|
||||
|
||||
static void deleter( X * px )
|
||||
{
|
||||
++px->deleted_;
|
||||
}
|
||||
|
||||
static void deleter2( X * px )
|
||||
{
|
||||
++px->deleted_;
|
||||
delete px;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
void test()
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
X x( 0 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
std::auto_ptr<X> px( new X( 0 ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> px( new X( 0 ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::weak_ptr<X> wp( px );
|
||||
BOOST_TEST( !wp.expired() );
|
||||
|
||||
px.reset();
|
||||
|
||||
BOOST_TEST( wp.expired() );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
X x( 1 );
|
||||
boost::shared_ptr<X> px( &x, X::deleter );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
|
||||
BOOST_TEST( pd != 0 && *pd == X::deleter );
|
||||
|
||||
boost::weak_ptr<X> wp( px );
|
||||
BOOST_TEST( !wp.expired() );
|
||||
|
||||
px.reset();
|
||||
|
||||
BOOST_TEST( wp.expired() );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> px( new X( 1 ), X::deleter2 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
|
||||
BOOST_TEST( pd != 0 && *pd == X::deleter2 );
|
||||
|
||||
boost::weak_ptr<X> wp( px );
|
||||
BOOST_TEST( !wp.expired() );
|
||||
|
||||
px.reset();
|
||||
|
||||
BOOST_TEST( wp.expired() );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
struct V: public boost::enable_shared_from_raw
|
||||
{
|
||||
virtual ~V() {}
|
||||
std::string m_;
|
||||
};
|
||||
|
||||
struct V2
|
||||
{
|
||||
virtual ~V2() {}
|
||||
std::string m2_;
|
||||
};
|
||||
|
||||
struct W: V2, V
|
||||
{
|
||||
};
|
||||
|
||||
void test2()
|
||||
{
|
||||
boost::shared_ptr<W> p( new W );
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
V * p = new W;
|
||||
boost::shared_ptr<void> pv( p );
|
||||
BOOST_TEST( pv.get() == p );
|
||||
BOOST_TEST( pv.use_count() == 1 );
|
||||
}
|
||||
|
||||
struct null_deleter
|
||||
{
|
||||
void operator()( void const* ) const {}
|
||||
};
|
||||
|
||||
void test4()
|
||||
{
|
||||
boost::shared_ptr<V> pv( new V );
|
||||
boost::shared_ptr<V> pv2( pv.get(), null_deleter() );
|
||||
BOOST_TEST( pv2.get() == pv.get() );
|
||||
BOOST_TEST( pv2.use_count() == 1 );
|
||||
}
|
||||
|
||||
void test5()
|
||||
{
|
||||
V v;
|
||||
|
||||
boost::shared_ptr<V> p1( &v, null_deleter() );
|
||||
BOOST_TEST( p1.get() == &v );
|
||||
BOOST_TEST( p1.use_count() == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_from_raw( p1.get() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "shared_from_raw( p1.get() ) failed" );
|
||||
}
|
||||
|
||||
p1.reset();
|
||||
|
||||
boost::shared_ptr<V> p2( &v, null_deleter() );
|
||||
BOOST_TEST( p2.get() == &v );
|
||||
BOOST_TEST( p2.use_count() == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_from_raw( p2.get() );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "shared_from_raw( p2.get() ) failed" );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
test5();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
52
test/shared_from_raw_test3.cpp
Normal file
52
test/shared_from_raw_test3.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// shared_from_raw_test3 - based on esft_second_ptr_test.cpp
|
||||
//
|
||||
// This test has been extracted from a real
|
||||
// scenario that occurs in Boost.Python
|
||||
//
|
||||
// Copyright 2009, 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
};
|
||||
|
||||
void null_deleter( void const* )
|
||||
{
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<X> px( new X );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> px2( px.get(), null_deleter );
|
||||
BOOST_TEST( px == px2 );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = boost::shared_from_raw( px.get() );
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "shared_from_raw( px.get() ) failed" );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
56
test/shared_from_raw_test4.cpp
Normal file
56
test/shared_from_raw_test4.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// shared_from_raw_test4 - based on esft_void_test.cpp
|
||||
//
|
||||
// Copyright 2009, 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr< void const volatile > pv( new X );
|
||||
boost::shared_ptr< void > pv2 = boost::const_pointer_cast< void >( pv );
|
||||
boost::shared_ptr< X > px = boost::static_pointer_cast< X >( pv2 );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X > qx = boost::shared_from_raw( px.get() );
|
||||
|
||||
BOOST_TEST( px == qx );
|
||||
BOOST_TEST( !( px < qx ) && !( qx < px ) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "shared_from_this( px.get() ) failed" );
|
||||
}
|
||||
|
||||
boost::shared_ptr< X const volatile > px2( px );
|
||||
|
||||
try
|
||||
{
|
||||
boost::shared_ptr< X const volatile > qx2 = boost::shared_from_raw( px2.get() );
|
||||
|
||||
BOOST_TEST( px2 == qx2 );
|
||||
BOOST_TEST( !( px2 < qx2 ) && !( qx2 < px2 ) );
|
||||
}
|
||||
catch( boost::bad_weak_ptr const& )
|
||||
{
|
||||
BOOST_ERROR( "shared_from_this( px2.get() ) failed" );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// esft_constructor_test.cpp
|
||||
// shared_from_raw_test5.cpp - was esft_constructor_test.cpp
|
||||
//
|
||||
// A test for the new enable_shared_from_this support for calling
|
||||
// shared_from_this from constructors (that is, prior to the
|
||||
// object's ownership being passed to an external shared_ptr).
|
||||
// A test for calling shared_from_raw from constructors
|
||||
// (that is, prior to the object's ownership being passed to
|
||||
// an external shared_ptr).
|
||||
//
|
||||
// Copyright (c) 2008 Frank Mori Hess
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
@@ -13,6 +13,7 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
52
test/shared_from_raw_test6.cpp
Normal file
52
test/shared_from_raw_test6.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// shared_from_raw_test6
|
||||
//
|
||||
// Tests that dangling shared_ptr instances are caught by
|
||||
// the BOOST_ASSERT in ~enable_shared_from_raw
|
||||
//
|
||||
// Copyright 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <stdio.h>
|
||||
|
||||
static int assertion_failed_ = 0;
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
void assertion_failed( char const * expr, char const * function, char const * file, long line )
|
||||
{
|
||||
printf( "Assertion '%s' failed in function '%s', file '%s', line %ld\n", expr, function, file, line );
|
||||
++assertion_failed_;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<X> px;
|
||||
|
||||
{
|
||||
X x;
|
||||
px = boost::shared_from_raw( &x );
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( assertion_failed_, 1 );
|
||||
|
||||
// px is a dangling pointer here
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
239
test/sp_bml_unique_ptr_test.cpp
Normal file
239
test/sp_bml_unique_ptr_test.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
//
|
||||
// sp_bml_unique_ptr_test.cpp
|
||||
//
|
||||
// Copyright (c) 2012, 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/move/unique_ptr.hpp>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
struct X: public boost::enable_shared_from_this< X >
|
||||
{
|
||||
static int instances;
|
||||
|
||||
X()
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
struct Y
|
||||
{
|
||||
static int instances;
|
||||
|
||||
bool deleted_;
|
||||
|
||||
Y(): deleted_( false )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~Y()
|
||||
{
|
||||
BOOST_TEST( deleted_ );
|
||||
--instances;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Y( Y const & );
|
||||
Y & operator=( Y const & );
|
||||
};
|
||||
|
||||
int Y::instances = 0;
|
||||
|
||||
struct YD
|
||||
{
|
||||
void operator()( Y* p ) const
|
||||
{
|
||||
p->deleted_ = true;
|
||||
delete p;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
boost::movelib::unique_ptr<X> p( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::shared_ptr<X> p2( boost::move( p ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
boost::shared_ptr<X> p3 = p2->shared_from_this();
|
||||
BOOST_TEST( p2 == p3 );
|
||||
BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
|
||||
|
||||
p2.reset();
|
||||
p3.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<X>( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<X>( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p3 = p2->shared_from_this();
|
||||
BOOST_TEST( p2 == p3 );
|
||||
BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
|
||||
|
||||
p2.reset();
|
||||
p3.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
boost::movelib::unique_ptr<X> p( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::shared_ptr<X const> p2( boost::move( p ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
boost::shared_ptr<X const> p3 = p2->shared_from_this();
|
||||
BOOST_TEST( p2 == p3 );
|
||||
BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
|
||||
|
||||
p2.reset();
|
||||
p3.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<X>( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<X>( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p3 = p2->shared_from_this();
|
||||
BOOST_TEST( p2 == p3 );
|
||||
BOOST_TEST( !(p2 < p3) && !(p3 < p2) );
|
||||
|
||||
p2.reset();
|
||||
p3.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
boost::movelib::unique_ptr<X> p( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::shared_ptr<void> p2( boost::move( p ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<X>( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<X>( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
|
||||
boost::movelib::unique_ptr<Y, YD> p( new Y, YD() );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
boost::shared_ptr<Y> p2( boost::move( p ) );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<Y, YD>( new Y, YD() );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<Y, YD>( new Y, YD() );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
|
||||
YD yd;
|
||||
|
||||
boost::movelib::unique_ptr<Y, YD&> p( new Y, yd );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
boost::shared_ptr<Y> p2( boost::move( p ) );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<Y, YD&>( new Y, yd );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<Y, YD&>( new Y, yd );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
|
||||
YD yd;
|
||||
|
||||
boost::movelib::unique_ptr<Y, YD const&> p( new Y, yd );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
boost::shared_ptr<Y> p2( boost::move( p ) );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<Y, YD const&>( new Y, yd );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
p2 = boost::movelib::unique_ptr<Y, YD const&>( new Y, yd );
|
||||
BOOST_TEST( Y::instances == 1 );
|
||||
|
||||
p2.reset();
|
||||
BOOST_TEST( Y::instances == 0 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
23
test/sp_explicit_inst_test.cpp
Normal file
23
test/sp_explicit_inst_test.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Explicit instantiations are reported to exist in user code
|
||||
//
|
||||
// Copyright (c) 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
template class boost::shared_ptr< int >;
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
template class boost::shared_ptr< X >;
|
||||
|
||||
int main()
|
||||
{
|
||||
}
|
@@ -9,6 +9,7 @@
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
@@ -37,7 +38,7 @@ private:
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
void f( std::nullptr_t )
|
||||
void f( boost::detail::sp_nullptr_t )
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,6 @@
|
||||
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
|
||||
@@ -23,7 +22,7 @@ void basic_weak_from_raw_test()
|
||||
{
|
||||
X *p(new X);
|
||||
boost::weak_ptr<X> weak = boost::weak_from_raw(p);
|
||||
BOOST_TEST(weak.expired());
|
||||
BOOST_TEST(!weak.expired());
|
||||
boost::shared_ptr<X> shared(p);
|
||||
weak = boost::weak_from_raw(p);
|
||||
BOOST_TEST(weak.expired() == false);
|
67
test/weak_from_raw_test2.cpp
Normal file
67
test/weak_from_raw_test2.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// weak_from_raw_test2.cpp
|
||||
//
|
||||
// Test that weak_from_raw returns consistent values
|
||||
// throughout the object lifetime
|
||||
//
|
||||
// Copyright (c) 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
class X;
|
||||
|
||||
static boost::weak_ptr< X > r_;
|
||||
|
||||
void register_( boost::weak_ptr< X > const & r )
|
||||
{
|
||||
r_ = r;
|
||||
}
|
||||
|
||||
void check_( boost::weak_ptr< X > const & r )
|
||||
{
|
||||
BOOST_TEST( !( r < r_ ) && !( r_ < r ) );
|
||||
}
|
||||
|
||||
void unregister_( boost::weak_ptr< X > const & r )
|
||||
{
|
||||
BOOST_TEST( !( r < r_ ) && !( r_ < r ) );
|
||||
r_.reset();
|
||||
}
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
public:
|
||||
|
||||
X()
|
||||
{
|
||||
register_( boost::shared_from_raw( this ) );
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
unregister_( boost::weak_from_raw( this ) );
|
||||
}
|
||||
|
||||
void check()
|
||||
{
|
||||
check_( boost::weak_from_raw( this ) );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::shared_ptr< X > px( new X );
|
||||
px->check();
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
46
test/weak_from_raw_test3.cpp
Normal file
46
test/weak_from_raw_test3.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// weak_from_raw_test3.cpp
|
||||
//
|
||||
// Test that weak_from_raw and shared_from_raw
|
||||
// return consistent values from a constructor
|
||||
//
|
||||
// Copyright (c) 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
public:
|
||||
|
||||
X()
|
||||
{
|
||||
boost::weak_ptr<X> p1 = boost::weak_from_raw( this );
|
||||
BOOST_TEST( !p1.expired() );
|
||||
|
||||
boost::weak_ptr<X> p2 = boost::weak_from_raw( this );
|
||||
BOOST_TEST( !p2.expired() );
|
||||
BOOST_TEST( !( p1 < p2 ) && !( p2 < p1 ) );
|
||||
|
||||
boost::weak_ptr<X> p3 = boost::shared_from_raw( this );
|
||||
BOOST_TEST( !( p1 < p3 ) && !( p3 < p1 ) );
|
||||
|
||||
boost::weak_ptr<X> p4 = boost::weak_from_raw( this );
|
||||
BOOST_TEST( !p4.expired() );
|
||||
BOOST_TEST( !( p3 < p4 ) && !( p4 < p3 ) );
|
||||
BOOST_TEST( !( p1 < p4 ) && !( p4 < p1 ) );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr< X > px( new X );
|
||||
return boost::report_errors();
|
||||
}
|
67
test/weak_from_raw_test4.cpp
Normal file
67
test/weak_from_raw_test4.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// weak_from_raw_test4.cpp
|
||||
//
|
||||
// As weak_from_raw_test2.cpp, but uses weak_from_raw
|
||||
// in the constructor
|
||||
//
|
||||
// Copyright (c) 2014, 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
class X;
|
||||
|
||||
static boost::weak_ptr< X > r_;
|
||||
|
||||
void register_( boost::weak_ptr< X > const & r )
|
||||
{
|
||||
r_ = r;
|
||||
}
|
||||
|
||||
void check_( boost::weak_ptr< X > const & r )
|
||||
{
|
||||
BOOST_TEST( !( r < r_ ) && !( r_ < r ) );
|
||||
}
|
||||
|
||||
void unregister_( boost::weak_ptr< X > const & r )
|
||||
{
|
||||
BOOST_TEST( !( r < r_ ) && !( r_ < r ) );
|
||||
r_.reset();
|
||||
}
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
public:
|
||||
|
||||
X()
|
||||
{
|
||||
register_( boost::weak_from_raw( this ) );
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
unregister_( boost::weak_from_raw( this ) );
|
||||
}
|
||||
|
||||
void check()
|
||||
{
|
||||
check_( boost::weak_from_raw( this ) );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::shared_ptr< X > px( new X );
|
||||
px->check();
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
45
test/weak_from_raw_test5.cpp
Normal file
45
test/weak_from_raw_test5.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// weak_from_raw_test5.cpp
|
||||
//
|
||||
// Tests whether pointers returned from weak_from_raw
|
||||
// expire properly
|
||||
//
|
||||
// Copyright 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_raw.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
class X: public boost::enable_shared_from_raw
|
||||
{
|
||||
public:
|
||||
|
||||
explicit X( boost::weak_ptr< X > & r )
|
||||
{
|
||||
r = boost::weak_from_raw( this );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::weak_ptr<X> p1, p2;
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > px( new X( p1 ) );
|
||||
p2 = boost::weak_from_raw( px.get() );
|
||||
|
||||
BOOST_TEST( !p1.expired() );
|
||||
BOOST_TEST( !p2.expired() );
|
||||
}
|
||||
|
||||
BOOST_TEST( p1.expired() );
|
||||
BOOST_TEST( p2.expired() );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
52
test/weak_from_this_test.cpp
Normal file
52
test/weak_from_this_test.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
//
|
||||
// weak_from_this_test.cpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003, 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
class V: public boost::enable_shared_from_this<V>
|
||||
{
|
||||
};
|
||||
|
||||
void test()
|
||||
{
|
||||
boost::shared_ptr<V> p( new V );
|
||||
|
||||
boost::weak_ptr<V> q = p;
|
||||
BOOST_TEST( !q.expired() );
|
||||
|
||||
boost::weak_ptr<V> q2 = p->weak_from_this();
|
||||
BOOST_TEST( !q2.expired() );
|
||||
BOOST_TEST( !(q < q2) && !(q2 < q) );
|
||||
|
||||
V v2( *p );
|
||||
|
||||
boost::weak_ptr<V> q3 = v2.weak_from_this();
|
||||
BOOST_TEST( q3.expired() );
|
||||
|
||||
*p = V();
|
||||
|
||||
boost::weak_ptr<V> q4 = p->shared_from_this();
|
||||
BOOST_TEST( !q4.expired() );
|
||||
BOOST_TEST( !(q < q4) && !(q4 < q) );
|
||||
BOOST_TEST( !(q2 < q4) && !(q4 < q2) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
return boost::report_errors();
|
||||
}
|
60
test/weak_from_this_test2.cpp
Normal file
60
test/weak_from_this_test2.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// weak_from_this_test2.cpp
|
||||
//
|
||||
// Tests weak_from_this in a destructor
|
||||
//
|
||||
// Copyright (c) 2014, 2015 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/smart_ptr/enable_shared_from_this.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
class X: public boost::enable_shared_from_this< X >
|
||||
{
|
||||
private:
|
||||
|
||||
boost::weak_ptr<X> px_;
|
||||
|
||||
public:
|
||||
|
||||
X()
|
||||
{
|
||||
boost::weak_ptr<X> p1 = weak_from_this();
|
||||
BOOST_TEST( p1._empty() );
|
||||
BOOST_TEST( p1.expired() );
|
||||
}
|
||||
|
||||
void check()
|
||||
{
|
||||
boost::weak_ptr<X> p2 = weak_from_this();
|
||||
BOOST_TEST( !p2.expired() );
|
||||
|
||||
BOOST_TEST( p2.lock().get() == this );
|
||||
|
||||
px_ = p2;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
boost::weak_ptr<X> p3 = weak_from_this();
|
||||
BOOST_TEST( p3.expired() );
|
||||
|
||||
BOOST_TEST( !(px_ < p3) && !(p3 < px_) );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::shared_ptr< X > px( new X );
|
||||
px->check();
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user