Compare commits

...

10 Commits

Author SHA1 Message Date
Marshall Clow
9b964f6881 Release 1.55.0
[SVN r86621]
2013-11-11 19:45:21 +00:00
Peter Dimov
be06392771 Merged revision(s) 85995 from trunk: Remove #pragma intrinsic( _mm_pause ); not needed, not supported on Intel. Closes #6646, #7318.
[SVN r86417]
2013-10-24 14:05:26 +00:00
Andrey Semashev
fc20a29c99 Merged changes from trunk: added intrusive_ref_counter.
[SVN r85609]
2013-09-08 17:17:18 +00:00
Peter Dimov
6eefc6bf81 Merge [84506] from trunk: Document that constructors initialize enable_shared_from_this. Fixes #8573.
[SVN r84507]
2013-05-26 13:39:04 +00:00
Peter Dimov
9355404d10 Merged revision(s) 83914 from trunk:
Fix new double(n) to new double[n].

[SVN r83915]
2013-04-15 15:13:20 +00:00
Glen Fernandes
240c66e633 Merge revision(s) 83829 from trunk:
More small cosmetic documentation changes.
........

[SVN r83830]
2013-04-10 05:17:32 +00:00
Glen Fernandes
e497aec58a Merge revision(s) 83827 from trunk:
Small improvements to make_shared documentation.
........


[SVN r83828]
2013-04-10 05:03:45 +00:00
Peter Dimov
579b347267 Merged revision(s) 83198 from trunk: Avoid stack overflow in make_shared. Fixes #4256. Fixes #7965.
[SVN r83341]
2013-03-07 08:18:48 +00:00
Glen Fernandes
3178d38137 Merge revision 82971 from trunk:
Identifier renaming in allocate_array_helper, array_deleter, make_array_helper
function parameters to satisfy higher warning levels.
........


[SVN r82976]
2013-02-18 18:04:48 +00:00
Peter Dimov
e39fcad839 Merged revision(s) 82927 from trunk: Check for BOOST_NO_CXX11_RVALUE_REFERENCES in addition to BOOST_NO_CXX11_SMART_PTR. Fixes #8055.
[SVN r82928]
2013-02-16 17:21:23 +00:00
14 changed files with 584 additions and 122 deletions

View File

@@ -33,10 +33,10 @@ namespace boost {
struct rebind {
typedef allocate_array_helper<A, T[], U> other;
};
allocate_array_helper(const A& allocator, std::size_t size, T** data)
: allocator(allocator),
size(sizeof(T) * size),
data(data) {
allocate_array_helper(const A& allocator_, std::size_t size_, T** data_)
: allocator(allocator_),
size(sizeof(T) * size_),
data(data_) {
}
template<class U>
allocate_array_helper(const allocate_array_helper<A, T[], U>& other)
@@ -107,9 +107,9 @@ namespace boost {
struct rebind {
typedef allocate_array_helper<A, T[N], U> other;
};
allocate_array_helper(const A& allocator, T** data)
: allocator(allocator),
data(data) {
allocate_array_helper(const A& allocator_, T** data_)
: allocator(allocator_),
data(data_) {
}
template<class U>
allocate_array_helper(const allocate_array_helper<A, T[N], U>& other)

View File

@@ -19,8 +19,8 @@ namespace boost {
template<typename T>
class array_deleter<T[]> {
public:
array_deleter(std::size_t size)
: size(size),
array_deleter(std::size_t size_)
: size(size_),
object(0) {
}
~array_deleter() {

View File

@@ -31,9 +31,9 @@ namespace boost {
struct rebind {
typedef make_array_helper<T[], U> other;
};
make_array_helper(std::size_t size, T** data)
: size(sizeof(T) * size),
data(data) {
make_array_helper(std::size_t size_, T** data_)
: size(sizeof(T) * size_),
data(data_) {
}
template<class U>
make_array_helper(const make_array_helper<T[], U>& other)
@@ -72,7 +72,7 @@ namespace boost {
memory->~Y();
}
template<typename U>
bool operator==(const make_array_helper<T[], U>& other) const {
bool operator==(const make_array_helper<T[], U>&) const {
return true;
}
template<typename U>
@@ -99,8 +99,8 @@ namespace boost {
struct rebind {
typedef make_array_helper<T[N], U> other;
};
make_array_helper(T** data)
: data(data) {
make_array_helper(T** data_)
: data(data_) {
}
template<class U>
make_array_helper(const make_array_helper<T[N], U>& other)
@@ -138,7 +138,7 @@ namespace boost {
memory->~Y();
}
template<typename U>
bool operator==(const make_array_helper<T[N], U>& other) const {
bool operator==(const make_array_helper<T[N], U>&) const {
return true;
}
template<typename U>

View File

@@ -200,7 +200,7 @@ public:
}
catch( ... )
{
D()( p ); // delete p
D::operator_fn( p ); // delete p
throw;
}
@@ -210,7 +210,7 @@ public:
if( pi_ == 0 )
{
D()( p ); // delete p
D::operator_fn( p ); // delete p
boost::throw_exception( std::bad_alloc() );
}
@@ -286,7 +286,7 @@ public:
}
catch(...)
{
D()( p );
D::operator_fn( p );
if( pi_ != 0 )
{
@@ -306,7 +306,7 @@ public:
}
else
{
D()( p );
D::operator_fn( p );
boost::throw_exception( std::bad_alloc() );
}

View File

@@ -30,7 +30,6 @@
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
extern "C" void _mm_pause();
#pragma intrinsic( _mm_pause )
#define BOOST_SMT_PAUSE _mm_pause();

View File

@@ -0,0 +1,187 @@
/*
* Copyright Andrey Semashev 2007 - 2013.
* 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)
*/
/*!
* \file intrusive_ref_counter.hpp
* \author Andrey Semashev
* \date 12.03.2009
*
* This header contains a reference counter class for \c intrusive_ptr.
*/
#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if defined(_MSC_VER)
#pragma warning(push)
// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
// Note that there is no inline specifier in the declarations.
#pragma warning(disable: 4396)
#endif
namespace boost {
namespace sp_adl_block {
/*!
* \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
*
* The policy instructs the \c intrusive_ref_counter base class to implement
* a reference counter suitable for single threaded use only. Pointers to the same
* object with this kind of reference counter must not be used by different threads.
*/
struct thread_unsafe_counter
{
typedef unsigned int type;
static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
{
return counter;
}
static void increment(unsigned int& counter) BOOST_NOEXCEPT
{
++counter;
}
static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
{
return --counter;
}
};
/*!
* \brief Thread safe reference counter policy for \c intrusive_ref_counter
*
* The policy instructs the \c intrusive_ref_counter base class to implement
* a thread-safe reference counter, if the target platform supports multithreading.
*/
struct thread_safe_counter
{
typedef boost::detail::atomic_count type;
static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
{
return static_cast< unsigned int >(static_cast< long >(counter));
}
static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
{
++counter;
}
static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
{
return --counter;
}
};
template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
class intrusive_ref_counter;
template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
template< typename DerivedT, typename CounterPolicyT >
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
/*!
* \brief A reference counter base class
*
* This base class can be used with user-defined classes to add support
* for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
* Upon releasing the last \c intrusive_ptr referencing the object
* derived from the \c intrusive_ref_counter class, operator \c delete
* is automatically called on the pointer to the object.
*
* The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
*/
template< typename DerivedT, typename CounterPolicyT >
class intrusive_ref_counter
{
private:
//! Reference counter type
typedef typename CounterPolicyT::type counter_type;
//! Reference counter
mutable counter_type m_ref_counter;
public:
/*!
* Default constructor
*
* \post <tt>use_count() == 0</tt>
*/
intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
{
}
/*!
* Copy constructor
*
* \post <tt>use_count() == 0</tt>
*/
intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
{
}
/*!
* Assignment
*
* \post The reference counter is not modified after assignment
*/
intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
/*!
* \return The reference counter
*/
unsigned int use_count() const BOOST_NOEXCEPT
{
return CounterPolicyT::load(m_ref_counter);
}
protected:
/*!
* Destructor
*/
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
};
template< typename DerivedT, typename CounterPolicyT >
inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
{
CounterPolicyT::increment(p->m_ref_counter);
}
template< typename DerivedT, typename CounterPolicyT >
inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
{
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
delete static_cast< const DerivedT* >(p);
}
} // namespace sp_adl_block
using sp_adl_block::intrusive_ref_counter;
using sp_adl_block::thread_unsafe_counter;
using sp_adl_block::thread_safe_counter;
} // namespace boost
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_

View File

@@ -87,6 +87,10 @@ public:
destroy();
}
static void operator_fn( T* ) // operator() can't be static
{
}
void * address() BOOST_NOEXCEPT
{
return storage_.data_;

View File

@@ -485,7 +485,7 @@ public:
#endif // BOOST_NO_AUTO_PTR
#if !defined( BOOST_NO_CXX11_SMART_PTR )
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template< class Y, class D >
shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
@@ -550,7 +550,7 @@ public:
#endif // BOOST_NO_AUTO_PTR
#if !defined( BOOST_NO_CXX11_SMART_PTR )
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y, class D>
shared_ptr & operator=( std::unique_ptr<Y, D> && r )

View File

@@ -24,7 +24,9 @@
compilers that support argument-dependent lookup, <STRONG>intrusive_ptr_add_ref</STRONG>
and <STRONG>intrusive_ptr_release</STRONG> should be defined in the namespace
that corresponds to their parameter; otherwise, the definitions need to go in
namespace <STRONG>boost</STRONG>.</p>
namespace <STRONG>boost</STRONG>. The library provides a helper base class template
<STRONG><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></STRONG> which may
help adding support for <STRONG>intrusive_ptr</STRONG> to user&apos;s types.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <STRONG>intrusive_ptr&lt;T&gt;</STRONG> can be implicitly converted to <STRONG>intrusive_ptr&lt;U&gt;</STRONG>
whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.</p>

View File

@@ -0,0 +1,95 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>intrusive_ref_counter</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgColor="#ffffff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
border="0"></A>basic_intrusive_ref_counter class template</h1>
<p>
<A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br>
<A href="#Members">Members</A><br>
</p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <STRONG>intrusive_ref_counter</STRONG> class template implements a reference counter for a derived
user&apos;s class that is intended to be used with <STRONG><a href="intrusive_ptr.html">intrusive_ptr</a></STRONG>.
The base class has associated <STRONG>intrusive_ptr_add_ref</STRONG> and <STRONG>intrusive_ptr_release</STRONG> functions
which modify the reference counter as needed and destroy the user's object when the counter drops to zero.</p>
<p>The class template is parameterized on <STRONG>DerivedT</STRONG> and <STRONG>CounterPolicyT</STRONG> parameters.
The first parameter is the user&apos;s class that derives from <STRONG>intrusive_ref_counter</STRONG>. This type
is needed in order to destroy the object correctly when there are no references to it left.</p>
<p>The second parameter is a policy that defines the nature of the reference counter.
Boost.SmartPtr provides two such policies: <STRONG>thread_unsafe_counter</STRONG> and <STRONG>thread_safe_counter</STRONG>. The former
instructs the <STRONG>intrusive_ref_counter</STRONG> base class to use a counter only suitable for a single-threaded use.
Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy
makes the reference counter thread-safe, unless the target platform doesn't support threading. Since in modern systems support for
threading is common, the default counter policy is <STRONG>thread_safe_counter</STRONG>.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
struct thread_unsafe_counter;
struct thread_safe_counter;
template&lt;class DerivedT, class CounterPolicyT = thread_safe_counter&gt;
class intrusive_ref_counter
{
public:
<A href="#constructors" >intrusive_ref_counter</A>() = noexcept;
<A href="#constructors" >intrusive_ref_counter</A>(intrusive_ref_counter const &amp; r) = noexcept;
intrusive_ref_counter &amp; <A href="#assignment" >operator=</A>(intrusive_ref_counter const &amp; r) noexcept;
unsigned int <a href="#use_count" >use_count</a>() const noexcept;
protected:
<A href="#destructor" >~intrusive_ref_counter</A>() = default;
};
}</pre>
<h2><a name="Members">Members</a></h2>
<h3><a name="constructors">constructors</a></h3>
<pre>intrusive_ref_counter();</pre>
<blockquote>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
</blockquote>
<pre>intrusive_ref_counter(intrusive_ref_counter const &amp;);</pre>
<blockquote>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
</blockquote>
<h3><a name="destructor">destructor</a></h3>
<pre>~intrusive_ref_counter();</pre>
<BLOCKQUOTE>
<p><b>Throws:</b> nothing.</p>
<P><B>Effects:</B> Destroys the counter object.</P>
<P><B>Notes:</B> The destructor is protected so that the object can only be destroyed through the <STRONG>DerivedT</STRONG> class.</P>
</BLOCKQUOTE>
<H3><a name="assignment">assignment</a></H3>
<pre>intrusive_ref_counter &amp; operator=(intrusive_ref_counter const &amp; r) noexcept;</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Does nothing, reference counter is not modified.</P>
<P><B>Returns:</B> <code>*this</code>.</P>
</BLOCKQUOTE>
<H3><a name="use_count">use_count</a></H3>
<pre>unsigned int use_count() const noexcept;</pre>
<BLOCKQUOTE>
<p><b>Returns:</b> The current value of the reference counter.</p>
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> The returned value may not be actual in multi-threaded applications.</P>
</BLOCKQUOTE>
<hr>
<p>
$Date$</p>
<p>
<small>Copyright <20> 2013 Andrey Semashev. 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>

View File

@@ -29,85 +29,86 @@
allowing finer control.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename T&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">make_shared</a>(size_t size);
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) &amp;&amp; !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">make_shared</a>(size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size);
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">make_shared</a>(Args&amp;&amp;... args);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) &amp;&amp; !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, Args&amp;&amp;... args);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(Args&amp;&amp;... args);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, Args&amp;&amp;... args);
#endif
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[][N]&gt; <a href="#functions">make_shared</a>(size_t size, const T (&amp;list)[N]);
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[M][N]&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename U, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, const T (&amp;list)[N]);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
template&lt;typename U, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[][N]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;T[&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[M][N]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">make_shared</a>(initializer_list&lt;T&gt; list);
template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(initializer_list&lt;T&gt; list);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, initializer_list&lt;T&gt; list);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, initializer_list&lt;T&gt; list);
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template&lt;typename T&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">make_shared</a>(size_t size, T&amp;&amp; value);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, T&amp;&amp; value);
template&lt;typename T&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">make_shared</a>(T&amp;&amp; value);
template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, T&amp;&amp; value);
#endif
#endif
template&lt;typename T&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">make_shared_noinit</a>(size_t size);
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>(size_t size);
template&lt;typename T&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">make_shared_noinit</a>();
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator, size_t size);
template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>();
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator, size_t size);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator);
}</pre>
<h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[]&gt; make_shared(size_t size, Args&amp;&amp;... args);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[]&gt; allocate_shared(const A&amp; allocator, size_t size, Args&amp;&amp;... args);</pre>
<pre>template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared(size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, Args&amp;&amp;... args);</pre>
<blockquote>
<p><b>Requires:</b> The expression
<code>new(pointer) T(forward&lt;Args&gt;(args)...)</code>, where
@@ -121,7 +122,7 @@ template&lt;typename T, typename A, typename... Args&gt;
<code>T</code> and size <code>size</code> and constructs an array
of objects in it via the placement new expression
<code>new(pointer) T()</code> or
<code>new(pointer) T(forward&lt;Args&gt;(args)...)</code>.
<code>new(pointer) T(args...)</code>.
<code>allocate_shared</code> uses a copy of
<code>allocator</code> to allocate memory. If an exception is thrown,
has no effect.</p>
@@ -146,74 +147,83 @@ template&lt;typename T, typename A, typename... Args&gt;
take any constructor arguments. These overloads invoke the default
constructor of <code>T</code> for each array element.</p>
</blockquote>
<pre>template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[N]&gt; make_shared(Args&amp;&amp;... args);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[N]&gt; allocate_shared(const A&amp; allocator, Args&amp;&amp;... args);</pre>
<pre>template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, Args&amp;&amp;... args);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[]&gt; make_shared(initializer_list&lt;T&gt; list);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[]&gt; allocate_shared(const A&amp; allocator, initializer_list&lt;T&gt; list);</pre>
<pre>template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared(initializer_list&lt;T&gt; list);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, initializer_list&lt;T&gt; list);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize the array elements
from the initializer list.</p>
</blockquote>
<pre>template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[N]&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[N]&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);</pre>
<pre>template&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[][N]&gt; make_shared(size_t size, const T (&amp;list)[N]);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[][N]&gt; allocate_shared(const A&amp; allocator, size_t size, const T (&amp;list)[N]);</pre>
<pre>template&lt;typename U, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; make_shared(size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize inner array elements
from the initializer list.</p>
</blockquote>
<pre>template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T[M][N]&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[M][N]&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);</pre>
<pre>template&lt;typename U, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename T&gt;
shared_ptr&lt;T[]&gt; make_shared(size_t size, T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[]&gt; allocate_shared(const A&amp; allocator, size_t size, T&amp;&amp; value);</pre>
</blockquote>
<pre>template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared(size_t size, T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, T&amp;&amp; value);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize array elements with
the given value.</p>
</blockquote>
<pre>template&lt;typename T&gt;
shared_ptr&lt;T[N]&gt; make_shared(T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[N]&gt; allocate_shared(const A&amp; allocator, T&amp;&amp; value);</pre>
<pre>template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, T&amp;&amp; value);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename T&gt;
shared_ptr&lt;T[]&gt; make_shared_noinit(size_t size);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[]&gt; allocate_shared_noinit(const A&amp; allocator, size_t size);</pre>
<pre>template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared_noinit(size_t size);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator, size_t size);</pre>
<blockquote>
<p><b>Description:</b> These overloads do not perform any value
initialization of elements.</p>
</blockquote>
<pre>template&lt;typename T&gt;
shared_ptr&lt;T[N]&gt; make_shared_noinit();
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[N]&gt; allocate_shared_noinit(const A&amp; allocator);</pre>
<pre>template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared_noinit();
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
@@ -221,7 +231,7 @@ template&lt;typename T, typename A&gt;
<h2><a name="example">Example</a></h2>
<p>An example of each overload of make_shared for arrays:</p>
<blockquote>
<pre>boost::shared_ptr&lt;point[]&gt; a1 = boost::make_shared&lt;point[]&gt;(size);
<pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared&lt;int[]&gt;(size);
boost::shared_ptr&lt;point[]&gt; a2 = boost::make_shared&lt;point[]&gt;(size, x, y);
boost::shared_ptr&lt;point[5]&gt; a3 = boost::make_shared&lt;point[5]&gt;(x, y);
boost::shared_ptr&lt;int[]&gt; a4 = boost::make_shared&lt;int[]&gt;({1, 2, 3});

View File

@@ -61,8 +61,8 @@ shared_ptr&lt;void&gt; p2( new int(5) );
the template parameter. There is almost no difference between using an unsized array, <code>T[]</code>,
and a sized array, <code>T[N]</code>; the latter just enables <code>operator[]</code> to perform a range check
on the index.</p>
<blockquote><em>Example:</em><br /><pre>shared_ptr&lt;double[1024]&gt; p1( new double(1024) );
shared_ptr&lt;double[]&gt; p2( new double(n) );
<blockquote><em>Example:</em><br /><pre>shared_ptr&lt;double[1024]&gt; p1( new double[1024] );
shared_ptr&lt;double[]&gt; p2( new double[n] );
</pre></blockquote>
<h2 id="BestPractices">Best Practices</h2>
@@ -262,8 +262,12 @@ shared_ptr(std::nullptr_t); // never throws</pre>
the pointer <code>p</code>.
Otherwise, constructs a <code>shared_ptr</code> that <em>owns</em>
<code>p</code> and a deleter of an unspecified type that calls <code>delete[] p</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
<p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.
If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code>
<a href="enable_shared_from_this.html">enable_shared_from_this</a>&lt;V&gt;*</code>
for some <code>V</code>, <code>p-&gt;shared_from_this()</code> returns a copy of
<code>*this</code>.</p>
<p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, the constructor calls
<code>delete[] p</code>, when <code>T</code> is an array type,
@@ -296,7 +300,11 @@ template&lt;class D, class A&gt; shared_ptr(std::nullptr_t p, D d, A a);</pre>
<p><b>Effects:</b> Constructs a <code>shared_ptr</code> that <em>owns</em> the pointer <code>
p</code> and the deleter <code>d</code>. The constructors taking an allocator <code>a</code>
allocate memory using a copy of <code>a</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.</p>
<p><b>Postconditions:</b> <code>use_count() == 1 &amp;&amp; get() == p</code>.
If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code>
<a href="enable_shared_from_this.html">enable_shared_from_this</a>&lt;V&gt;*</code>
for some <code>V</code>, <code>p-&gt;shared_from_this()</code> returns a copy of
<code>*this</code>.</p>
<p><b>Throws:</b> <code>std::bad_alloc</code>, or an implementation-defined
exception when a resource other than memory could not be obtained.</p>
<p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p>

View File

@@ -21,6 +21,7 @@ import testing ;
[ run get_deleter_test.cpp ]
[ run intrusive_ptr_test.cpp ]
[ run intrusive_ptr_move_test.cpp ]
[ run intrusive_ref_counter_test.cpp ]
[ run atomic_count_test.cpp ]
[ run lw_mutex_test.cpp ]
[ compile-fail shared_ptr_assign_fail.cpp ]

View File

@@ -0,0 +1,156 @@
/*
* Copyright Andrey Semashev 2013.
* 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)
*/
/*!
* \file intrusive_ref_counter_test.cpp
* \author Andrey Semashev
* \date 31.08.2013
*
* This file contains tests for the \c intrusive_ref_counter base class.
*/
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#pragma warning(disable: 4511) // copy constructor could not be generated
#pragma warning(disable: 4512) // assignment operator could not be generated
#if (BOOST_MSVC >= 1310)
#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
#endif
#endif
#include <cstddef>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
namespace N1 {
class my_class :
public boost::intrusive_ref_counter< my_class >
{
public:
static unsigned int destructor_count;
~my_class()
{
++destructor_count;
}
};
unsigned int my_class::destructor_count = 0;
} // namespace N1
namespace N2 {
class my_class :
public boost::intrusive_ref_counter< my_class, boost::thread_unsafe_counter >
{
public:
static unsigned int destructor_count;
~my_class()
{
++destructor_count;
}
};
unsigned int my_class::destructor_count = 0;
} // namespace N2
namespace N3 {
struct root :
public boost::intrusive_ref_counter< root >
{
virtual ~root() {}
};
} // namespace N3
namespace N4 {
struct X :
public virtual N3::root
{
};
} // namespace N4
namespace N5 {
struct Y :
public virtual N3::root
{
};
} // namespace N5
namespace N6 {
struct Z :
public N4::X,
public N5::Y
{
static unsigned int destructor_count;
~Z()
{
++destructor_count;
}
};
unsigned int Z::destructor_count = 0;
} // namespace N6
int main()
{
// The test check that ADL works
{
boost::intrusive_ptr< N1::my_class > p = new N1::my_class();
p = NULL;
BOOST_TEST(N1::my_class::destructor_count == 1);
}
{
boost::intrusive_ptr< N2::my_class > p = new N2::my_class();
p = NULL;
BOOST_TEST(N2::my_class::destructor_count == 1);
}
{
N1::my_class* p = new N1::my_class();
intrusive_ptr_add_ref(p);
intrusive_ptr_release(p);
BOOST_TEST(N1::my_class::destructor_count == 2);
}
// The test checks that destroying through the base class works
{
boost::intrusive_ptr< N6::Z > p1 = new N6::Z();
BOOST_TEST(p1->use_count() == 1);
BOOST_TEST(N6::Z::destructor_count == 0);
boost::intrusive_ptr< N3::root > p2 = p1;
BOOST_TEST(p1->use_count() == 2);
BOOST_TEST(N6::Z::destructor_count == 0);
p1 = NULL;
BOOST_TEST(N6::Z::destructor_count == 0);
p2 = NULL;
BOOST_TEST(N6::Z::destructor_count == 1);
}
return boost::report_errors();
}