mirror of
				https://github.com/boostorg/smart_ptr.git
				synced 2025-11-03 01:01:54 +01:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			boost-1.58
			...
			boost-1.47
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					565a79c136 | 
@@ -1,88 +1,88 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>Smart Pointer Changes</title>
 | 
			
		||||
        <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">Smart Pointer Changes</h1>
 | 
			
		||||
        <p>The February 2002 change to the Boost smart pointers introduced a number of 
 | 
			
		||||
            changes. Since the previous version of the smart pointers was in use for a long 
 | 
			
		||||
            time, it's useful to have a detailed list of what changed from a library user's 
 | 
			
		||||
            point of view.</p>
 | 
			
		||||
        <p>Note that for compilers that don't support member templates well enough, a 
 | 
			
		||||
            separate implementation is used that lacks many of the new features and is more 
 | 
			
		||||
            like the old version.</p>
 | 
			
		||||
        <h2>Features Requiring Code Changes to Take Advantage</h2>
 | 
			
		||||
        <ul>
 | 
			
		||||
            <li>
 | 
			
		||||
                The smart pointer class templates now each have their own header file. For 
 | 
			
		||||
                compatibility, the <a href="../../boost/smart_ptr.hpp"><boost/smart_ptr.hpp></a>
 | 
			
		||||
            header now includes the headers for the four classic smart pointer class 
 | 
			
		||||
            templates.
 | 
			
		||||
            <li>
 | 
			
		||||
                The <b>weak_ptr</b>
 | 
			
		||||
            template was added.
 | 
			
		||||
            <li>
 | 
			
		||||
                The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that 
 | 
			
		||||
                the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
 | 
			
		||||
            destructor. This makes it easier to have shared_ptr members in classes without 
 | 
			
		||||
            explicit destructors.
 | 
			
		||||
            <li>
 | 
			
		||||
                A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
 | 
			
		||||
            <li>
 | 
			
		||||
                <b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are 
 | 
			
		||||
                provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
 | 
			
		||||
                and <b>dynamic_cast</b>
 | 
			
		||||
            do for pointers.
 | 
			
		||||
            <li>
 | 
			
		||||
                The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>, 
 | 
			
		||||
                although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>. 
 | 
			
		||||
                Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
 | 
			
		||||
            results in undefined behavior (an assertion, or eventually a double-delete if 
 | 
			
		||||
            assertions are off).
 | 
			
		||||
            <li>
 | 
			
		||||
                The <b>BOOST_SMART_PTR_CONVERSION</b>
 | 
			
		||||
            feature has been removed.
 | 
			
		||||
            <li>
 | 
			
		||||
                <b>shared_ptr<void></b> is now allowed.</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
        <h2>Features That Improve Robustness</h2>
 | 
			
		||||
        <ul>
 | 
			
		||||
            <li>
 | 
			
		||||
                The manipulation of use counts is now <a name="threadsafe">thread safe</a> on 
 | 
			
		||||
                Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
 | 
			
		||||
                    <boost/detail/atomic_count.hpp></a>
 | 
			
		||||
            file for details
 | 
			
		||||
            <li>
 | 
			
		||||
                The new shared_ptr will always delete the object using the pointer it was 
 | 
			
		||||
                originally constructed with. This prevents subtle problems that could happen if 
 | 
			
		||||
                the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did 
 | 
			
		||||
                not have a virtual destructor.</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
        <h2>Implementation Details</h2>
 | 
			
		||||
        <ul>
 | 
			
		||||
            <li>
 | 
			
		||||
                Some bugs in the assignment operator implementations and in <b>reset</b>
 | 
			
		||||
            have been fixed by using the "copy and swap" idiom.
 | 
			
		||||
            <li>
 | 
			
		||||
                Assertions have been added to check preconditions of various functions; 
 | 
			
		||||
                however, since these use the new <a href="../../boost/assert.hpp"><boost/assert.hpp></a>
 | 
			
		||||
            header, the assertions are disabled by default.
 | 
			
		||||
            <li>
 | 
			
		||||
                The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
 | 
			
		||||
            overloads which accomplish the same thing without relying on undefined 
 | 
			
		||||
            behavior.
 | 
			
		||||
            <li>
 | 
			
		||||
                The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, 
 | 
			
		||||
                which has many of the same advantages for generic programming but does not 
 | 
			
		||||
                violate the C++ standard.</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p><small>Copyright 2002 Darin Adler. 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>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>Smart Pointer Changes</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="#ffffff" text="#000000">
 | 
			
		||||
		<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
 | 
			
		||||
					border="0"></A>Smart Pointer Changes</h1>
 | 
			
		||||
		<p>The February 2002 change to the Boost smart pointers introduced a number of 
 | 
			
		||||
			changes. Since the previous version of the smart pointers was in use for a long 
 | 
			
		||||
			time, it's useful to have a detailed list of what changed from a library user's 
 | 
			
		||||
			point of view.</p>
 | 
			
		||||
		<p>Note that for compilers that don't support member templates well enough, a 
 | 
			
		||||
			separate implementation is used that lacks many of the new features and is more 
 | 
			
		||||
			like the old version.</p>
 | 
			
		||||
		<h2>Features Requiring Code Changes to Take Advantage</h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				The smart pointer class templates now each have their own header file. For 
 | 
			
		||||
				compatibility, the <a href="../../boost/smart_ptr.hpp"><boost/smart_ptr.hpp></a>
 | 
			
		||||
			header now includes the headers for the four classic smart pointer class 
 | 
			
		||||
			templates.
 | 
			
		||||
			<li>
 | 
			
		||||
				The <b>weak_ptr</b>
 | 
			
		||||
			template was added.
 | 
			
		||||
			<li>
 | 
			
		||||
				The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that 
 | 
			
		||||
				the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
 | 
			
		||||
			destructor. This makes it easier to have shared_ptr members in classes without 
 | 
			
		||||
			explicit destructors.
 | 
			
		||||
			<li>
 | 
			
		||||
				A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
 | 
			
		||||
			<li>
 | 
			
		||||
				<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are 
 | 
			
		||||
				provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
 | 
			
		||||
				and <b>dynamic_cast</b>
 | 
			
		||||
			do for pointers.
 | 
			
		||||
			<li>
 | 
			
		||||
				The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>, 
 | 
			
		||||
				although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>. 
 | 
			
		||||
				Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
 | 
			
		||||
			results in undefined behavior (an assertion, or eventually a double-delete if 
 | 
			
		||||
			assertions are off).
 | 
			
		||||
			<li>
 | 
			
		||||
				The <b>BOOST_SMART_PTR_CONVERSION</b>
 | 
			
		||||
			feature has been removed.
 | 
			
		||||
			<li>
 | 
			
		||||
				<b>shared_ptr<void></b> is now allowed.</li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<h2>Features That Improve Robustness</h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				The manipulation of use counts is now <a name="threadsafe">thread safe</a> on 
 | 
			
		||||
				Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
 | 
			
		||||
					<boost/detail/atomic_count.hpp></a>
 | 
			
		||||
			file for details
 | 
			
		||||
			<li>
 | 
			
		||||
				The new shared_ptr will always delete the object using the pointer it was 
 | 
			
		||||
				originally constructed with. This prevents subtle problems that could happen if 
 | 
			
		||||
				the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did 
 | 
			
		||||
				not have a virtual destructor.</li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<h2>Implementation Details</h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				Some bugs in the assignment operator implementations and in <b>reset</b>
 | 
			
		||||
			have been fixed by using the "copy and swap" idiom.
 | 
			
		||||
			<li>
 | 
			
		||||
				Assertions have been added to check preconditions of various functions; 
 | 
			
		||||
				however, since these use the new <a href="../../boost/assert.hpp"><boost/assert.hpp></a>
 | 
			
		||||
			header, the assertions are disabled by default.
 | 
			
		||||
			<li>
 | 
			
		||||
				The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
 | 
			
		||||
			overloads which accomplish the same thing without relying on undefined 
 | 
			
		||||
			behavior.
 | 
			
		||||
			<li>
 | 
			
		||||
				The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, 
 | 
			
		||||
				which has many of the same advantages for generic programming but does not 
 | 
			
		||||
				violate the C++ standard.</li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>Revised 1 February 2002</p>
 | 
			
		||||
		<p><small>Copyright 2002 Darin Adler. 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>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +1,34 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>enable_shared_from_this</title>
 | 
			
		||||
        <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>
 | 
			
		||||
        <h2><a name="Purpose">Purpose</a></h2>
 | 
			
		||||
        <p>
 | 
			
		||||
            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>
 | 
			
		||||
        <h2><a name="Example">Example</a></h2>
 | 
			
		||||
        <pre>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>Boost: enable_shared_from_this.hpp documentation</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
 | 
			
		||||
		<table border="0" width="100%">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
 | 
			
		||||
				</td>
 | 
			
		||||
				<td align="center">
 | 
			
		||||
					<h1>enable_shared_from_this.hpp</h1>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td colspan="2" height="64"> </td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</table>
 | 
			
		||||
		<h3><a name="Purpose">Purpose</a></h3>
 | 
			
		||||
		<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.
 | 
			
		||||
		</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>
 | 
			
		||||
		<h3><a name="Example">Example</a></h3>
 | 
			
		||||
		<pre>
 | 
			
		||||
#include <boost/enable_shared_from_this.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
@@ -45,8 +51,8 @@ int main()
 | 
			
		||||
    assert(!(p < q || q < p)); // p and q must share ownership
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><a name="Synopsis">Synopsis</a></h2>
 | 
			
		||||
        <pre>
 | 
			
		||||
		<h3><a name="Synopsis">Synopsis</a></h3>
 | 
			
		||||
		<pre>
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@@ -56,55 +62,34 @@ 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><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> <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, a <code>shared_ptr<T></code> instance <code>r</code> that shares 
 | 
			
		||||
                ownership with <code>p</code>.
 | 
			
		||||
            </p>
 | 
			
		||||
            <p>
 | 
			
		||||
                <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>
 | 
			
		||||
        <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, 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>
 | 
			
		||||
		<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>
 | 
			
		||||
		<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>.
 | 
			
		||||
			</p>
 | 
			
		||||
			<p>
 | 
			
		||||
				<b>Returns:</b> A <b>shared_ptr<T></b> instance <b>r</b> that shares 
 | 
			
		||||
				ownership with <b>p</b>.
 | 
			
		||||
			</p>
 | 
			
		||||
			<p>
 | 
			
		||||
				<b>Postconditions:</b> <tt>r.get() == this</tt>.
 | 
			
		||||
			</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<p>
 | 
			
		||||
			<br>
 | 
			
		||||
			<small>Copyright <20> 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>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,135 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  boost/detail/lightweight_thread.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2008 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>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <cerrno>
 | 
			
		||||
 | 
			
		||||
// pthread_create, pthread_join
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <process.h>
 | 
			
		||||
 | 
			
		||||
typedef HANDLE pthread_t;
 | 
			
		||||
 | 
			
		||||
int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
 | 
			
		||||
{
 | 
			
		||||
    HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
 | 
			
		||||
 | 
			
		||||
    if( h != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        *thread = h;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return EAGAIN;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pthread_join( pthread_t thread, void ** /*value_ptr*/ )
 | 
			
		||||
{
 | 
			
		||||
    ::WaitForSingleObject( thread, INFINITE );
 | 
			
		||||
    ::CloseHandle( thread );
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// template<class F> int lw_thread_create( pthread_t & pt, F f );
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class lw_abstract_thread
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual ~lw_abstract_thread() {}
 | 
			
		||||
    virtual void run() = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
 | 
			
		||||
extern "C" void * lw_thread_routine( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
 | 
			
		||||
 | 
			
		||||
    pt->run();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
unsigned __stdcall lw_thread_routine( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
 | 
			
		||||
 | 
			
		||||
    pt->run();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class F> class lw_thread_impl: public lw_abstract_thread
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit lw_thread_impl( F f ): f_( f )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void run()
 | 
			
		||||
    {
 | 
			
		||||
        f_();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    F f_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class F> int lw_thread_create( pthread_t & pt, F f )
 | 
			
		||||
{
 | 
			
		||||
    std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
 | 
			
		||||
 | 
			
		||||
    int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );
 | 
			
		||||
 | 
			
		||||
    if( r == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        p.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/quick_allocator.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2003 David Abrahams
 | 
			
		||||
//  Copyright (c) 2003 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/detail/quick_allocator.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										135
									
								
								include/boost/detail/sp_typeinfo.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								include/boost/detail/sp_typeinfo.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_typeinfo.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007 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( BOOST_NO_TYPEID )
 | 
			
		||||
 | 
			
		||||
#include <boost/current_function.hpp>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class sp_typeinfo
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_typeinfo( sp_typeinfo const& );
 | 
			
		||||
    sp_typeinfo& operator=( sp_typeinfo const& );
 | 
			
		||||
 | 
			
		||||
    char const * name_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit sp_typeinfo( char const * name ): name_( name )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator==( sp_typeinfo const& rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return this == &rhs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator!=( sp_typeinfo const& rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return this != &rhs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool before( sp_typeinfo const& rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return std::less< sp_typeinfo const* >()( this, &rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char const* name() const
 | 
			
		||||
    {
 | 
			
		||||
        return name_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> struct sp_typeid_
 | 
			
		||||
{
 | 
			
		||||
    static sp_typeinfo ti_;
 | 
			
		||||
 | 
			
		||||
    static char const * name()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_CURRENT_FUNCTION;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__SUNPRO_CC)
 | 
			
		||||
// see #4199, the Sun Studio compiler gets confused about static initialization 
 | 
			
		||||
// constructor arguments. But an assignment works just fine. 
 | 
			
		||||
template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
 | 
			
		||||
#else
 | 
			
		||||
template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_NO_STD_TYPEINFO )
 | 
			
		||||
 | 
			
		||||
typedef ::type_info sp_typeinfo;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
typedef std::type_info sp_typeinfo;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_SP_TYPEID(T) typeid(T)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										33
									
								
								include/boost/get_pointer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								include/boost/get_pointer.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
// Copyright Peter Dimov and David Abrahams 2002.
 | 
			
		||||
// 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)
 | 
			
		||||
#ifndef GET_POINTER_DWA20021219_HPP
 | 
			
		||||
# define GET_POINTER_DWA20021219_HPP
 | 
			
		||||
 | 
			
		||||
// In order to avoid circular dependencies with Boost.TR1
 | 
			
		||||
// we make sure that our include of <memory> doesn't try to
 | 
			
		||||
// pull in the TR1 headers: that's why we use this header 
 | 
			
		||||
// rather than including <memory> directly:
 | 
			
		||||
# include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
 | 
			
		||||
 | 
			
		||||
namespace boost { 
 | 
			
		||||
 | 
			
		||||
// get_pointer(p) extracts a ->* capable pointer from p
 | 
			
		||||
 | 
			
		||||
template<class T> T * get_pointer(T * p)
 | 
			
		||||
{
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer(shared_ptr<T> const & p) has been moved to shared_ptr.hpp
 | 
			
		||||
 | 
			
		||||
template<class T> T * get_pointer(std::auto_ptr<T> const& p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // GET_POINTER_DWA20021219_HPP
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_MAKE_UNIQUE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_MAKE_UNIQUE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/make_unique.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										53
									
								
								include/boost/memory_order.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								include/boost/memory_order.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
 | 
			
		||||
#define BOOST_MEMORY_ORDER_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  boost/memory_order.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Defines enum boost::memory_order per the C++0x working draft
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008, 2009 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)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Enum values are chosen so that code that needs to insert
 | 
			
		||||
// a trailing fence for acquire semantics can use a single
 | 
			
		||||
// test such as:
 | 
			
		||||
//
 | 
			
		||||
// if( mo & memory_order_acquire ) { ...fence... }
 | 
			
		||||
//
 | 
			
		||||
// For leading fences one can use:
 | 
			
		||||
//
 | 
			
		||||
// if( mo & memory_order_release ) { ...fence... }
 | 
			
		||||
//
 | 
			
		||||
// Architectures such as Alpha that need a fence on consume
 | 
			
		||||
// can use:
 | 
			
		||||
//
 | 
			
		||||
// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
enum memory_order
 | 
			
		||||
{
 | 
			
		||||
    memory_order_relaxed = 0,
 | 
			
		||||
    memory_order_acquire = 1,
 | 
			
		||||
    memory_order_release = 2,
 | 
			
		||||
    memory_order_acq_rel = 3, // acquire | release
 | 
			
		||||
    memory_order_seq_cst = 7, // acq_rel | 4
 | 
			
		||||
    memory_order_consume = 8
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
 | 
			
		||||
@@ -1,181 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/array_count_impl.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    template<class T, class A>
 | 
			
		||||
    inline typename boost::detail::sp_if_array<T>::type
 | 
			
		||||
    allocate_shared(const A& allocator, std::size_t size) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_init_tag R1;
 | 
			
		||||
        typedef boost::detail::as_allocator<A, T, R1> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        std::size_t n1 = size * boost::detail::array_total<T1>::size;
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(allocator, size, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
        boost::detail::as_init(allocator, p2, n1);
 | 
			
		||||
#else
 | 
			
		||||
        boost::detail::ms_init(p2, n1);
 | 
			
		||||
#endif
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T, class A>
 | 
			
		||||
    inline typename boost::detail::sp_if_size_array<T>::type
 | 
			
		||||
    allocate_shared(const A& allocator) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_init_tag R1;
 | 
			
		||||
        typedef boost::detail::as_allocator<A, T, R1> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            N = boost::detail::array_total<T>::size
 | 
			
		||||
        };
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(allocator, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
        boost::detail::as_init(allocator, p2, N);
 | 
			
		||||
#else
 | 
			
		||||
        boost::detail::ms_init(p2, N);
 | 
			
		||||
#endif
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T, class A>
 | 
			
		||||
    inline typename boost::detail::sp_if_array<T>::type
 | 
			
		||||
    allocate_shared(const A& allocator, std::size_t size,
 | 
			
		||||
        const typename boost::detail::array_inner<T>::type& value) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef const T2 T3;
 | 
			
		||||
        typedef boost::detail::ms_init_tag R1;
 | 
			
		||||
        typedef boost::detail::as_allocator<A, T, R1> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            M = boost::detail::array_total<T1>::size
 | 
			
		||||
        };
 | 
			
		||||
        std::size_t n1 = M * size;
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        T3* p3 = reinterpret_cast<T3*>(&value);
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(allocator, size, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
        boost::detail::as_init<T2, A, M>(allocator, p2, n1, p3);
 | 
			
		||||
#else
 | 
			
		||||
        boost::detail::ms_init<T2, M>(p2, n1, p3);
 | 
			
		||||
#endif
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T, class A>
 | 
			
		||||
    inline typename boost::detail::sp_if_size_array<T>::type
 | 
			
		||||
    allocate_shared(const A& allocator, 
 | 
			
		||||
        const typename boost::detail::array_inner<T>::type& value) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef const T2 T3;
 | 
			
		||||
        typedef boost::detail::ms_init_tag R1;
 | 
			
		||||
        typedef boost::detail::as_allocator<A, T, R1> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            N = boost::detail::array_total<T>::size,
 | 
			
		||||
            M = boost::detail::array_total<T1>::size
 | 
			
		||||
        };
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        T3* p3 = reinterpret_cast<T3*>(&value);
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(allocator, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
        boost::detail::as_init<T2, A, M>(allocator, p2, N, p3);
 | 
			
		||||
#else
 | 
			
		||||
        boost::detail::ms_init<T2,  M>(p2, N, p3);
 | 
			
		||||
#endif
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T, class A>
 | 
			
		||||
    inline typename boost::detail::sp_if_array<T>::type
 | 
			
		||||
    allocate_shared_noinit(const A& allocator, std::size_t size) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_noinit_tag R1;
 | 
			
		||||
        typedef boost::detail::as_allocator<A, T, R1> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        std::size_t n1 = size * boost::detail::array_total<T1>::size;
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(allocator, size, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_noinit(p2, n1);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T, class A>
 | 
			
		||||
    inline typename boost::detail::sp_if_size_array<T>::type
 | 
			
		||||
    allocate_shared_noinit(const A& allocator) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_noinit_tag R1;
 | 
			
		||||
        typedef boost::detail::as_allocator<A, T, R1> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            N = boost::detail::array_total<T>::size
 | 
			
		||||
        };
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(allocator, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_noinit(p2, N);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,318 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/align/align.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/array_traits.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/array_utility.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    namespace detail {
 | 
			
		||||
        struct ms_init_tag   { };
 | 
			
		||||
        struct ms_noinit_tag { };
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct ms_allocator_state;
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct ms_allocator_state<T[]> {
 | 
			
		||||
            typedef typename array_base<T>::type type;
 | 
			
		||||
 | 
			
		||||
            ms_allocator_state(std::size_t size_,
 | 
			
		||||
                type** result_)
 | 
			
		||||
                : size(size_ * array_total<T>::size),
 | 
			
		||||
                  result(result_) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            std::size_t size;
 | 
			
		||||
 | 
			
		||||
            union {
 | 
			
		||||
                type** result;
 | 
			
		||||
                type* object;
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T, std::size_t N>
 | 
			
		||||
        struct ms_allocator_state<T[N]> {
 | 
			
		||||
            typedef typename array_base<T>::type type;
 | 
			
		||||
 | 
			
		||||
            ms_allocator_state(type** result_)
 | 
			
		||||
                : result(result_) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            enum {
 | 
			
		||||
                size = array_total<T[N]>::size
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            union {
 | 
			
		||||
                type** result;
 | 
			
		||||
                type* object;
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class A, class T, class R>
 | 
			
		||||
        class as_allocator
 | 
			
		||||
            : public A {
 | 
			
		||||
            template<class A_, class T_, class R_>
 | 
			
		||||
            friend class as_allocator;
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
            typedef std::allocator_traits<A> AT;
 | 
			
		||||
            typedef typename AT::template rebind_alloc<char> CA;
 | 
			
		||||
            typedef typename AT::template rebind_traits<char> CT;
 | 
			
		||||
#else
 | 
			
		||||
            typedef typename A::template rebind<char>::other CA;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        public:
 | 
			
		||||
            typedef A allocator_type;
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
            typedef typename AT::value_type value_type;
 | 
			
		||||
            typedef typename AT::pointer pointer;
 | 
			
		||||
            typedef typename AT::const_pointer const_pointer;
 | 
			
		||||
            typedef typename AT::void_pointer void_pointer;
 | 
			
		||||
            typedef typename AT::const_void_pointer const_void_pointer;
 | 
			
		||||
            typedef typename AT::size_type size_type;
 | 
			
		||||
            typedef typename AT::difference_type difference_type;
 | 
			
		||||
#else
 | 
			
		||||
            typedef typename A::value_type value_type;
 | 
			
		||||
            typedef typename A::pointer pointer;
 | 
			
		||||
            typedef typename A::const_pointer const_pointer;
 | 
			
		||||
            typedef typename A::size_type size_type;
 | 
			
		||||
            typedef typename A::difference_type difference_type;
 | 
			
		||||
            typedef typename A::reference reference;
 | 
			
		||||
            typedef typename A::const_reference const_reference;
 | 
			
		||||
            typedef void* void_pointer;
 | 
			
		||||
            typedef const void* const_void_pointer;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            template<class U>
 | 
			
		||||
            struct rebind {
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
                typedef as_allocator<typename AT::
 | 
			
		||||
                    template rebind_alloc<U>, T, R> other;
 | 
			
		||||
#else
 | 
			
		||||
                typedef as_allocator<typename A::
 | 
			
		||||
                    template rebind<U>::other, T, R> other;
 | 
			
		||||
#endif
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            typedef typename array_base<T>::type type;
 | 
			
		||||
 | 
			
		||||
            as_allocator(const A& allocator_, type** result)
 | 
			
		||||
                : A(allocator_),
 | 
			
		||||
                  data(result) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            as_allocator(const A& allocator_, std::size_t size,
 | 
			
		||||
                type** result)
 | 
			
		||||
                : A(allocator_),
 | 
			
		||||
                  data(size, result) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            template<class U>
 | 
			
		||||
            as_allocator(const as_allocator<U, T, R>& other)
 | 
			
		||||
                : A(other.allocator()),
 | 
			
		||||
                  data(other.data) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pointer allocate(size_type count, const_void_pointer = 0) {
 | 
			
		||||
                enum {
 | 
			
		||||
                    M = boost::alignment_of<type>::value
 | 
			
		||||
                };
 | 
			
		||||
                std::size_t n1 = count * sizeof(value_type);
 | 
			
		||||
                std::size_t n2 = data.size * sizeof(type);
 | 
			
		||||
                std::size_t n3 = n2 + M;
 | 
			
		||||
                CA ca(allocator());
 | 
			
		||||
                void* p1 = ca.allocate(n1 + n3);
 | 
			
		||||
                void* p2 = static_cast<char*>(p1) + n1;
 | 
			
		||||
                (void)boost::alignment::align(M, n2, p2, n3);
 | 
			
		||||
                *data.result = static_cast<type*>(p2);
 | 
			
		||||
                return static_cast<value_type*>(p1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void deallocate(pointer memory, size_type count) {
 | 
			
		||||
                enum {
 | 
			
		||||
                    M = boost::alignment_of<type>::value
 | 
			
		||||
                };
 | 
			
		||||
                std::size_t n1 = count * sizeof(value_type);
 | 
			
		||||
                std::size_t n2 = data.size * sizeof(type) + M;
 | 
			
		||||
                char* p1 = reinterpret_cast<char*>(memory);
 | 
			
		||||
                CA ca(allocator());
 | 
			
		||||
                ca.deallocate(p1, n1 + n2);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const A& allocator() const {
 | 
			
		||||
                return static_cast<const A&>(*this);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            A& allocator() {
 | 
			
		||||
                return static_cast<A&>(*this);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void set(type* memory) {
 | 
			
		||||
                data.object = memory;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void operator()() {
 | 
			
		||||
                if (data.object) {
 | 
			
		||||
                    R tag;
 | 
			
		||||
                    release(tag);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        private:
 | 
			
		||||
            void release(ms_init_tag) {
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
                as_destroy(allocator(), data.object, data.size);
 | 
			
		||||
#else
 | 
			
		||||
                ms_destroy(data.object, data.size);
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void release(ms_noinit_tag) {
 | 
			
		||||
                ms_destroy(data.object, data.size);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ms_allocator_state<T> data;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class A1, class A2, class T, class R>
 | 
			
		||||
        bool operator==(const as_allocator<A1, T, R>& a1,
 | 
			
		||||
            const as_allocator<A2, T, R>& a2) {
 | 
			
		||||
            return a1.allocator() == a2.allocator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class A1, class A2, class T, class R>
 | 
			
		||||
        bool operator!=(const as_allocator<A1, T, R>& a1,
 | 
			
		||||
            const as_allocator<A2, T, R>& a2) {
 | 
			
		||||
            return a1.allocator() != a2.allocator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T, class Y = char>
 | 
			
		||||
        class ms_allocator;
 | 
			
		||||
 | 
			
		||||
        template<class T, class Y>
 | 
			
		||||
        class ms_allocator {
 | 
			
		||||
            template<class T_, class Y_>
 | 
			
		||||
            friend class ms_allocator;
 | 
			
		||||
 | 
			
		||||
        public:
 | 
			
		||||
            typedef typename array_base<T>::type type;
 | 
			
		||||
 | 
			
		||||
            typedef Y value_type;
 | 
			
		||||
            typedef Y* pointer;
 | 
			
		||||
            typedef const Y* const_pointer;
 | 
			
		||||
            typedef std::size_t size_type;
 | 
			
		||||
            typedef std::ptrdiff_t difference_type;
 | 
			
		||||
            typedef Y& reference;
 | 
			
		||||
            typedef const Y& const_reference;
 | 
			
		||||
 | 
			
		||||
            template<class U>
 | 
			
		||||
            struct rebind {
 | 
			
		||||
                typedef ms_allocator<T, U> other;
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            ms_allocator(type** result)
 | 
			
		||||
                : data(result) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ms_allocator(std::size_t size, type** result)
 | 
			
		||||
                : data(size, result) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            template<class U>
 | 
			
		||||
            ms_allocator(const ms_allocator<T, U>& other)
 | 
			
		||||
                : data(other.data) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pointer allocate(size_type count, const void* = 0) {
 | 
			
		||||
                enum {
 | 
			
		||||
                    M = boost::alignment_of<type>::value
 | 
			
		||||
                };
 | 
			
		||||
                std::size_t n1 = count * sizeof(Y);
 | 
			
		||||
                std::size_t n2 = data.size * sizeof(type);
 | 
			
		||||
                std::size_t n3 = n2 + M;
 | 
			
		||||
                void* p1 = ::operator new(n1 + n3);
 | 
			
		||||
                void* p2 = static_cast<char*>(p1) + n1;
 | 
			
		||||
                (void)boost::alignment::align(M, n2, p2, n3);
 | 
			
		||||
                *data.result = static_cast<type*>(p2);
 | 
			
		||||
                return static_cast<Y*>(p1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void deallocate(pointer memory, size_type) {
 | 
			
		||||
                void* p1 = memory;
 | 
			
		||||
                ::operator delete(p1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
            pointer address(reference value) const {
 | 
			
		||||
                return &value;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const_pointer address(const_reference value) const {
 | 
			
		||||
                return &value;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            size_type max_size() const {
 | 
			
		||||
                enum {
 | 
			
		||||
                    N = static_cast<std::size_t>(-1) / sizeof(Y)
 | 
			
		||||
                };
 | 
			
		||||
                return N;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void construct(pointer memory, const_reference value) {
 | 
			
		||||
                void* p1 = memory;
 | 
			
		||||
                ::new(p1) Y(value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void destroy(pointer memory) {
 | 
			
		||||
                (void)memory;
 | 
			
		||||
                memory->~Y();
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            void set(type* memory) {
 | 
			
		||||
                data.object = memory;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void operator()() {
 | 
			
		||||
                if (data.object) {
 | 
			
		||||
                    ms_destroy(data.object, data.size);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        private:
 | 
			
		||||
            ms_allocator_state<T> data;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T, class Y1, class Y2>
 | 
			
		||||
        bool operator==(const ms_allocator<T, Y1>&,
 | 
			
		||||
            const ms_allocator<T, Y2>&) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T, class Y1, class Y2>
 | 
			
		||||
        bool operator!=(const ms_allocator<T, Y1>&,
 | 
			
		||||
            const ms_allocator<T, Y2>&) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        class ms_in_allocator_tag {
 | 
			
		||||
        public:
 | 
			
		||||
            void operator()(const void*) {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,67 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/array_allocator.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    namespace detail {
 | 
			
		||||
        template<class P, class A>
 | 
			
		||||
        class sp_counted_impl_pda<P, ms_in_allocator_tag, A>
 | 
			
		||||
            : public sp_counted_base {
 | 
			
		||||
            typedef ms_in_allocator_tag D;
 | 
			
		||||
            typedef sp_counted_impl_pda<P, D, A> Y;
 | 
			
		||||
        public:
 | 
			
		||||
            sp_counted_impl_pda(P, D, const A& allocator_)
 | 
			
		||||
                : allocator(allocator_) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            virtual void dispose() {
 | 
			
		||||
                allocator();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            virtual void destroy() {
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
                typedef typename std::allocator_traits<A>::
 | 
			
		||||
                    template rebind_alloc<Y> YA;
 | 
			
		||||
                typedef typename std::allocator_traits<A>::
 | 
			
		||||
                    template rebind_traits<Y> YT;
 | 
			
		||||
#else
 | 
			
		||||
                typedef typename A::template rebind<Y>::other YA;
 | 
			
		||||
#endif
 | 
			
		||||
                YA a1(allocator);
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
                YT::destroy(a1, this);
 | 
			
		||||
                YT::deallocate(a1, this, 1);
 | 
			
		||||
#else
 | 
			
		||||
                this->~Y();
 | 
			
		||||
                a1.deallocate(this, 1);
 | 
			
		||||
#endif                
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            virtual void* get_deleter(const sp_typeinfo&) {
 | 
			
		||||
                return &reinterpret_cast<char&>(allocator);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            virtual void* get_untyped_deleter() {
 | 
			
		||||
                return &reinterpret_cast<char&>(allocator);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        private:
 | 
			
		||||
            sp_counted_impl_pda(const sp_counted_impl_pda&);
 | 
			
		||||
            sp_counted_impl_pda& operator=(const sp_counted_impl_pda&);
 | 
			
		||||
 | 
			
		||||
            A allocator;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/type_traits/remove_cv.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    namespace detail {
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct array_base {
 | 
			
		||||
            typedef typename boost::remove_cv<T>::type type;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct array_base<T[]> {
 | 
			
		||||
            typedef typename array_base<T>::type type;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T, std::size_t N>
 | 
			
		||||
        struct array_base<T[N]> {
 | 
			
		||||
            typedef typename array_base<T>::type type;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct array_total {
 | 
			
		||||
            enum {
 | 
			
		||||
                size = 1
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T, std::size_t N>
 | 
			
		||||
        struct array_total<T[N]> {
 | 
			
		||||
            enum {
 | 
			
		||||
                size = N * array_total<T>::size
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct array_inner;
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct array_inner<T[]> {
 | 
			
		||||
            typedef T type;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T, std::size_t N>
 | 
			
		||||
        struct array_inner<T[N]> {
 | 
			
		||||
            typedef T type;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,214 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/type_traits/has_trivial_constructor.hpp>
 | 
			
		||||
#include <boost/type_traits/has_trivial_destructor.hpp>
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
#include <memory>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    namespace detail {
 | 
			
		||||
        typedef boost::true_type  ms_is_trivial;
 | 
			
		||||
        typedef boost::false_type ms_no_trivial;
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_destroy(T*, std::size_t, ms_is_trivial) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) {
 | 
			
		||||
            for (std::size_t i = size; i > 0;) {
 | 
			
		||||
                memory[--i].~T();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_destroy(T* memory, std::size_t size) {
 | 
			
		||||
            boost::has_trivial_destructor<T> trivial;
 | 
			
		||||
            ms_destroy(memory, size, trivial);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_init(T* memory, std::size_t size, ms_is_trivial) {
 | 
			
		||||
            for (std::size_t i = 0; i < size; i++) {
 | 
			
		||||
                void* p1 = memory + i;
 | 
			
		||||
                ::new(p1) T();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_init(T* memory, std::size_t size, ms_no_trivial) {
 | 
			
		||||
#if !defined(BOOST_NO_EXCEPTIONS)
 | 
			
		||||
            std::size_t i = 0;
 | 
			
		||||
            try {
 | 
			
		||||
                for (; i < size; i++) {
 | 
			
		||||
                    void* p1 = memory + i;
 | 
			
		||||
                    ::new(p1) T();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (...) {
 | 
			
		||||
                ms_destroy(memory, i);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
#else
 | 
			
		||||
            for (std::size_t i = 0; i < size; i++) {
 | 
			
		||||
                void* p1 = memory + i;
 | 
			
		||||
                ::new(p1) T();
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_init(T* memory, std::size_t size) {
 | 
			
		||||
            boost::has_trivial_default_constructor<T> trivial;
 | 
			
		||||
            ms_init(memory, size, trivial);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T, std::size_t N>
 | 
			
		||||
        inline void ms_init(T* memory, std::size_t size, const T* list) {
 | 
			
		||||
#if !defined(BOOST_NO_EXCEPTIONS)
 | 
			
		||||
            std::size_t i = 0;
 | 
			
		||||
            try {
 | 
			
		||||
                for (; i < size; i++) {
 | 
			
		||||
                    void* p1 = memory + i;
 | 
			
		||||
                    ::new(p1) T(list[i % N]);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (...) {
 | 
			
		||||
                ms_destroy(memory, i);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
#else
 | 
			
		||||
            for (std::size_t i = 0; i < size; i++) {
 | 
			
		||||
                void* p1 = memory + i;
 | 
			
		||||
                ::new(p1) T(list[i % N]);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
        template<class T, class A>
 | 
			
		||||
        inline void as_destroy(const A& allocator, T* memory,
 | 
			
		||||
            std::size_t size) {
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_alloc<T> TA;
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_traits<T> TT;
 | 
			
		||||
            TA a2(allocator);
 | 
			
		||||
            for (std::size_t i = size; i > 0;) {
 | 
			
		||||
                TT::destroy(a2, &memory[--i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T, class A>
 | 
			
		||||
        inline void as_init(const A& allocator, T* memory, std::size_t size,
 | 
			
		||||
            ms_is_trivial) {
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_alloc<T> TA;
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_traits<T> TT;
 | 
			
		||||
            TA a2(allocator);
 | 
			
		||||
            for (std::size_t i = 0; i < size; i++) {
 | 
			
		||||
                TT::construct(a2, memory + i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T, class A>
 | 
			
		||||
        inline void as_init(const A& allocator, T* memory, std::size_t size,
 | 
			
		||||
            ms_no_trivial) {
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_alloc<T> TA;
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_traits<T> TT;
 | 
			
		||||
            TA a2(allocator);
 | 
			
		||||
#if !defined(BOOST_NO_EXCEPTIONS)
 | 
			
		||||
            std::size_t i = 0;
 | 
			
		||||
            try {
 | 
			
		||||
                for (; i < size; i++) {
 | 
			
		||||
                    TT::construct(a2, memory + i);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (...) {
 | 
			
		||||
                as_destroy(a2, memory, i);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
#else
 | 
			
		||||
            for (std::size_t i = 0; i < size; i++) {
 | 
			
		||||
                TT::construct(a2, memory + i);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T, class A>
 | 
			
		||||
        inline void as_init(const A& allocator, T* memory, std::size_t size) {
 | 
			
		||||
            boost::has_trivial_default_constructor<T> trivial;
 | 
			
		||||
            as_init(allocator, memory, size, trivial);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T, class A, std::size_t N>
 | 
			
		||||
        inline void as_init(const A& allocator, T* memory, std::size_t size,
 | 
			
		||||
            const T* list) {
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_alloc<T> TA;
 | 
			
		||||
            typedef typename std::allocator_traits<A>::
 | 
			
		||||
                template rebind_traits<T> TT;
 | 
			
		||||
            TA a2(allocator);
 | 
			
		||||
#if !defined(BOOST_NO_EXCEPTIONS)
 | 
			
		||||
            std::size_t i = 0;
 | 
			
		||||
            try {
 | 
			
		||||
                for (; i < size; i++) {
 | 
			
		||||
                    TT::construct(a2, memory + i, list[i % N]);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (...) {
 | 
			
		||||
                as_destroy(a2, memory, i);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
#else
 | 
			
		||||
            for (std::size_t i = 0; i < size; i++) {
 | 
			
		||||
                TT::construct(a2, memory + i, list[i % N]);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_noinit(T*, std::size_t, ms_is_trivial) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) {
 | 
			
		||||
#if !defined(BOOST_NO_EXCEPTIONS)
 | 
			
		||||
            std::size_t i = 0;
 | 
			
		||||
            try {
 | 
			
		||||
                for (; i < size; i++) {
 | 
			
		||||
                    void* p1 = memory + i;
 | 
			
		||||
                    ::new(p1) T;
 | 
			
		||||
                }
 | 
			
		||||
            } catch (...) {
 | 
			
		||||
                ms_destroy(memory, i);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
#else
 | 
			
		||||
            for (std::size_t i = 0; i < size; i++) {
 | 
			
		||||
                void* p1 = memory + i;
 | 
			
		||||
                ::new(p1) T;
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        inline void ms_noinit(T* memory, std::size_t size) {
 | 
			
		||||
            boost::has_trivial_default_constructor<T> trivial;
 | 
			
		||||
            ms_noinit(memory, size, trivial);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -11,11 +11,10 @@
 | 
			
		||||
//  boost/detail/atomic_count.hpp - thread/SMP safe reference counter
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2013 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
 | 
			
		||||
// 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)
 | 
			
		||||
//
 | 
			
		||||
//  typedef <implementation-defined> boost::detail::atomic_count;
 | 
			
		||||
//
 | 
			
		||||
@@ -28,68 +27,92 @@
 | 
			
		||||
//  a;
 | 
			
		||||
//
 | 
			
		||||
//    Returns: (long) the current value of a
 | 
			
		||||
//    Memory Ordering: acquire
 | 
			
		||||
//
 | 
			
		||||
//  ++a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically increments the value of a
 | 
			
		||||
//    Returns: (long) the new value of a
 | 
			
		||||
//    Memory Ordering: acquire/release
 | 
			
		||||
//
 | 
			
		||||
//  --a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically decrements the value of a
 | 
			
		||||
//    Returns: (long) the new value of a
 | 
			
		||||
//    Memory Ordering: acquire/release
 | 
			
		||||
//
 | 
			
		||||
//    Important note: when --a returns zero, it must act as a
 | 
			
		||||
//      read memory barrier (RMB); i.e. the calling thread must
 | 
			
		||||
//      have a synchronized view of the memory
 | 
			
		||||
//
 | 
			
		||||
//    On Intel IA-32 (x86) memory is always synchronized, so this
 | 
			
		||||
//      is not a problem.
 | 
			
		||||
//
 | 
			
		||||
//    On many architectures the atomic instructions already act as
 | 
			
		||||
//      a memory barrier.
 | 
			
		||||
//
 | 
			
		||||
//    This property is necessary for proper reference counting, since
 | 
			
		||||
//      a thread can update the contents of a shared object, then
 | 
			
		||||
//      release its reference, and another thread may immediately
 | 
			
		||||
//      release the last reference causing object destruction.
 | 
			
		||||
//
 | 
			
		||||
//    The destructor needs to have a synchronized view of the
 | 
			
		||||
//      object to perform proper cleanup.
 | 
			
		||||
//
 | 
			
		||||
//    Original example by Alexander Terekhov:
 | 
			
		||||
//
 | 
			
		||||
//    Given:
 | 
			
		||||
//
 | 
			
		||||
//    - a mutable shared object OBJ;
 | 
			
		||||
//    - two threads THREAD1 and THREAD2 each holding 
 | 
			
		||||
//      a private smart_ptr object pointing to that OBJ.
 | 
			
		||||
//
 | 
			
		||||
//    t1: THREAD1 updates OBJ (thread-safe via some synchronization)
 | 
			
		||||
//      and a few cycles later (after "unlock") destroys smart_ptr;
 | 
			
		||||
//
 | 
			
		||||
//    t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization 
 | 
			
		||||
//      with respect to shared mutable object OBJ; OBJ destructors
 | 
			
		||||
//      are called driven by smart_ptr interface...
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_AC_DISABLE_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
#ifndef BOOST_HAS_THREADS
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_AC_USE_STD_ATOMIC )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_AC_USE_SPINLOCK )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_AC_USE_PTHREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
 | 
			
		||||
typedef long atomic_count;
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_DISABLE_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_STD_ATOMIC )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_SPINLOCK )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 | 
			
		||||
#elif defined(BOOST_AC_USE_PTHREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_SYNC )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_win32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_SYNC )
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_HAS_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
 | 
			
		||||
#  define BOOST_AC_USE_PTHREADS
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 | 
			
		||||
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
#error Unrecognized threading platform
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_nt.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Trivial atomic_count for the single-threaded case
 | 
			
		||||
//
 | 
			
		||||
//  http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2013 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
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return ++value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return --value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
 | 
			
		||||
@@ -11,7 +11,6 @@
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
@@ -38,12 +37,12 @@ private:
 | 
			
		||||
 | 
			
		||||
        scoped_lock(pthread_mutex_t & m): m_(m)
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
            pthread_mutex_lock(&m_);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
            pthread_mutex_unlock(&m_);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
@@ -55,12 +54,12 @@ public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count(long v): value_(v)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
 | 
			
		||||
        pthread_mutex_init(&mutex_, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~atomic_count()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
 | 
			
		||||
        pthread_mutex_destroy(&mutex_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_spin.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2013 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/detail/spinlock_pool.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<0>::scoped_lock lock( &value_ );
 | 
			
		||||
        return ++value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<0>::scoped_lock lock( &value_ );
 | 
			
		||||
        return --value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<0>::scoped_lock lock( &value_ );
 | 
			
		||||
        return value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_std_atomic.hpp
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count for std::atomic
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2013 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 <atomic>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return value_.fetch_add( 1, std::memory_order_acq_rel ) + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return value_.fetch_sub( 1, std::memory_order_acq_rel ) - 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return value_.load( std::memory_order_acquire );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    std::atomic_int_least32_t value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
 | 
			
		||||
#include <boost/detail/interlocked.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -35,12 +35,12 @@ public:
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_SP_INTERLOCKED_INCREMENT( &value_ );
 | 
			
		||||
        return BOOST_INTERLOCKED_INCREMENT( &value_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_SP_INTERLOCKED_DECREMENT( &value_ );
 | 
			
		||||
        return BOOST_INTERLOCKED_DECREMENT( &value_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
 
 | 
			
		||||
@@ -11,15 +11,12 @@
 | 
			
		||||
//  boost/detail/lwm_win32_cs.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov
 | 
			
		||||
//  Copyright (c) Microsoft Corporation 2014
 | 
			
		||||
//
 | 
			
		||||
// 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/predef.h>
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_USE_WINDOWS_H
 | 
			
		||||
#  include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
@@ -46,11 +43,7 @@ struct critical_section
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(critical_section *, unsigned long, unsigned long);
 | 
			
		||||
#else
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
 | 
			
		||||
#endif
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
 | 
			
		||||
@@ -74,11 +67,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex()
 | 
			
		||||
    {
 | 
			
		||||
#if BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
        InitializeCriticalSectionEx(&cs_, 4000, 0);
 | 
			
		||||
#else
 | 
			
		||||
        InitializeCriticalSection(&cs_);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~lightweight_mutex()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,14 @@
 | 
			
		||||
//  This header intentionally has no include guards.
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001-2009, 2012 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2001-2009 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
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
 | 
			
		||||
 | 
			
		||||
    explicit operator bool () const BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return px != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
 | 
			
		||||
 | 
			
		||||
    operator bool () const BOOST_NOEXCEPT
 | 
			
		||||
    operator bool () const
 | 
			
		||||
    {
 | 
			
		||||
        return px != 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -28,7 +21,7 @@
 | 
			
		||||
 | 
			
		||||
    typedef void (*unspecified_bool_type)( this_type*** );
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const BOOST_NOEXCEPT
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: unspecified_bool;
 | 
			
		||||
    }
 | 
			
		||||
@@ -38,18 +31,18 @@
 | 
			
		||||
    ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
 | 
			
		||||
    ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
 | 
			
		||||
 | 
			
		||||
    typedef element_type * (this_type::*unspecified_bool_type)() const;
 | 
			
		||||
    typedef T * (this_type::*unspecified_bool_type)() const;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const BOOST_NOEXCEPT
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::get;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    typedef element_type * this_type::*unspecified_bool_type;
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const BOOST_NOEXCEPT
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::px;
 | 
			
		||||
    }
 | 
			
		||||
@@ -57,7 +50,7 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // operator! is redundant, but some compilers need it
 | 
			
		||||
    bool operator! () const BOOST_NOEXCEPT
 | 
			
		||||
    bool operator! () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										151
									
								
								include/boost/smart_ptr/detail/shared_array_nmt.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								include/boost/smart_ptr/detail/shared_array_nmt.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/shared_array_nmt.hpp - shared_array.hpp without member templates
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 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)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/throw_exception.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstddef>          // for std::ptrdiff_t
 | 
			
		||||
#include <algorithm>        // for std::swap
 | 
			
		||||
#include <functional>       // for std::less
 | 
			
		||||
#include <new>              // for std::bad_alloc
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class shared_array
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    typedef detail::atomic_count count_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
      
 | 
			
		||||
    explicit shared_array(T * p = 0): px(p)
 | 
			
		||||
    {
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try  // prevent leak if new throws
 | 
			
		||||
        {
 | 
			
		||||
            pn = new count_type(1);
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_array_delete(p);
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pn = new count_type(1);
 | 
			
		||||
 | 
			
		||||
        if(pn == 0)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_array_delete(p);
 | 
			
		||||
            boost::throw_exception(std::bad_alloc());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~shared_array()
 | 
			
		||||
    {
 | 
			
		||||
        if(--*pn == 0)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_array_delete(px);
 | 
			
		||||
            delete pn;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_array(shared_array const & r) : px(r.px)  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        ++*pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_array & operator=(shared_array const & r)
 | 
			
		||||
    {
 | 
			
		||||
        shared_array(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px);
 | 
			
		||||
        shared_array(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator[](std::ptrdiff_t i) const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        BOOST_ASSERT(i >= 0);
 | 
			
		||||
        return px[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return *pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool unique() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return *pn == 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(shared_array<T> & other)  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        std::swap(pn, other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * px;            // contained pointer
 | 
			
		||||
    count_type * pn;   // ptr to reference counter
 | 
			
		||||
      
 | 
			
		||||
};  // shared_array
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(shared_array<T> const & a, shared_array<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(shared_array<T> const & a, shared_array<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T*>()(a.get(), b.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
@@ -35,14 +35,7 @@
 | 
			
		||||
// rather than including <memory> directly:
 | 
			
		||||
#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
 | 
			
		||||
#include <functional>       // std::less
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_NO_EXCEPTIONS
 | 
			
		||||
# include <new>              // std::bad_alloc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
 | 
			
		||||
# include <boost/utility/addressof.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#include <new>              // std::bad_alloc
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -63,38 +56,6 @@ template< class D > struct sp_inplace_tag
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
 | 
			
		||||
 | 
			
		||||
template< class T > class sp_reference_wrapper
 | 
			
		||||
{ 
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class Y > void operator()( Y * p ) const
 | 
			
		||||
    {
 | 
			
		||||
        (*t_)( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * t_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class D > struct sp_convert_reference
 | 
			
		||||
{
 | 
			
		||||
    typedef D type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class D > struct sp_convert_reference< D& >
 | 
			
		||||
{
 | 
			
		||||
    typedef sp_reference_wrapper< D > type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class weak_count;
 | 
			
		||||
 | 
			
		||||
class shared_count
 | 
			
		||||
@@ -200,7 +161,7 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
        catch( ... )
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p ); // delete p
 | 
			
		||||
            D()( p ); // delete p
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -210,7 +171,7 @@ public:
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p ); // delete p
 | 
			
		||||
            D()( p ); // delete p
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -225,35 +186,16 @@ public:
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        typedef sp_counted_impl_pda<P, D, A> impl_type;
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        typedef typename A::template rebind< impl_type >::other A2;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        A2 a2( a );
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
            impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
 | 
			
		||||
            pi_ = pi;
 | 
			
		||||
            std::allocator_traits<A2>::construct( a2, pi, p, d, a );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
            new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
@@ -267,30 +209,13 @@ public:
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
 | 
			
		||||
        pi_ = pi;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if( pi_ != 0 )
 | 
			
		||||
        {
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
            std::allocator_traits<A2>::construct( a2, pi, p, d, a );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
            new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
@@ -309,39 +234,20 @@ public:
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        typedef sp_counted_impl_pda< P, D, A > impl_type;
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        typedef typename A::template rebind< impl_type >::other A2;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        A2 a2( a );
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
            impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
 | 
			
		||||
            pi_ = pi;
 | 
			
		||||
            std::allocator_traits<A2>::construct( a2, pi, p, a );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
            new( static_cast< void* >( pi_ ) ) impl_type( p, a );
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p );
 | 
			
		||||
            D()( p );
 | 
			
		||||
 | 
			
		||||
            if( pi_ != 0 )
 | 
			
		||||
            {
 | 
			
		||||
@@ -351,34 +257,17 @@ public:
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
 | 
			
		||||
        pi_ = pi;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if( pi_ != 0 )
 | 
			
		||||
        {
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
            std::allocator_traits<A2>::construct( a2, pi, p, a );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
            new( static_cast< void* >( pi_ ) ) impl_type( p, a );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            D::operator_fn( p );
 | 
			
		||||
            D()( p );
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -411,33 +300,6 @@ public:
 | 
			
		||||
 | 
			
		||||
#endif 
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D>
 | 
			
		||||
    explicit shared_count( std::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 std::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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ~shared_count() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( pi_ != 0 ) pi_->release();
 | 
			
		||||
@@ -454,7 +316,7 @@ public:
 | 
			
		||||
        if( pi_ != 0 ) pi_->add_ref_copy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    shared_count(shared_count && r): pi_(r.pi_) // nothrow
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
@@ -519,11 +381,6 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        return pi_? pi_->get_deleter( ti ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * get_untyped_deleter() const
 | 
			
		||||
    {
 | 
			
		||||
        return pi_? pi_->get_untyped_deleter(): 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -566,7 +423,7 @@ public:
 | 
			
		||||
 | 
			
		||||
// Move support
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    weak_count(weak_count && r): pi_(r.pi_) // nothrow
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										182
									
								
								include/boost/smart_ptr/detail/shared_ptr_nmt.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								include/boost/smart_ptr/detail/shared_ptr_nmt.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,182 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 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)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/throw_exception.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
# include <memory>          // for std::auto_ptr
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <algorithm>        // for std::swap
 | 
			
		||||
#include <functional>       // for std::less
 | 
			
		||||
#include <new>              // for std::bad_alloc
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class shared_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    typedef detail::atomic_count count_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
    typedef T value_type;
 | 
			
		||||
 | 
			
		||||
    explicit shared_ptr(T * p = 0): px(p)
 | 
			
		||||
    {
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try  // prevent leak if new throws
 | 
			
		||||
        {
 | 
			
		||||
            pn = new count_type(1);
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_delete(p);
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pn = new count_type(1);
 | 
			
		||||
 | 
			
		||||
        if(pn == 0)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_delete(p);
 | 
			
		||||
            boost::throw_exception(std::bad_alloc());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~shared_ptr()
 | 
			
		||||
    {
 | 
			
		||||
        if(--*pn == 0)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_delete(px);
 | 
			
		||||
            delete pn;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr(shared_ptr const & r): px(r.px)  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        ++*pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr & operator=(shared_ptr const & r)
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    explicit shared_ptr(std::auto_ptr<T> & r)
 | 
			
		||||
    { 
 | 
			
		||||
        pn = new count_type(1); // may throw
 | 
			
		||||
        px = r.release(); // fix: moved here to stop leak if new throws
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    shared_ptr & operator=(std::auto_ptr<T> & r)
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px);
 | 
			
		||||
        shared_ptr(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator*() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return *px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator->() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return *pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool unique() const  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return *pn == 1;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void swap(shared_ptr<T> & other)  // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        std::swap(pn, other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * px;            // contained pointer
 | 
			
		||||
    count_type * pn;   // ptr to reference counter
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T*>()(a.get(), b.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
 | 
			
		||||
 | 
			
		||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
@@ -16,7 +16,6 @@
 | 
			
		||||
//  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
 | 
			
		||||
@@ -49,21 +48,6 @@ template< class Y, class T > struct sp_convertible
 | 
			
		||||
    enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_convertible< Y, T[] >
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = false };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_convertible< Y[], T[] >
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = sp_convertible< Y[1], T[1] >::value };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = sp_convertible< Y[1], T[1] >::value };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sp_empty
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2005-2013 Peter Dimov
 | 
			
		||||
//  Copyright 2005, 2006 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@@ -20,18 +20,9 @@
 | 
			
		||||
#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>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_STD_ATOMIC )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_SPINLOCK )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -41,31 +32,22 @@
 | 
			
		||||
#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>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__HP_aCC) && defined(__ia64)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __IBMCPP__ ) && defined( __powerpc )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_SYNC )
 | 
			
		||||
@@ -77,9 +59,6 @@
 | 
			
		||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( _AIX )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_HAS_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -88,6 +67,4 @@
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef BOOST_SP_HAS_CLANG_C11_ATOMICS
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -104,7 +104,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,143 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_aix.hpp
 | 
			
		||||
//   based on: detail/sp_counted_base_w32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//  Copyright 2006 Michael van der Westhuizen
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <builtins.h>
 | 
			
		||||
#include <sys/atomic_op.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int32_t* pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    fetch_and_add( pw, 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_decrement( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int32_t originalValue;
 | 
			
		||||
 | 
			
		||||
    __lwsync();
 | 
			
		||||
    originalValue = fetch_and_add( pw, -1 );
 | 
			
		||||
    __isync();
 | 
			
		||||
 | 
			
		||||
    return (originalValue - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_conditional_increment( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int32_t tmp = fetch_and_add( pw, 0 );
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        if( tmp == 0 ) return 0;
 | 
			
		||||
        if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    int32_t use_count_;        // #shared
 | 
			
		||||
    int32_t weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), 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_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
@@ -1,140 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -124,7 +124,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -112,7 +112,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -111,7 +111,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -37,12 +37,9 @@ inline void atomic_increment( int * pw )
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
        "ll %0, %1\n\t"
 | 
			
		||||
        "addiu %0, 1\n\t"
 | 
			
		||||
        "sc %0, %1\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %0, 0b":
 | 
			
		||||
        "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
        "m"( *pw )
 | 
			
		||||
@@ -58,12 +55,9 @@ inline int atomic_decrement( int * pw )
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
        "ll %1, %2\n\t"
 | 
			
		||||
        "addiu %0, %1, -1\n\t"
 | 
			
		||||
        "sc %0, %2\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %0, 0b\n\t"
 | 
			
		||||
        "addiu %0, %1, -1":
 | 
			
		||||
        "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
@@ -84,13 +78,10 @@ inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
        "ll %0, %2\n\t"
 | 
			
		||||
        "beqz %0, 1f\n\t"
 | 
			
		||||
        "addiu %1, %0, 1\n\t"
 | 
			
		||||
        "sc %1, %2\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %1, 0b\n\t"
 | 
			
		||||
        "addiu %0, %0, 1\n\t"
 | 
			
		||||
        "1:":
 | 
			
		||||
@@ -135,7 +126,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -135,7 +135,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
@@ -47,15 +46,15 @@ public:
 | 
			
		||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
 | 
			
		||||
 | 
			
		||||
#if defined(__hpux) && defined(_DECTHREADS_)
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
 | 
			
		||||
        pthread_mutex_init( &m_, pthread_mutexattr_default );
 | 
			
		||||
#else
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
 | 
			
		||||
        pthread_mutex_init( &m_, 0 );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_destroy( &m_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dispose() is called when use_count_ drops to zero, to release
 | 
			
		||||
@@ -71,28 +70,27 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        bool r = use_count_ == 0? false: ( ++use_count_, true );
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        long new_use_count = --use_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
 | 
			
		||||
        if( new_use_count == 0 )
 | 
			
		||||
        {
 | 
			
		||||
@@ -103,16 +101,16 @@ public:
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        ++weak_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        long new_weak_count = --weak_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
 | 
			
		||||
        if( new_weak_count == 0 )
 | 
			
		||||
        {
 | 
			
		||||
@@ -122,9 +120,9 @@ public:
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        long r = use_count_;
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,162 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2006 Piotr Wyderski
 | 
			
		||||
//  Copyright (c) 2006 Tomas Puverle
 | 
			
		||||
//  Copyright (c) 2006 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2011 Emil Dotchevski
 | 
			
		||||
//
 | 
			
		||||
//  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
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Michael van der Westhuizen
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <inttypes.h> // uint32_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // *pw += dv;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t r = *pw;
 | 
			
		||||
 | 
			
		||||
        if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( uint32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    (void) __builtin_cellAtomicIncr32( pw );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t atomic_decrement( uint32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_cellAtomicDecr32( pw );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t atomic_conditional_increment( uint32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // if( r != 0 ) ++*pw;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t r = *pw;
 | 
			
		||||
 | 
			
		||||
        if( r == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    uint32_t use_count_;        // #shared
 | 
			
		||||
    uint32_t weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), 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 const_cast< uint32_t const volatile & >( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
 | 
			
		||||
@@ -62,7 +62,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -84,7 +84,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,137 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_counted_base_std_atomic.hpp - C++11 std::atomic
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007, 2013 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 <atomic>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( std::atomic_int_least32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    pw->fetch_add( 1, std::memory_order_relaxed );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    return pw->fetch_sub( 1, std::memory_order_acq_rel );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // long r = *pw;
 | 
			
		||||
    // if( r != 0 ) ++*pw;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    std::int_least32_t r = pw->load( std::memory_order_relaxed );
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        if( r == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
 | 
			
		||||
        {
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    std::atomic_int_least32_t use_count_;	// #shared
 | 
			
		||||
    std::atomic_int_least32_t weak_count_;	// #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), 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 use_count_.load( std::memory_order_acquire );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
@@ -109,7 +109,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,151 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
 | 
			
		||||
//   based on: detail/sp_counted_base_w32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//  Copyright 2006 Michael van der Westhuizen
 | 
			
		||||
//  Copyright 2012 IBM Corp.
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
extern "builtin" void __lwsync(void);
 | 
			
		||||
extern "builtin" void __isync(void);
 | 
			
		||||
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
 | 
			
		||||
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int *pw )
 | 
			
		||||
{
 | 
			
		||||
   // ++*pw;
 | 
			
		||||
   __lwsync();
 | 
			
		||||
   __fetch_and_add(pw, 1);
 | 
			
		||||
   __isync();
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int *pw )
 | 
			
		||||
{
 | 
			
		||||
   // return --*pw;
 | 
			
		||||
   __lwsync();
 | 
			
		||||
   int originalValue = __fetch_and_add(pw, -1);
 | 
			
		||||
   __isync();
 | 
			
		||||
 | 
			
		||||
   return (originalValue - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int *pw )
 | 
			
		||||
{
 | 
			
		||||
   // if( *pw != 0 ) ++*pw;
 | 
			
		||||
   // return *pw;
 | 
			
		||||
 | 
			
		||||
   __lwsync();
 | 
			
		||||
   int v = *const_cast<volatile int*>(pw);
 | 
			
		||||
   for (;;)
 | 
			
		||||
   // loop until state is known
 | 
			
		||||
   {
 | 
			
		||||
      if (v == 0) return 0;
 | 
			
		||||
      if (__compare_and_swap(pw, &v, v + 1))
 | 
			
		||||
      {
 | 
			
		||||
         __isync(); return (v + 1);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    int use_count_;        // #shared
 | 
			
		||||
    int weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
    char pad[64] __attribute__((__aligned__(64)));
 | 
			
		||||
            // pad to prevent false sharing
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), 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_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_decrement( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return *const_cast<volatile int*>(&use_count_); 
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
 | 
			
		||||
#include <boost/detail/interlocked.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -67,11 +67,10 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
    virtual void * get_untyped_deleter() = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ );
 | 
			
		||||
        BOOST_INTERLOCKED_INCREMENT( &use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
@@ -86,11 +85,11 @@ public:
 | 
			
		||||
            // work around a code generation bug
 | 
			
		||||
 | 
			
		||||
            long tmp2 = tmp + 1;
 | 
			
		||||
            if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
 | 
			
		||||
            if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
 | 
			
		||||
            if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
@@ -98,7 +97,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
 | 
			
		||||
        if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
@@ -107,12 +106,12 @@ public:
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ );
 | 
			
		||||
        BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
 | 
			
		||||
        if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -78,12 +78,7 @@ public:
 | 
			
		||||
        boost::checked_delete( px_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & )
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_untyped_deleter()
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & )
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -153,16 +148,11 @@ public:
 | 
			
		||||
        del( ptr );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti )
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & ti )
 | 
			
		||||
    {
 | 
			
		||||
        return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_untyped_deleter()
 | 
			
		||||
    {
 | 
			
		||||
        return &reinterpret_cast<char&>( del );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t )
 | 
			
		||||
@@ -213,7 +203,7 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
 | 
			
		||||
    sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -224,40 +214,18 @@ public:
 | 
			
		||||
 | 
			
		||||
    virtual void destroy() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        typedef typename A::template rebind< this_type >::other A2;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        A2 a2( a_ );
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
        std::allocator_traits<A2>::destroy( a2, this );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        this->~this_type();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        a2.deallocate( this, 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti )
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & ti )
 | 
			
		||||
    {
 | 
			
		||||
        return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_untyped_deleter()
 | 
			
		||||
    {
 | 
			
		||||
        return &reinterpret_cast<char&>( d_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __CODEGUARD__
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_forward.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2008,2012 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>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
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 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
 | 
			
		||||
@@ -20,17 +20,7 @@
 | 
			
		||||
//  are available.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_SP_NO_SYNC
 | 
			
		||||
 | 
			
		||||
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_HAS_SYNC
 | 
			
		||||
 | 
			
		||||
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_HAS_SYNC
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
 | 
			
		||||
#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( BOOST_SP_NO_SYNC )
 | 
			
		||||
 | 
			
		||||
#define BOOST_SP_HAS_SYNC
 | 
			
		||||
 | 
			
		||||
@@ -46,24 +36,14 @@
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __sh__ )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __sparc__ )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
 | 
			
		||||
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1100 )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9)) 
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SP_NO_SYNC
 | 
			
		||||
#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    namespace detail {
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct sp_if_array;
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct sp_if_array<T[]> {
 | 
			
		||||
            typedef boost::shared_ptr<T[]> type;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct sp_if_size_array;
 | 
			
		||||
 | 
			
		||||
        template<class T, std::size_t N>
 | 
			
		||||
        struct sp_if_size_array<T[N]> {
 | 
			
		||||
            typedef boost::shared_ptr<T[N]> type;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,152 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/sp_interlocked.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2005, 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/config.hpp>
 | 
			
		||||
 | 
			
		||||
// BOOST_SP_HAS_INTRIN_H
 | 
			
		||||
 | 
			
		||||
// VC9 has intrin.h, but it collides with <utility>
 | 
			
		||||
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_HAS_INTRIN_H
 | 
			
		||||
 | 
			
		||||
// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets.
 | 
			
		||||
#elif defined( __MINGW64_VERSION_MAJOR )
 | 
			
		||||
 | 
			
		||||
// MinGW-w64 provides intrin.h for both 32 and 64-bit targets.
 | 
			
		||||
# define BOOST_SP_HAS_INTRIN_H
 | 
			
		||||
 | 
			
		||||
// Intel C++ on Windows on VC10+ stdlib
 | 
			
		||||
#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_HAS_INTRIN_H
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_USE_WINDOWS_H )
 | 
			
		||||
 | 
			
		||||
# include <windows.h>
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H )
 | 
			
		||||
 | 
			
		||||
#include <intrin.h>
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
 | 
			
		||||
 | 
			
		||||
#elif defined( _WIN32_WCE )
 | 
			
		||||
 | 
			
		||||
#if _WIN32_WCE >= 0x600
 | 
			
		||||
 | 
			
		||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
 | 
			
		||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
 | 
			
		||||
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 );
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// under Windows CE we still have old-style Interlocked* functions
 | 
			
		||||
 | 
			
		||||
extern "C" long __cdecl InterlockedIncrement( long* );
 | 
			
		||||
extern "C" long __cdecl InterlockedDecrement( long* );
 | 
			
		||||
extern "C" long __cdecl InterlockedCompareExchange( long*, long, long );
 | 
			
		||||
extern "C" long __cdecl InterlockedExchange( long*, long );
 | 
			
		||||
extern "C" long __cdecl InterlockedExchangeAdd( long*, long );
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN )
 | 
			
		||||
 | 
			
		||||
#if defined( __CLRCALL_PURE_OR_CDECL )
 | 
			
		||||
 | 
			
		||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * );
 | 
			
		||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * );
 | 
			
		||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long );
 | 
			
		||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long );
 | 
			
		||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
 | 
			
		||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
 | 
			
		||||
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 );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
 | 
			
		||||
 | 
			
		||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * );
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * );
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long );
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long );
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long );
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange
 | 
			
		||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
# error "Interlocked intrinsics not available"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_nullptr_t.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2013 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>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
 | 
			
		||||
 | 
			
		||||
    typedef decltype(nullptr) sp_nullptr_t;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    typedef std::nullptr_t sp_nullptr_t;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
 | 
			
		||||
@@ -31,16 +31,7 @@
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_SP_USE_STD_ATOMIC )
 | 
			
		||||
# if !defined( __clang__ )
 | 
			
		||||
#   include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
 | 
			
		||||
# else
 | 
			
		||||
//  Clang (at least up to 3.4) can't compile spinlock_pool when
 | 
			
		||||
//  using std::atomic, so substitute the __sync implementation instead.
 | 
			
		||||
#   include <boost/smart_ptr/detail/spinlock_sync.hpp>
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
#if defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
#  include <boost/smart_ptr/detail/spinlock_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008, 2011 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@@ -11,22 +11,6 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/yield_k.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_ARM_BARRIER "dmb"
 | 
			
		||||
# define BOOST_SP_ARM_HAS_LDREX
 | 
			
		||||
 | 
			
		||||
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
 | 
			
		||||
# define BOOST_SP_ARM_HAS_LDREX
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_ARM_BARRIER ""
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@@ -45,28 +29,12 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        int r;
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_SP_ARM_HAS_LDREX
 | 
			
		||||
 | 
			
		||||
        __asm__ __volatile__(
 | 
			
		||||
            "ldrex %0, [%2]; \n"
 | 
			
		||||
            "cmp %0, %1; \n"
 | 
			
		||||
            "strexne %0, %1, [%2]; \n"
 | 
			
		||||
            BOOST_SP_ARM_BARRIER :
 | 
			
		||||
            "swp %0, %1, [%2]":
 | 
			
		||||
            "=&r"( r ): // outputs
 | 
			
		||||
            "r"( 1 ), "r"( &v_ ): // inputs
 | 
			
		||||
            "memory", "cc" );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        __asm__ __volatile__(
 | 
			
		||||
            "swp %0, %1, [%2];\n"
 | 
			
		||||
            BOOST_SP_ARM_BARRIER :
 | 
			
		||||
            "=&r"( r ): // outputs
 | 
			
		||||
            "r"( 1 ), "r"( &v_ ): // inputs
 | 
			
		||||
            "memory", "cc" );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return r == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -80,7 +48,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
 | 
			
		||||
        __asm__ __volatile__( "" ::: "memory" );
 | 
			
		||||
        *const_cast< int volatile* >( &v_ ) = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -114,7 +82,4 @@ public:
 | 
			
		||||
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
 | 
			
		||||
 | 
			
		||||
#undef BOOST_SP_ARM_BARRIER
 | 
			
		||||
#undef BOOST_SP_ARM_HAS_LDREX
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ namespace boost
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template< int M > class spinlock_pool
 | 
			
		||||
template< int I > class spinlock_pool
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +72,7 @@ public:
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< int M > spinlock spinlock_pool< M >::pool_[ 41 ] =
 | 
			
		||||
template< int I > spinlock spinlock_pool< I >::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, 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,83 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  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/detail/yield_k.hpp>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class spinlock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    std::atomic_flag v_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        return !v_.test_and_set( std::memory_order_acquire );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
        for( unsigned k = 0; !try_lock(); ++k )
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::yield( k );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        v_ .clear( std::memory_order_release );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        spinlock & sp_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock( scoped_lock const & );
 | 
			
		||||
        scoped_lock & operator=( scoped_lock const & );
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock( spinlock & sp ): sp_( sp )
 | 
			
		||||
        {
 | 
			
		||||
            sp.lock();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            sp_.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT }
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
 | 
			
		||||
#include <boost/detail/interlocked.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/yield_k.hpp>
 | 
			
		||||
 | 
			
		||||
// BOOST_COMPILER_FENCE
 | 
			
		||||
@@ -59,7 +59,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
 | 
			
		||||
        long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
 | 
			
		||||
 | 
			
		||||
        BOOST_COMPILER_FENCE
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    namespace detail {
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct up_if_array;
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct up_if_array<T[]> {
 | 
			
		||||
            typedef std::unique_ptr<T[]> type;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    namespace detail {
 | 
			
		||||
        template<class T> 
 | 
			
		||||
        struct up_if_not_array {
 | 
			
		||||
            typedef std::unique_ptr<T> type;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T>
 | 
			
		||||
        struct up_if_not_array<T[]> {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        template<class T, std::size_t N>
 | 
			
		||||
        struct up_if_not_array<T[N]> {
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -11,7 +11,6 @@
 | 
			
		||||
//  yield_k.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 Peter Dimov
 | 
			
		||||
//  Copyright (c) Microsoft Corporation 2014
 | 
			
		||||
//
 | 
			
		||||
//  void yield( unsigned k );
 | 
			
		||||
//
 | 
			
		||||
@@ -25,17 +24,13 @@
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/predef.h>
 | 
			
		||||
 | 
			
		||||
#if BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
#include <thread>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// BOOST_SMT_PAUSE
 | 
			
		||||
 | 
			
		||||
#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();
 | 
			
		||||
 | 
			
		||||
@@ -59,7 +54,7 @@ namespace boost
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
#if !defined( BOOST_USE_WINDOWS_H )
 | 
			
		||||
  extern "C" void __stdcall Sleep( unsigned long ms );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -74,7 +69,6 @@ inline void yield( unsigned k )
 | 
			
		||||
        BOOST_SMT_PAUSE
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#if !BOOST_PLAT_WINDOWS_RUNTIME
 | 
			
		||||
    else if( k < 32 )
 | 
			
		||||
    {
 | 
			
		||||
        Sleep( 0 );
 | 
			
		||||
@@ -83,13 +77,6 @@ inline void yield( unsigned k )
 | 
			
		||||
    {
 | 
			
		||||
        Sleep( 1 );
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Sleep isn't supported on the Windows Runtime.
 | 
			
		||||
        std::this_thread::yield();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
@@ -98,13 +85,7 @@ 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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,165 +0,0 @@
 | 
			
		||||
#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
 | 
			
		||||
#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  enable_shared_from_raw.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2002, 2009, 2014 Peter Dimov
 | 
			
		||||
//  Copyright 2008-2009 Frank Mori Hess
 | 
			
		||||
//
 | 
			
		||||
//  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>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
 | 
			
		||||
template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
class enable_shared_from_raw
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_raw()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_raw( enable_shared_from_raw const & )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_raw & operator=( enable_shared_from_raw const & )
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~enable_shared_from_raw()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void init_if_expired() const
 | 
			
		||||
    {
 | 
			
		||||
        if( weak_this_.expired() )
 | 
			
		||||
        {
 | 
			
		||||
            shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
 | 
			
		||||
            weak_this_ = shared_this_;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
private:
 | 
			
		||||
    template<class Y> friend class shared_ptr;
 | 
			
		||||
    template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
 | 
			
		||||
    template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
 | 
			
		||||
    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 const volatile> shared_from_this() const
 | 
			
		||||
    {
 | 
			
		||||
        init_if_expired();
 | 
			
		||||
        return shared_ptr<void const volatile>( weak_this_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<void const volatile> shared_from_this() const volatile
 | 
			
		||||
    {
 | 
			
		||||
        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
 | 
			
		||||
    template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( ppx != 0 );
 | 
			
		||||
 | 
			
		||||
        if( weak_this_.expired() )
 | 
			
		||||
        {
 | 
			
		||||
            weak_this_ = *ppx;
 | 
			
		||||
        }
 | 
			
		||||
        else if( shared_this_.use_count() != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
 | 
			
		||||
 | 
			
		||||
            detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
 | 
			
		||||
            BOOST_ASSERT( pd != 0 );
 | 
			
		||||
 | 
			
		||||
            pd->set_deleter( *ppx );
 | 
			
		||||
 | 
			
		||||
            ppx->reset( shared_this_, ppx->get() );
 | 
			
		||||
            shared_this_.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mutable weak_ptr<void const volatile> weak_this_;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    mutable shared_ptr<void const volatile> shared_this_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
boost::shared_ptr<T> shared_from_raw(T *p)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_ASSERT(p != 0);
 | 
			
		||||
    return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
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_from_this(), p);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
    template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
 | 
			
		||||
    {
 | 
			
		||||
        if( pe != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
} // namepsace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
 | 
			
		||||
@@ -25,20 +25,20 @@ template<class T> class enable_shared_from_this
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this() BOOST_NOEXCEPT
 | 
			
		||||
    enable_shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT
 | 
			
		||||
    enable_shared_from_this(enable_shared_from_this const &)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT
 | 
			
		||||
    enable_shared_from_this & operator=(enable_shared_from_this const &)
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
 | 
			
		||||
    ~enable_shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -58,16 +58,6 @@ 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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										132
									
								
								include/boost/smart_ptr/enable_shared_from_this2.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								include/boost/smart_ptr/enable_shared_from_this2.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
 | 
			
		||||
#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  enable_shared_from_this2.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2002, 2009 Peter Dimov
 | 
			
		||||
//  Copyright 2008 Frank Mori Hess
 | 
			
		||||
//
 | 
			
		||||
//  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>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class esft2_deleter_wrapper
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<void> deleter_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    esft2_deleter_wrapper()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class T > void set_deleter( shared_ptr<T> const & deleter )
 | 
			
		||||
    {
 | 
			
		||||
        deleter_ = deleter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class T> void operator()( T* )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( deleter_.use_count() <= 1 );
 | 
			
		||||
        deleter_.reset();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
template< class T > class enable_shared_from_this2
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this2()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this2( enable_shared_from_this2 const & )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this2 & operator=( enable_shared_from_this2 const & )
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~enable_shared_from_this2()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    mutable weak_ptr<T> weak_this_;
 | 
			
		||||
    mutable shared_ptr<T> shared_this_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
        init_weak_once();
 | 
			
		||||
        return shared_ptr<T>( weak_this_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T const> shared_from_this() const
 | 
			
		||||
    {
 | 
			
		||||
        init_weak_once();
 | 
			
		||||
        return shared_ptr<T>( weak_this_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void init_weak_once() const
 | 
			
		||||
    {
 | 
			
		||||
        if( weak_this_._empty() )
 | 
			
		||||
        {
 | 
			
		||||
            shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() );
 | 
			
		||||
            weak_this_ = shared_this_;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public: // actually private, but avoids compiler template friendship issues
 | 
			
		||||
 | 
			
		||||
    // Note: invoked automatically by shared_ptr; do not call
 | 
			
		||||
    template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( ppx != 0 );
 | 
			
		||||
 | 
			
		||||
        if( weak_this_.use_count() == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            weak_this_ = shared_ptr<T>( *ppx, py );
 | 
			
		||||
        }
 | 
			
		||||
        else if( shared_this_.use_count() != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
 | 
			
		||||
 | 
			
		||||
            detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
 | 
			
		||||
            BOOST_ASSERT( pd != 0 );
 | 
			
		||||
 | 
			
		||||
            pd->set_deleter( *ppx );
 | 
			
		||||
 | 
			
		||||
            ppx->reset( shared_this_, ppx->get() );
 | 
			
		||||
            shared_this_.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
 | 
			
		||||
@@ -18,7 +18,6 @@
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/config/no_tr1/functional.hpp>           // for std::less
 | 
			
		||||
 | 
			
		||||
@@ -59,7 +58,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
 | 
			
		||||
    intrusive_ptr(): px( 0 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -109,14 +108,14 @@ public:
 | 
			
		||||
 | 
			
		||||
// Move support
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px )
 | 
			
		||||
    intrusive_ptr(intrusive_ptr && rhs): px( rhs.px )
 | 
			
		||||
    {
 | 
			
		||||
        rhs.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT
 | 
			
		||||
    intrusive_ptr & operator=(intrusive_ptr && rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
@@ -136,7 +135,7 @@ public:
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() BOOST_NOEXCEPT
 | 
			
		||||
    void reset()
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
@@ -146,23 +145,11 @@ public:
 | 
			
		||||
        this_type( rhs ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset( T * rhs, bool add_ref )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( rhs, add_ref ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const BOOST_NOEXCEPT
 | 
			
		||||
    T * get() const
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * detach() BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        T * ret = px;
 | 
			
		||||
        px = 0;
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator*() const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
@@ -178,7 +165,7 @@ public:
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
 | 
			
		||||
    void swap(intrusive_ptr & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = px;
 | 
			
		||||
        px = rhs.px;
 | 
			
		||||
@@ -231,30 +218,6 @@ template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_p
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T *>()(a.get(), b.get());
 | 
			
		||||
@@ -322,15 +285,6 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
 | 
			
		||||
 | 
			
		||||
#endif // !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
 | 
			
		||||
// hash_value
 | 
			
		||||
 | 
			
		||||
template< class T > struct hash;
 | 
			
		||||
 | 
			
		||||
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
 | 
			
		||||
{
 | 
			
		||||
    return boost::hash< T* >()( p.get() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -1,187 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *          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_
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
//  make_shared.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007, 2008, 2012 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2007, 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
//  See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@@ -12,11 +12,970 @@
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/make_shared.html
 | 
			
		||||
//  for documentation.
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/make_shared_object.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
#include <boost/type_traits/type_with_alignment.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <new>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template< std::size_t N, std::size_t A > struct sp_aligned_storage
 | 
			
		||||
{
 | 
			
		||||
    union type
 | 
			
		||||
    {
 | 
			
		||||
        char data_[ N ];
 | 
			
		||||
        typename boost::type_with_alignment< A >::type align_;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class T > class sp_ms_deleter
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
 | 
			
		||||
 | 
			
		||||
    bool initialized_;
 | 
			
		||||
    storage_type storage_;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void destroy()
 | 
			
		||||
    {
 | 
			
		||||
        if( initialized_ )
 | 
			
		||||
        {
 | 
			
		||||
#if defined( __GNUC__ )
 | 
			
		||||
 | 
			
		||||
            // fixes incorrect aliasing warning
 | 
			
		||||
            T * p = reinterpret_cast< T* >( storage_.data_ );
 | 
			
		||||
            p->~T();
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            reinterpret_cast< T* >( storage_.data_ )->~T();
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE )
 | 
			
		||||
# include <boost/smart_ptr/make_shared_array.hpp>
 | 
			
		||||
# include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            initialized_ = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_ms_deleter(): initialized_( false )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // optimization: do not copy storage_
 | 
			
		||||
    sp_ms_deleter( sp_ms_deleter const & ): initialized_( false )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~sp_ms_deleter()
 | 
			
		||||
    {
 | 
			
		||||
        destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator()( T * )
 | 
			
		||||
    {
 | 
			
		||||
        destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * address()
 | 
			
		||||
    {
 | 
			
		||||
        return storage_.data_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_initialized()
 | 
			
		||||
    {
 | 
			
		||||
        initialized_ = true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
template< class T > T&& sp_forward( T & t )
 | 
			
		||||
{
 | 
			
		||||
    return static_cast< T&& >( t );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
# define BOOST_SP_MSD( T ) boost::detail::sp_inplace_tag< boost::detail::sp_ms_deleter< T > >()
 | 
			
		||||
#else
 | 
			
		||||
# define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Zero-argument versions
 | 
			
		||||
//
 | 
			
		||||
// Used even when variadic templates are available because of the new T() vs new T issue
 | 
			
		||||
 | 
			
		||||
template< class T > boost::shared_ptr< T > make_shared()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T();
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T();
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// Variadic templates, rvalue reference
 | 
			
		||||
 | 
			
		||||
template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_shared( Arg1 && arg1, Args && ... args )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Arg1 && arg1, Args && ... args )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// For example MSVC 10.0
 | 
			
		||||
 | 
			
		||||
template< class T, class A1 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 ), 
 | 
			
		||||
        boost::detail::sp_forward<A9>( a9 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 ), 
 | 
			
		||||
        boost::detail::sp_forward<A9>( a9 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// C++03 version
 | 
			
		||||
 | 
			
		||||
template< class T, class A1 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef BOOST_SP_MSD
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -1,158 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/array_count_impl.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::sp_if_array<T>::type
 | 
			
		||||
    make_shared(std::size_t size) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_allocator<T> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        std::size_t n1 = size * boost::detail::array_total<T1>::size;
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(size, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_init(p2, n1);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::sp_if_size_array<T>::type
 | 
			
		||||
    make_shared() {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_allocator<T> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            N = boost::detail::array_total<T>::size
 | 
			
		||||
        };
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(&p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_init(p2, N);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::sp_if_array<T>::type
 | 
			
		||||
    make_shared(std::size_t size,
 | 
			
		||||
        const typename boost::detail::array_inner<T>::type& value) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef const T2 T3;
 | 
			
		||||
        typedef boost::detail::ms_allocator<T> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            M = boost::detail::array_total<T1>::size
 | 
			
		||||
        };
 | 
			
		||||
        std::size_t n1 = M * size;
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        T3* p3 = reinterpret_cast<T3*>(&value);
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(size, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_init<T2, M>(p2, n1, p3);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::sp_if_size_array<T>::type
 | 
			
		||||
    make_shared(const typename boost::detail::array_inner<T>::type& value) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef const T2 T3;
 | 
			
		||||
        typedef boost::detail::ms_allocator<T> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            M = boost::detail::array_total<T1>::size,
 | 
			
		||||
            N = boost::detail::array_total<T>::size
 | 
			
		||||
        };
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        T3* p3 = reinterpret_cast<T3*>(&value);
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(&p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_init<T2, M>(p2, N, p3);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::sp_if_array<T>::type
 | 
			
		||||
    make_shared_noinit(std::size_t size) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_allocator<T> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        std::size_t n1 = size * boost::detail::array_total<T1>::size;
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(size, &p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_noinit(p2, n1);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::sp_if_size_array<T>::type
 | 
			
		||||
    make_shared_noinit() {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type T1;
 | 
			
		||||
        typedef typename boost::detail::array_base<T1>::type T2;
 | 
			
		||||
        typedef boost::detail::ms_allocator<T> A1;
 | 
			
		||||
        typedef boost::detail::ms_in_allocator_tag D1;
 | 
			
		||||
        enum {
 | 
			
		||||
            N = boost::detail::array_total<T>::size
 | 
			
		||||
        };
 | 
			
		||||
        T1* p1 = 0;
 | 
			
		||||
        T2* p2 = 0;
 | 
			
		||||
        D1 d1;
 | 
			
		||||
        A1 a1(&p2);
 | 
			
		||||
        shared_ptr<T> s1(p1, d1, a1);
 | 
			
		||||
        A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
 | 
			
		||||
        a2->set(0);
 | 
			
		||||
        boost::detail::ms_noinit(p2, N);
 | 
			
		||||
        a2->set(p2);
 | 
			
		||||
        p1 = reinterpret_cast<T1*>(p2);
 | 
			
		||||
        return shared_ptr<T>(s1, p1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,15 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/make_unique_array.hpp>
 | 
			
		||||
#include <boost/smart_ptr/make_unique_object.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/up_if_array.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/array_traits.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::up_if_array<T>::type
 | 
			
		||||
    make_unique(std::size_t size) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type U;
 | 
			
		||||
        return std::unique_ptr<T>(new U[size]());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::up_if_array<T>::type
 | 
			
		||||
    make_unique_noinit(std::size_t size) {
 | 
			
		||||
        typedef typename boost::detail::array_inner<T>::type U;
 | 
			
		||||
        return std::unique_ptr<T>(new U[size]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_OBJECT_HPP
 | 
			
		||||
#define BOOST_SMART_PTR_MAKE_UNIQUE_OBJECT_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/up_if_not_array.hpp>
 | 
			
		||||
#include <boost/type_traits/add_rvalue_reference.hpp>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::up_if_not_array<T>::type
 | 
			
		||||
    make_unique() {
 | 
			
		||||
        return std::unique_ptr<T>(new T());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
 | 
			
		||||
    template<class T, class... Args>
 | 
			
		||||
    inline typename boost::detail::up_if_not_array<T>::type
 | 
			
		||||
    make_unique(Args&&... args) {
 | 
			
		||||
        return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::up_if_not_array<T>::type
 | 
			
		||||
    make_unique(typename add_rvalue_reference<T>::type value) {
 | 
			
		||||
        return std::unique_ptr<T>(new T(std::move(value)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T>
 | 
			
		||||
    inline typename boost::detail::up_if_not_array<T>::type
 | 
			
		||||
    make_unique_noinit() {
 | 
			
		||||
        return std::unique_ptr<T>(new T);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  owner_less.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 Frank Mori Hess
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/smart_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
  template<typename T> class shared_ptr;
 | 
			
		||||
  template<typename T> class weak_ptr;
 | 
			
		||||
 | 
			
		||||
  namespace detail
 | 
			
		||||
  {
 | 
			
		||||
    template<typename T, typename U>
 | 
			
		||||
      struct generic_owner_less : public std::binary_function<T, T, bool>
 | 
			
		||||
    {
 | 
			
		||||
      bool operator()(const T &lhs, const T &rhs) const
 | 
			
		||||
      {
 | 
			
		||||
        return lhs.owner_before(rhs);
 | 
			
		||||
      }
 | 
			
		||||
      bool operator()(const T &lhs, const U &rhs) const
 | 
			
		||||
      {
 | 
			
		||||
        return lhs.owner_before(rhs);
 | 
			
		||||
      }
 | 
			
		||||
      bool operator()(const U &lhs, const T &rhs) const
 | 
			
		||||
      {
 | 
			
		||||
        return lhs.owner_before(rhs);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  } // namespace detail
 | 
			
		||||
 | 
			
		||||
  template<typename T> struct owner_less;
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
    struct owner_less<shared_ptr<T> >:
 | 
			
		||||
    public detail::generic_owner_less<shared_ptr<T>, weak_ptr<T> >
 | 
			
		||||
  {};
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
    struct owner_less<weak_ptr<T> >:
 | 
			
		||||
    public detail::generic_owner_less<weak_ptr<T>, shared_ptr<T> >
 | 
			
		||||
  {};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
 | 
			
		||||
@@ -11,10 +11,9 @@
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_array.htm
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
 | 
			
		||||
#include <boost/config.hpp>   // in case ptrdiff_t not in std
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -54,7 +53,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p )
 | 
			
		||||
    explicit scoped_array( T * p = 0 ) : px( p ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_array_constructor_hook( px );
 | 
			
		||||
@@ -69,20 +68,20 @@ public:
 | 
			
		||||
        boost::checked_array_delete( px );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
 | 
			
		||||
    void reset(T * p = 0) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
 | 
			
		||||
    T & operator[](std::ptrdiff_t i) const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        BOOST_ASSERT( i >= 0 );
 | 
			
		||||
        return px[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const BOOST_NOEXCEPT
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
@@ -90,7 +89,7 @@ public:
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_array & b) BOOST_NOEXCEPT
 | 
			
		||||
    void swap(scoped_array & b) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = b.px;
 | 
			
		||||
        b.px = px;
 | 
			
		||||
@@ -98,31 +97,7 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,10 +11,8 @@
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
@@ -65,7 +63,7 @@ public:
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
 | 
			
		||||
    explicit scoped_ptr( std::auto_ptr<T> p ): px( p.release() ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_constructor_hook( px );
 | 
			
		||||
@@ -100,7 +98,7 @@ public:
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const BOOST_NOEXCEPT
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
@@ -108,7 +106,7 @@ public:
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_ptr & b) BOOST_NOEXCEPT
 | 
			
		||||
    void swap(scoped_ptr & b) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = b.px;
 | 
			
		||||
        b.px = px;
 | 
			
		||||
@@ -116,38 +114,14 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer(p) is a generic way to say p.get()
 | 
			
		||||
 | 
			
		||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
//  shared_array.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2012 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@@ -16,14 +16,16 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>   // for broken compiler workarounds
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_array_nmt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <memory>             // TR1 cyclic inclusion fix
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstddef>            // for std::ptrdiff_t
 | 
			
		||||
@@ -53,154 +55,41 @@ public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    shared_array() BOOST_NOEXCEPT : px( 0 ), pn()
 | 
			
		||||
    explicit shared_array(T * p = 0): px(p), pn(p, deleter())
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
    shared_array( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y[], T[] >();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Requirements: D's copy constructor must not throw
 | 
			
		||||
    //
 | 
			
		||||
    // shared_array will release p by calling d(p)
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y[], T[] >();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // As above, but with allocator. A's copy constructor shall not throw.
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y[], T[] >();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, destructor are fine...
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
// ... except in C++0x, move disables the implicit copy
 | 
			
		||||
 | 
			
		||||
    shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
 | 
			
		||||
    template<class D> shared_array(T * p, D d): px(p), pn(p, d)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn()
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0)
 | 
			
		||||
    {
 | 
			
		||||
        pn.swap( r.pn );
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px);
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // conversion
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    shared_array( shared_array<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    template <class D> void reset(T * p, D d)
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y[], T[] >();
 | 
			
		||||
        this_type(p, d).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // aliasing
 | 
			
		||||
 | 
			
		||||
    template< class Y >
 | 
			
		||||
    shared_array( shared_array<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // assignment
 | 
			
		||||
 | 
			
		||||
    shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        this_type( r ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        this_type( r ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
    shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< shared_array && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_array & operator=( shared_array<Y> && r ) BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    void reset() BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset( Y * p ) // Y must be complete
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
 | 
			
		||||
        this_type( p ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> void reset( Y * p, D d )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( p, d ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D, class A> void reset( Y * p, D d, A a )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( p, d, a ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset( shared_array<Y> const & r, element_type * p )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( r, p ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
 | 
			
		||||
    T & operator[] (std::ptrdiff_t i) const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        BOOST_ASSERT(i >= 0);
 | 
			
		||||
        return px[i];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    T * get() const BOOST_NOEXCEPT
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
@@ -208,85 +97,51 @@ public:
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    bool unique() const BOOST_NOEXCEPT
 | 
			
		||||
    bool unique() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.unique();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const BOOST_NOEXCEPT
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(shared_array<T> & other) BOOST_NOEXCEPT
 | 
			
		||||
    void swap(shared_array<T> & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn.get_deleter( ti );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    template<class Y> friend class shared_array;
 | 
			
		||||
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    detail::shared_count pn;    // reference counter
 | 
			
		||||
 | 
			
		||||
};  // shared_array
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T*>()(a.get(), b.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class D, class T > D * get_deleter( shared_array<T> const & p )
 | 
			
		||||
{
 | 
			
		||||
    return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,10 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>   // for broken compiler workarounds
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_ptr_nmt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// In order to avoid circular dependencies with Boost.TR1
 | 
			
		||||
// we make sure that our include of <memory> doesn't try to
 | 
			
		||||
// pull in the TR1 headers: that's why we use this header 
 | 
			
		||||
@@ -28,10 +32,10 @@
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
 | 
			
		||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
 | 
			
		||||
#include <boost/memory_order.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <algorithm>            // for std::swap
 | 
			
		||||
@@ -53,151 +57,45 @@ namespace boost
 | 
			
		||||
template<class T> class shared_ptr;
 | 
			
		||||
template<class T> class weak_ptr;
 | 
			
		||||
template<class T> class enable_shared_from_this;
 | 
			
		||||
class enable_shared_from_raw;
 | 
			
		||||
template<class T> class enable_shared_from_this2;
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// sp_element, element_type
 | 
			
		||||
struct static_cast_tag {};
 | 
			
		||||
struct const_cast_tag {};
 | 
			
		||||
struct dynamic_cast_tag {};
 | 
			
		||||
struct polymorphic_cast_tag {};
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_element
 | 
			
		||||
template<class T> struct shared_ptr_traits
 | 
			
		||||
{
 | 
			
		||||
    typedef T type;
 | 
			
		||||
    typedef T & reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_element< T[] >
 | 
			
		||||
template<> struct shared_ptr_traits<void>
 | 
			
		||||
{
 | 
			
		||||
    typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
 | 
			
		||||
 | 
			
		||||
template< class T, std::size_t N > struct sp_element< T[N] >
 | 
			
		||||
{
 | 
			
		||||
    typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
// sp_dereference, return type of operator*
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_dereference
 | 
			
		||||
{
 | 
			
		||||
    typedef T & type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct sp_dereference< void >
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
 | 
			
		||||
 | 
			
		||||
template<> struct sp_dereference< void const >
 | 
			
		||||
template<> struct shared_ptr_traits<void const>
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct sp_dereference< void volatile >
 | 
			
		||||
template<> struct shared_ptr_traits<void volatile>
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct sp_dereference< void const volatile >
 | 
			
		||||
template<> struct shared_ptr_traits<void const volatile>
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_dereference< T[] >
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
 | 
			
		||||
 | 
			
		||||
template< class T, std::size_t N > struct sp_dereference< T[N] >
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
// sp_member_access, return type of operator->
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_member_access
 | 
			
		||||
{
 | 
			
		||||
    typedef T * type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_member_access< T[] >
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
 | 
			
		||||
 | 
			
		||||
template< class T, std::size_t N > struct sp_member_access< T[N] >
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
// sp_array_access, return type of operator[]
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_array_access
 | 
			
		||||
{
 | 
			
		||||
    typedef void type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_array_access< T[] >
 | 
			
		||||
{
 | 
			
		||||
    typedef T & type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
 | 
			
		||||
 | 
			
		||||
template< class T, std::size_t N > struct sp_array_access< T[N] >
 | 
			
		||||
{
 | 
			
		||||
    typedef T & type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
// sp_extent, for operator[] index check
 | 
			
		||||
 | 
			
		||||
template< class T > struct sp_extent
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = 0 };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
template< class T, std::size_t N > struct sp_extent< T[N] >
 | 
			
		||||
{
 | 
			
		||||
    enum _vt { value = N };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
// enable_shared_from_this support
 | 
			
		||||
 | 
			
		||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
 | 
			
		||||
@@ -208,7 +106,13 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( bo
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
 | 
			
		||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe )
 | 
			
		||||
{
 | 
			
		||||
    if( pe != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _MANAGED
 | 
			
		||||
 | 
			
		||||
@@ -246,69 +150,6 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// sp_assert_convertible
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > inline void sp_assert_convertible()
 | 
			
		||||
{
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    // static_assert( sp_convertible< Y, T >::value );
 | 
			
		||||
    typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ];
 | 
			
		||||
    (void)sizeof( tmp );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    T* p = static_cast< Y* >( 0 );
 | 
			
		||||
    (void)p;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// pointer constructor helper
 | 
			
		||||
 | 
			
		||||
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::shared_count( p ).swap( pn );
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( ppx, p, p );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
 | 
			
		||||
{
 | 
			
		||||
    sp_assert_convertible< Y[], T[] >();
 | 
			
		||||
    boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
 | 
			
		||||
{
 | 
			
		||||
    sp_assert_convertible< Y[N], T[N] >();
 | 
			
		||||
    boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
// deleter constructor helper
 | 
			
		||||
 | 
			
		||||
template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( ppx, p, p );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
 | 
			
		||||
{
 | 
			
		||||
    sp_assert_convertible< Y[], T[] >();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ )
 | 
			
		||||
{
 | 
			
		||||
    sp_assert_convertible< Y[N], T[N] >();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -329,24 +170,19 @@ private:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::detail::sp_element< T >::type element_type;
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
    typedef T value_type;
 | 
			
		||||
    typedef T * pointer;
 | 
			
		||||
    typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
 | 
			
		||||
 | 
			
		||||
    shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
 | 
			
		||||
    shared_ptr(): px(0), pn() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
    shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
 | 
			
		||||
    explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_pointer_construct( this, p, pn );
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( this, p, p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
@@ -355,58 +191,29 @@ public:
 | 
			
		||||
    // shared_ptr will release p by calling d(p)
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
 | 
			
		||||
    template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_deleter_construct( this, p );
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( this, p, p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
    template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // As above, but with allocator. A's copy constructor shall not throw.
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_deleter_construct( this, p );
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( this, p, p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
    template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, destructor are fine...
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
// ... except in C++0x, move disables the implicit copy
 | 
			
		||||
 | 
			
		||||
    shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
//  generated copy constructor, destructor are fine
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
 | 
			
		||||
    explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        // it is now safe to copy r.px, as pn(r.pn) did not throw
 | 
			
		||||
        px = r.px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
 | 
			
		||||
    BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
 | 
			
		||||
    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        if( !pn.empty() )
 | 
			
		||||
        {
 | 
			
		||||
@@ -424,80 +231,72 @@ public:
 | 
			
		||||
    shared_ptr( shared_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
 | 
			
		||||
    : px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // aliasing
 | 
			
		||||
    template< class Y >
 | 
			
		||||
    shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
 | 
			
		||||
    shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    {
 | 
			
		||||
        if(px == 0) // need to allocate new counter -- the cast failed
 | 
			
		||||
        {
 | 
			
		||||
            pn = boost::detail::shared_count();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    {
 | 
			
		||||
        if(px == 0)
 | 
			
		||||
        {
 | 
			
		||||
            boost::throw_exception(std::bad_cast());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
 | 
			
		||||
    explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        Y * tmp = r.get();
 | 
			
		||||
        pn = boost::detail::shared_count( r );
 | 
			
		||||
 | 
			
		||||
        boost::detail::sp_deleter_construct( this, tmp );
 | 
			
		||||
        pn = boost::detail::shared_count(r);
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn()
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        Y * tmp = r.get();
 | 
			
		||||
        pn = boost::detail::shared_count( r );
 | 
			
		||||
 | 
			
		||||
        boost::detail::sp_deleter_construct( this, tmp );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
    template<class Ap>
 | 
			
		||||
    explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
 | 
			
		||||
    {
 | 
			
		||||
        typedef typename Ap::element_type Y;
 | 
			
		||||
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        Y * tmp = r.get();
 | 
			
		||||
        typename Ap::element_type * tmp = r.get();
 | 
			
		||||
        pn = boost::detail::shared_count( r );
 | 
			
		||||
 | 
			
		||||
        boost::detail::sp_deleter_construct( this, tmp );
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_AUTO_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()
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        typename std::unique_ptr< Y, D >::pointer tmp = r.get();
 | 
			
		||||
        pn = boost::detail::shared_count( r );
 | 
			
		||||
 | 
			
		||||
        boost::detail::sp_deleter_construct( this, tmp );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // assignment
 | 
			
		||||
 | 
			
		||||
    shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
 | 
			
		||||
    shared_ptr & operator=( shared_ptr const & r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
@@ -506,7 +305,7 @@ public:
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_NOEXCEPT
 | 
			
		||||
    shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
@@ -519,20 +318,11 @@ public:
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=( std::auto_ptr<Y> & r )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( r ).swap( *this );
 | 
			
		||||
        this_type(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=( std::auto_ptr<Y> && r )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
    template<class Ap>
 | 
			
		||||
    typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
 | 
			
		||||
@@ -541,26 +331,16 @@ public:
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_AUTO_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 )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Move support
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn()
 | 
			
		||||
    shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
 | 
			
		||||
    {
 | 
			
		||||
        pn.swap( r.pn );
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
@@ -576,22 +356,20 @@ public:
 | 
			
		||||
    shared_ptr( shared_ptr<Y> && r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    BOOST_NOEXCEPT : px( r.px ), pn()
 | 
			
		||||
    : px( r.px ), pn() // never throws
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        pn.swap( r.pn );
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT
 | 
			
		||||
    shared_ptr & operator=( shared_ptr && r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_NOEXCEPT
 | 
			
		||||
    shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
@@ -599,25 +377,15 @@ public:
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
    shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    void reset() BOOST_NOEXCEPT // never throws in 1.30+
 | 
			
		||||
    void reset() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset( Y * p ) // Y must be complete
 | 
			
		||||
    template<class Y> void reset(Y * p) // Y must be complete
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
 | 
			
		||||
        this_type( p ).swap( *this );
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> void reset( Y * p, D d )
 | 
			
		||||
@@ -630,35 +398,24 @@ public:
 | 
			
		||||
        this_type( p, d, a ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
 | 
			
		||||
    template<class Y> void reset( shared_ptr<Y> const & r, T * p )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( r, p ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
 | 
			
		||||
    typename boost::detail::sp_dereference< T >::type operator* () const
 | 
			
		||||
 | 
			
		||||
    reference operator* () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return *px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
 | 
			
		||||
    typename boost::detail::sp_member_access< T >::type operator-> () const 
 | 
			
		||||
 | 
			
		||||
    T * operator-> () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
 | 
			
		||||
    typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
 | 
			
		||||
 | 
			
		||||
        return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element_type * get() const BOOST_NOEXCEPT
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
@@ -666,43 +423,33 @@ public:
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    bool unique() const BOOST_NOEXCEPT
 | 
			
		||||
    bool unique() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.unique();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const BOOST_NOEXCEPT
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap( shared_ptr & other ) BOOST_NOEXCEPT
 | 
			
		||||
    void swap(shared_ptr<T> & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
 | 
			
		||||
    template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT
 | 
			
		||||
    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn.get_deleter( ti );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pn.get_untyped_deleter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
 | 
			
		||||
    bool _internal_equiv( shared_ptr const & r ) const
 | 
			
		||||
    {
 | 
			
		||||
        return px == r.px && pn == r.pn;
 | 
			
		||||
    }
 | 
			
		||||
@@ -720,17 +467,17 @@ private:
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    element_type * px;                 // contained pointer
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    boost::detail::shared_count pn;    // reference counter
 | 
			
		||||
 | 
			
		||||
};  // shared_ptr
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
@@ -739,90 +486,64 @@ template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, share
 | 
			
		||||
 | 
			
		||||
// Resolve the ambiguity between our op!= and the one in rel_ops
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
    return a._internal_less(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return p.get() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    return a.owner_before( b );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 | 
			
		||||
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    (void) static_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
    typedef typename shared_ptr<T>::element_type E;
 | 
			
		||||
 | 
			
		||||
    E * p = static_cast< E* >( r.get() );
 | 
			
		||||
    return shared_ptr<T>( r, p );
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::static_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 | 
			
		||||
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    (void) const_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
    typedef typename shared_ptr<T>::element_type E;
 | 
			
		||||
 | 
			
		||||
    E * p = const_cast< E* >( r.get() );
 | 
			
		||||
    return shared_ptr<T>( r, p );
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::const_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 | 
			
		||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
 | 
			
		||||
    typedef typename shared_ptr<T>::element_type E;
 | 
			
		||||
 | 
			
		||||
    E * p = dynamic_cast< E* >( r.get() );
 | 
			
		||||
    return p? shared_ptr<T>( r, p ): shared_ptr<T>();
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 | 
			
		||||
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::static_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    typedef typename shared_ptr<T>::element_type E;
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    E * p = reinterpret_cast< E* >( r.get() );
 | 
			
		||||
    return shared_ptr<T>( r, p );
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
 | 
			
		||||
    return shared_static_cast<T>(r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
 | 
			
		||||
 | 
			
		||||
template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
@@ -864,9 +585,6 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
 | 
			
		||||
 | 
			
		||||
// get_deleter
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
 | 
			
		||||
    ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
 | 
			
		||||
    ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
 | 
			
		||||
@@ -874,7 +592,7 @@ namespace detail
 | 
			
		||||
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
 | 
			
		||||
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
 | 
			
		||||
 | 
			
		||||
template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
 | 
			
		||||
    return const_cast<D *>(static_cast<D const *>(q));
 | 
			
		||||
@@ -882,64 +600,18 @@ template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
 | 
			
		||||
    return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class esft2_deleter_wrapper
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<void const volatile> deleter_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    esft2_deleter_wrapper()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class T > void set_deleter( shared_ptr<T> const & deleter )
 | 
			
		||||
    {
 | 
			
		||||
        deleter_ = deleter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename D> D* get_deleter() const BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return boost::detail::basic_get_deleter<D>( deleter_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class T> void operator()( T* )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( deleter_.use_count() <= 1 );
 | 
			
		||||
        deleter_.reset();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
{
 | 
			
		||||
    D *del = boost::detail::basic_get_deleter<D>(p);
 | 
			
		||||
 | 
			
		||||
    if(del == 0)
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
 | 
			
		||||
// The following get_deleter method call is fully qualified because
 | 
			
		||||
// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
 | 
			
		||||
        if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return del;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// atomic access
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
 | 
			
		||||
{
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
@@ -950,7 +622,7 @@ template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
 | 
			
		||||
    return *p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ int )
 | 
			
		||||
template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
 | 
			
		||||
{
 | 
			
		||||
    return atomic_load( p );
 | 
			
		||||
}
 | 
			
		||||
@@ -961,7 +633,7 @@ template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
 | 
			
		||||
    p->swap( r );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
 | 
			
		||||
template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
 | 
			
		||||
{
 | 
			
		||||
    atomic_store( p, r ); // std::move( r )
 | 
			
		||||
}
 | 
			
		||||
@@ -977,7 +649,7 @@ template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T
 | 
			
		||||
    return r; // return std::move( r )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
 | 
			
		||||
template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
 | 
			
		||||
{
 | 
			
		||||
    return atomic_exchange( p, r ); // std::move( r )
 | 
			
		||||
}
 | 
			
		||||
@@ -1007,7 +679,7 @@ template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T>
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ int, /*memory_order failure*/ int )
 | 
			
		||||
template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
 | 
			
		||||
{
 | 
			
		||||
    return atomic_compare_exchange( p, v, w ); // std::move( w )
 | 
			
		||||
}
 | 
			
		||||
@@ -1018,11 +690,13 @@ template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> *
 | 
			
		||||
 | 
			
		||||
template< class T > struct hash;
 | 
			
		||||
 | 
			
		||||
template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT
 | 
			
		||||
template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p )
 | 
			
		||||
{
 | 
			
		||||
    return boost::hash< T* >()( p.get() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,11 @@
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
 | 
			
		||||
# pragma warning(push)
 | 
			
		||||
# pragma warning(disable:4284) // odd return type for operator->
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@@ -29,30 +34,14 @@ private:
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::detail::sp_element< T >::type element_type;
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
 | 
			
		||||
    weak_ptr(): px(0), pn() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine...
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
 | 
			
		||||
// ... except in C++0x, move disables the implicit copy
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        px = r.px;
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  The "obvious" converting constructor implementation:
 | 
			
		||||
@@ -81,12 +70,11 @@ public:
 | 
			
		||||
    weak_ptr( weak_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
 | 
			
		||||
    : px(r.lock().get()), pn(r.pn) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
@@ -98,21 +86,19 @@ public:
 | 
			
		||||
    weak_ptr( weak_ptr<Y> && r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // for better efficiency in the T == Y case
 | 
			
		||||
    weak_ptr( weak_ptr && r )
 | 
			
		||||
    BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
 | 
			
		||||
    : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // for better efficiency in the T == Y case
 | 
			
		||||
    weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
 | 
			
		||||
    weak_ptr( weak_ptr && r ): px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // for better efficiency in the T == Y case
 | 
			
		||||
    weak_ptr & operator=( weak_ptr && r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
@@ -131,28 +117,24 @@ public:
 | 
			
		||||
    weak_ptr( shared_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
 | 
			
		||||
    : px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
 | 
			
		||||
    weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        px = r.lock().get();
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
 | 
			
		||||
    weak_ptr & operator=( weak_ptr<Y> && r )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
@@ -161,29 +143,26 @@ public:
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
 | 
			
		||||
    weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_assert_convertible< Y, T >();
 | 
			
		||||
 | 
			
		||||
        px = r.px;
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> lock() const BOOST_NOEXCEPT
 | 
			
		||||
    shared_ptr<T> lock() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
 | 
			
		||||
        return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const BOOST_NOEXCEPT
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool expired() const BOOST_NOEXCEPT
 | 
			
		||||
    bool expired() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count() == 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -193,30 +172,24 @@ public:
 | 
			
		||||
        return pn.empty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() BOOST_NOEXCEPT // never throws in 1.30+
 | 
			
		||||
    void reset() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(this_type & other) BOOST_NOEXCEPT
 | 
			
		||||
    void swap(this_type & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Y>
 | 
			
		||||
    void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
 | 
			
		||||
    void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
 | 
			
		||||
    {
 | 
			
		||||
        px = px2;
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        pn = pn2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
 | 
			
		||||
    template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
@@ -233,21 +206,25 @@ private:
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    element_type * px;            // contained pointer
 | 
			
		||||
    T * px;                       // contained pointer
 | 
			
		||||
    boost::detail::weak_count pn; // reference counter
 | 
			
		||||
 | 
			
		||||
};  // weak_ptr
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.owner_before( b );
 | 
			
		||||
    return a._internal_less(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
 | 
			
		||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif    
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								index.html
									
									
									
									
									
								
							@@ -1,18 +1,15 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
<title>Smart Pointers</title>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
<meta http-equiv="refresh" content="0; URL=smart_ptr.htm">
 | 
			
		||||
</head>
 | 
			
		||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
 | 
			
		||||
<body>
 | 
			
		||||
Automatic redirection failed, please go to
 | 
			
		||||
<a href="smart_ptr.htm">smart_ptr.htm</a>.
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
<!--
 | 
			
		||||
    (C) Copyright Beman Dawes, 2001
 | 
			
		||||
    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
 | 
			
		||||
	<09> Copyright Beman Dawes, 2001
 | 
			
		||||
	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
 | 
			
		||||
-->
 | 
			
		||||
 
 | 
			
		||||
@@ -1,320 +1,297 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>intrusive_ptr</title>
 | 
			
		||||
        <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">intrusive_ptr class template</h1>
 | 
			
		||||
        <p>
 | 
			
		||||
            <a href="#Introduction">Introduction</a><br>
 | 
			
		||||
            <a href="#Synopsis">Synopsis</a><br>
 | 
			
		||||
            <a href="#Members">Members</a><br>
 | 
			
		||||
            <a href="#functions">Free Functions</a><br>
 | 
			
		||||
        </p>
 | 
			
		||||
        <h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
        <p>The <code>intrusive_ptr</code> class template stores a pointer to an object with an 
 | 
			
		||||
            embedded reference count. Every new <code>intrusive_ptr</code> instance increments 
 | 
			
		||||
            the reference count by using an unqualified call to the function <code>intrusive_ptr_add_ref</code>, 
 | 
			
		||||
            passing it the pointer as an argument. Similarly, when an <code>intrusive_ptr</code>
 | 
			
		||||
            is destroyed, it calls <code>intrusive_ptr_release</code>; this function is 
 | 
			
		||||
            responsible for destroying the object when its reference count drops to zero. 
 | 
			
		||||
            The user is expected to provide suitable definitions of these two functions. On 
 | 
			
		||||
            compilers that support argument-dependent lookup, <code>intrusive_ptr_add_ref</code>
 | 
			
		||||
            and <code>intrusive_ptr_release</code> should be defined in the namespace 
 | 
			
		||||
            that corresponds to their parameter; otherwise, the definitions need to go in 
 | 
			
		||||
            namespace <code>boost</code>. The library provides a helper base class template
 | 
			
		||||
            <code><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></code> which may
 | 
			
		||||
            help adding support for <code>intrusive_ptr</code> to user types.</p>
 | 
			
		||||
        <p>The class template is parameterized on <code>T</code>, the type of the object pointed 
 | 
			
		||||
            to. <code>intrusive_ptr<T></code> can be implicitly converted to <code>intrusive_ptr<U></code>
 | 
			
		||||
            whenever <code>T*</code> can be implicitly converted to <code>U*</code>.</p>
 | 
			
		||||
        <p>The main reasons to use <code>intrusive_ptr</code> are:</p>
 | 
			
		||||
        <ul>
 | 
			
		||||
            <li>
 | 
			
		||||
            Some existing frameworks or OSes provide objects with embedded reference 
 | 
			
		||||
            counts;</li>
 | 
			
		||||
            <li>
 | 
			
		||||
                The memory footprint of <code>intrusive_ptr</code>
 | 
			
		||||
            is the same as the corresponding raw pointer;</li>
 | 
			
		||||
            <li>
 | 
			
		||||
                <code>intrusive_ptr<T></code> can be constructed from an arbitrary 
 | 
			
		||||
                raw pointer of type <code>T *</code>.</li></ul>
 | 
			
		||||
        <p>As a general rule, if it isn't obvious whether <code>intrusive_ptr</code> better 
 | 
			
		||||
            fits your needs than <code>shared_ptr</code>, try a <code>shared_ptr</code>-based 
 | 
			
		||||
            design first.</p>
 | 
			
		||||
        <h2><a name="Synopsis">Synopsis</a></h2>
 | 
			
		||||
        <pre>namespace boost {
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>intrusive_ptr</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>intrusive_ptr class template</h1>
 | 
			
		||||
		<p>
 | 
			
		||||
			<A href="#Introduction">Introduction</A><br>
 | 
			
		||||
			<A href="#Synopsis">Synopsis</A><br>
 | 
			
		||||
			<A href="#Members">Members</A><br>
 | 
			
		||||
			<A href="#functions">Free Functions</A><br>
 | 
			
		||||
		</p>
 | 
			
		||||
		<h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
		<p>The <b>intrusive_ptr</b> class template stores a pointer to an object with an 
 | 
			
		||||
			embedded reference count. Every new <b>intrusive_ptr</b> instance increments 
 | 
			
		||||
			the reference count by using an unqualified call to the function <STRONG>intrusive_ptr_add_ref</STRONG>, 
 | 
			
		||||
			passing it the pointer as an argument. Similarly, when an <STRONG>intrusive_ptr</STRONG>
 | 
			
		||||
			is destroyed, it calls <STRONG>intrusive_ptr_release</STRONG>; this function is 
 | 
			
		||||
			responsible for destroying the object when its reference count drops to zero. 
 | 
			
		||||
			The user is expected to provide suitable definitions of these two functions. On 
 | 
			
		||||
			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>
 | 
			
		||||
		<p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
			to. <STRONG>intrusive_ptr<T></STRONG> can be implicitly converted to <STRONG>intrusive_ptr<U></STRONG>
 | 
			
		||||
			whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.</p>
 | 
			
		||||
		<P>The main reasons to use <STRONG>intrusive_ptr</STRONG> are:</P>
 | 
			
		||||
		<UL>
 | 
			
		||||
			<LI>
 | 
			
		||||
			Some existing frameworks or OSes provide objects with embedded reference 
 | 
			
		||||
			counts;
 | 
			
		||||
			<LI>
 | 
			
		||||
				The memory footprint of <STRONG>intrusive_ptr</STRONG>
 | 
			
		||||
			is the same as the corresponding raw pointer;
 | 
			
		||||
			<LI>
 | 
			
		||||
				<STRONG>intrusive_ptr<T></STRONG> can be constructed from an arbitrary 
 | 
			
		||||
				raw pointer of type <STRONG>T *</STRONG>.</LI></UL>
 | 
			
		||||
		<P>As a general rule, if it isn't obvious whether <STRONG>intrusive_ptr</STRONG> better 
 | 
			
		||||
			fits your needs than <STRONG>shared_ptr</STRONG>, try a <STRONG>shared_ptr</STRONG>-based 
 | 
			
		||||
			design first.</P>
 | 
			
		||||
		<h2><a name="Synopsis">Synopsis</a></h2>
 | 
			
		||||
		<pre>namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class intrusive_ptr {
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      typedef T <a href="#element_type" >element_type</a>;
 | 
			
		||||
      typedef T <A href="#element_type" >element_type</A>;
 | 
			
		||||
 | 
			
		||||
      <a href="#constructors" >intrusive_ptr</a>(); // never throws
 | 
			
		||||
      <a href="#constructors" >intrusive_ptr</a>(T * p, bool add_ref = true);
 | 
			
		||||
      <A href="#constructors" >intrusive_ptr</A>(); // never throws
 | 
			
		||||
      <A href="#constructors" >intrusive_ptr</A>(T * p, bool add_ref = true);
 | 
			
		||||
 | 
			
		||||
      <a href="#constructors" >intrusive_ptr</a>(intrusive_ptr const & r);
 | 
			
		||||
      template<class Y> <a href="#constructors" >intrusive_ptr</a>(intrusive_ptr<Y> const & r);
 | 
			
		||||
      <A href="#constructors" >intrusive_ptr</A>(intrusive_ptr const & r);
 | 
			
		||||
      template<class Y> <A href="#constructors" >intrusive_ptr</A>(intrusive_ptr<Y> const & r);
 | 
			
		||||
 | 
			
		||||
      <a href="#destructor" >~intrusive_ptr</a>();
 | 
			
		||||
      <A href="#destructor" >~intrusive_ptr</A>();
 | 
			
		||||
 | 
			
		||||
      intrusive_ptr & <a href="#assignment" >operator=</a>(intrusive_ptr const & r);
 | 
			
		||||
      template<class Y> intrusive_ptr & <a href="#assignment" >operator=</a>(intrusive_ptr<Y> const & r);
 | 
			
		||||
      intrusive_ptr & <a href="#assignment" >operator=</a>(T * r);
 | 
			
		||||
      intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr const & r);
 | 
			
		||||
      template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr<Y> const & r);
 | 
			
		||||
      intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
 | 
			
		||||
 | 
			
		||||
      void <a href="#reset" >reset</a>();
 | 
			
		||||
      void <a href="#reset" >reset</a>(T * r);
 | 
			
		||||
      void <a href="#reset" >reset</a>(T * r, bool add_ref);
 | 
			
		||||
 | 
			
		||||
      T & <a href="#indirection" >operator*</a>() const; // never throws
 | 
			
		||||
      T * <a href="#indirection" >operator-></a>() const; // never throws
 | 
			
		||||
      T * <a href="#get" >get</a>() const; // never throws
 | 
			
		||||
      T * <a href="#detach" >detach</a>(); // never throws
 | 
			
		||||
      T & <A href="#indirection" >operator*</A>() const; // never throws
 | 
			
		||||
      T * <A href="#indirection" >operator-></A>() const; // never throws
 | 
			
		||||
      T * <A href="#get" >get</A>() const; // never throws
 | 
			
		||||
 | 
			
		||||
      operator <a href="#conversions" ><i>unspecified-bool-type</i></a>() const; // never throws
 | 
			
		||||
      operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
 | 
			
		||||
 | 
			
		||||
      void <a href="#swap" >swap</a>(intrusive_ptr & b); // never throws
 | 
			
		||||
      void <A href="#swap" >swap</A>(intrusive_ptr & b); // never throws
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool <a href="#comparison" >operator==</a>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
 | 
			
		||||
    bool <A href="#comparison" >operator==</A>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool <a href="#comparison" >operator!=</a>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
 | 
			
		||||
    bool <A href="#comparison" >operator!=</A>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool <a href="#comparison" >operator==</a>(intrusive_ptr<T> const & a, T * b); // never throws
 | 
			
		||||
    bool <A href="#comparison" >operator==</A>(intrusive_ptr<T> const & a, T * b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool <a href="#comparison" >operator!=</a>(intrusive_ptr<T> const & a, T * b); // never throws
 | 
			
		||||
    bool <A href="#comparison" >operator!=</A>(intrusive_ptr<T> const & a, T * b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool <a href="#comparison" >operator==</a>(T * a, intrusive_ptr<T> const & b); // never throws
 | 
			
		||||
    bool <A href="#comparison" >operator==</A>(T * a, intrusive_ptr<T> const & b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T>
 | 
			
		||||
    bool <a href="#comparison" >operator!=</a>(T * a, intrusive_ptr<T> const & b); // never throws
 | 
			
		||||
    bool <A href="#comparison" >operator!=</A>(T * a, intrusive_ptr<T> const & b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    bool <a href="#comparison" >operator<</a>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
 | 
			
		||||
    bool <A href="#comparison" >operator<</A>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T> void <a href="#free-swap" >swap</a>(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws
 | 
			
		||||
  template<class T> void <A href="#free-swap" >swap</A>(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T> T * <a href="#get_pointer" >get_pointer</a>(intrusive_ptr<T> const & p); // never throws
 | 
			
		||||
  template<class T> T * <A href="#get_pointer" >get_pointer</A>(intrusive_ptr<T> const & p); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    intrusive_ptr<T> <a href="#static_pointer_cast" >static_pointer_cast</a>(intrusive_ptr<U> const & r); // never throws
 | 
			
		||||
    intrusive_ptr<T> <A href="#static_pointer_cast" >static_pointer_cast</A>(intrusive_ptr<U> const & r); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    intrusive_ptr<T> <a href="#const_pointer_cast" >const_pointer_cast</a>(intrusive_ptr<U> const & r); // never throws
 | 
			
		||||
    intrusive_ptr<T> <A href="#const_pointer_cast" >const_pointer_cast</A>(intrusive_ptr<U> const & r); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class T, class U>
 | 
			
		||||
    intrusive_ptr<T> <a href="#dynamic_pointer_cast" >dynamic_pointer_cast</a>(intrusive_ptr<U> const & r); // never throws
 | 
			
		||||
    intrusive_ptr<T> <A href="#dynamic_pointer_cast" >dynamic_pointer_cast</A>(intrusive_ptr<U> const & r); // never throws
 | 
			
		||||
 | 
			
		||||
  template<class E, class T, class Y>
 | 
			
		||||
    std::basic_ostream<E, T> & <a href="#insertion-operator" >operator<<</a> (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
 | 
			
		||||
    std::basic_ostream<E, T> & <A href="#insertion-operator" >operator<<</A> (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
 | 
			
		||||
 | 
			
		||||
}</pre>
 | 
			
		||||
        <h2><a name="Members">Members</a></h2>
 | 
			
		||||
        <h3><a name="element_type">element_type</a></h3>
 | 
			
		||||
        <pre>typedef T element_type;</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p>Provides the type of the template parameter <code>T</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="constructors">constructors</a></h3>
 | 
			
		||||
        <pre>intrusive_ptr(); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Postconditions:</b> <code>get() == 0</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>intrusive_ptr(T * p, bool add_ref = true);</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> <code>if(p != 0 && add_ref) intrusive_ptr_add_ref(p);</code>.</p>
 | 
			
		||||
            <p><b>Postconditions:</b> <code>get() == p</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>intrusive_ptr(intrusive_ptr const & r);
 | 
			
		||||
		<h2><a name="Members">Members</a></h2>
 | 
			
		||||
		<h3><a name="element_type">element_type</a></h3>
 | 
			
		||||
		<pre>typedef T element_type;</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p>Provides the type of the template parameter T.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="constructors">constructors</a></h3>
 | 
			
		||||
		<pre>intrusive_ptr(); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() == 0</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>intrusive_ptr(T * p, bool add_ref = true);</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Effects:</b> <code>if(p != 0 && add_ref) intrusive_ptr_add_ref(p);</code>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() == p</code>.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>intrusive_ptr(intrusive_ptr const & r);
 | 
			
		||||
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> <code>if(r.get() != 0) intrusive_ptr_add_ref(r.get());</code>.</p>
 | 
			
		||||
            <p><b>Postconditions:</b> <code>get() == r.get()</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
        <pre>~intrusive_ptr();</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="assignment">assignment</a></h3>
 | 
			
		||||
        <pre>intrusive_ptr & operator=(intrusive_ptr const & r);
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Effects:</b> <code>if(r.get() != 0) intrusive_ptr_add_ref(r.get());</code>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() == r.get()</code>.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
		<pre>~intrusive_ptr();</pre>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<H3><a name="assignment">assignment</a></H3>
 | 
			
		||||
		<pre>intrusive_ptr & operator=(intrusive_ptr const & r);
 | 
			
		||||
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
 | 
			
		||||
intrusive_ptr & operator=(T * r);</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
 | 
			
		||||
            <p><b>Returns:</b> <code>*this</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="reset">reset</a></h3>
 | 
			
		||||
        <pre>void reset();</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>void reset(T * r);</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>void reset(T * r, bool add_ref);</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r, add_ref).swap(*this)</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="indirection">indirection</a></h3>
 | 
			
		||||
        <pre>T & operator*() const; // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Requirements:</b> <code>get() != 0</code>.</p>
 | 
			
		||||
            <p><b>Returns:</b> <code>*get()</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>T * operator->() const; // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Requirements:</b> <code>get() != 0</code>.</p>
 | 
			
		||||
            <p><b>Returns:</b> <code>get()</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="get">get</a></h3>
 | 
			
		||||
        <pre>T * get() const; // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> the stored pointer.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="detach">detach</a></h3>
 | 
			
		||||
        <pre>T * detach(); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> the stored pointer.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
            <p><b>Postconditions:</b> <code>get() == 0</code>.</p>
 | 
			
		||||
            <p><b>Notes:</b> The returned pointer has an elevated reference count. This
 | 
			
		||||
                allows conversion of an <code>intrusive_ptr</code> back to a raw pointer,
 | 
			
		||||
                without the performance overhead of acquiring and dropping an extra
 | 
			
		||||
                reference. It can be viewed as the complement of the
 | 
			
		||||
                non-reference-incrementing constructor.</p>
 | 
			
		||||
            <p><b>Caution:</b> Using <code>detach</code> escapes the safety of automatic
 | 
			
		||||
                reference counting provided by <code>intrusive_ptr</code>. It should
 | 
			
		||||
                by used only where strictly necessary (such as when interfacing to an
 | 
			
		||||
                existing API), and when the implications are thoroughly understood.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
        <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is 
 | 
			
		||||
                equivalent to <code>get() != 0</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
            <p><b>Notes:</b> This conversion operator allows <code>intrusive_ptr</code> objects to be 
 | 
			
		||||
                used in boolean contexts, like <code>if (p && p->valid()) {}</code>. 
 | 
			
		||||
                The actual target type is typically a pointer to a member function, avoiding 
 | 
			
		||||
                many of the implicit conversion pitfalls.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="swap">swap</a></h3>
 | 
			
		||||
        <pre>void swap(intrusive_ptr & b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
        <h3><a name="comparison">comparison</a></h3>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
 | 
			
		||||
			<P><B>Returns:</B> <code>*this</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<H3><a name="reset">reset</a></H3>
 | 
			
		||||
		<pre>void reset();</pre>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<pre>void reset(T * r);</pre>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="indirection">indirection</a></h3>
 | 
			
		||||
		<pre>T & operator*() const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Requirements:</b> <code>get() != 0</code>.</p>
 | 
			
		||||
			<p><b>Returns:</b> <code>*get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>T * operator->() const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Requirements:</b> <code>get() != 0</code>.</p>
 | 
			
		||||
			<p><b>Returns:</b> <code>get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="get">get</a></h3>
 | 
			
		||||
		<pre>T * get() const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> the stored pointer.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
		<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is 
 | 
			
		||||
				equivalent to <code>get() != 0</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> This conversion operator allows <b>intrusive_ptr</b> objects to be 
 | 
			
		||||
				used in boolean contexts, like <code>if (p && p->valid()) {}</code>. 
 | 
			
		||||
				The actual target type is typically a pointer to a member function, avoiding 
 | 
			
		||||
				many of the implicit conversion pitfalls.</P>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="swap">swap</a></h3>
 | 
			
		||||
		<pre>void swap(intrusive_ptr & b); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Effects:</b> Exchanges the contents of the two smart pointers.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
		<h3><a name="comparison">comparison</a></h3>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>a.get() == b.get()</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a.get() == b.get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator==(intrusive_ptr<T> const & a, U * b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>a.get() == b</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a.get() == b</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator!=(intrusive_ptr<T> const & a, U * b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>a.get() != b</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a.get() != b</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator==(T * a, intrusive_ptr<U> const & b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>a == b.get()</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a == b.get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator!=(T * a, intrusive_ptr<U> const & b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>a != b.get()</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a != b.get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>std::less<T *>()(a.get(), b.get())</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
            <p><b>Notes:</b> Allows <code>intrusive_ptr</code> objects to be used as keys 
 | 
			
		||||
                in associative containers.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
        <pre>template<class T>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>std::less<T *>()(a.get(), b.get())</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> Allows <STRONG>intrusive_ptr</STRONG> objects to be used as keys 
 | 
			
		||||
				in associative containers.</P>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> Equivalent to <code>a.swap(b)</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
            <p><b>Notes:</b> Matches the interface of <code>std::swap</code>. Provided as an aid to 
 | 
			
		||||
                generic programming.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="get_pointer">get_pointer</a></h3>
 | 
			
		||||
        <pre>template<class T>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
			<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to 
 | 
			
		||||
				generic programming.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="get_pointer">get_pointer</a></h3>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  T * get_pointer(intrusive_ptr<T> const & p); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>p.get()</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
            <p><b>Notes:</b> Provided as an aid to generic programming. Used by <a href="../bind/mem_fn.html">
 | 
			
		||||
                    mem_fn</a>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="static_pointer_cast">static_pointer_cast</a></h3>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Returns:</B> <code>p.get()</code>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
			<P><B>Notes:</B> Provided as an aid to generic programming. Used by <A href="../bind/mem_fn.html">
 | 
			
		||||
					mem_fn</A>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="static_pointer_cast">static_pointer_cast</a></h3>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>intrusive_ptr<T>(static_cast<T*>(r.get()))</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Returns:</B> <code>intrusive_ptr<T>(static_cast<T*>(r.get()))</code>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r); // never throws</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>intrusive_ptr<T>(const_cast<T*>(r.get()))</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
 | 
			
		||||
        <pre>template<class T, class U>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Returns:</B> <code>intrusive_ptr<T>(const_cast<T*>(r.get()))</code>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r);</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Returns:</b> <code>intrusive_ptr<T>(dynamic_cast<T*>(r.get()))</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> nothing.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h3><a name="insertion-operator">operator<<</a></h3>
 | 
			
		||||
        <pre>template<class E, class T, class Y>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Returns:</B> <code>intrusive_ptr<T>(dynamic_cast<T*>(r.get()))</code>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="insertion-operator">operator<<</a></h3>
 | 
			
		||||
		<pre>template<class E, class T, class Y>
 | 
			
		||||
    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Effects:</b> <code>os << p.get();</code>.</p>
 | 
			
		||||
            <p><b>Returns:</b> <code>os</code>.</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p>
 | 
			
		||||
            <small>Copyright © 2003-2005, 2013 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>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<p><STRONG>Effects:</STRONG> <code>os << p.get();</code>.</p>
 | 
			
		||||
			<P><B>Returns:</B> <code>os</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>
 | 
			
		||||
			$Date$</p>
 | 
			
		||||
		<p>
 | 
			
		||||
			<small>Copyright <20> 2003-2005 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>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,94 +0,0 @@
 | 
			
		||||
<!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" link="#0000ff" vlink="#0000ff">
 | 
			
		||||
        <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png" 
 | 
			
		||||
            width="277" align="middle" border="0">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'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'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<class DerivedT, class CounterPolicyT = thread_safe_counter>
 | 
			
		||||
  class intrusive_ref_counter
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
      <A href="#constructors" >intrusive_ref_counter</A>() = noexcept;
 | 
			
		||||
      <A href="#constructors" >intrusive_ref_counter</A>(intrusive_ref_counter const & r) = noexcept;
 | 
			
		||||
 | 
			
		||||
      intrusive_ref_counter & <A href="#assignment" >operator=</A>(intrusive_ref_counter const & 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 &);</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 & operator=(intrusive_ref_counter const & 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 © 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>
 | 
			
		||||
							
								
								
									
										154
									
								
								make_shared.html
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								make_shared.html
									
									
									
									
									
								
							@@ -1,38 +1,37 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>make_shared and allocate_shared</title>
 | 
			
		||||
        <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">make_shared and allocate_shared 
 | 
			
		||||
            function templates</h1>
 | 
			
		||||
        <p><A href="#Introduction">Introduction</A><br>
 | 
			
		||||
            <A href="#Synopsis">Synopsis</A><br>
 | 
			
		||||
            <A href="#functions">Free Functions</A><br>
 | 
			
		||||
            <A href="#example">Example</A><br>
 | 
			
		||||
        <h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
        <p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a>
 | 
			
		||||
            can eliminate the need to use an explicit <code>delete</code>,
 | 
			
		||||
            but alone it provides no support in avoiding explicit <code>new</code>.
 | 
			
		||||
            There have been repeated requests from users for a factory function that creates
 | 
			
		||||
            an object of a given type and returns a <code>shared_ptr</code> to it.
 | 
			
		||||
            Besides convenience and style, such a function is also exception safe and
 | 
			
		||||
            considerably faster because it can use a single allocation for both the object
 | 
			
		||||
            and its corresponding control block, eliminating a significant portion of
 | 
			
		||||
            <code>shared_ptr</code>'s construction overhead.
 | 
			
		||||
            This eliminates one of the major efficiency complaints about <code>shared_ptr</code>.
 | 
			
		||||
        </p>
 | 
			
		||||
        <p>The header file <boost/make_shared.hpp> provides a family of overloaded function templates,
 | 
			
		||||
            <code>make_shared</code> and <code>allocate_shared</code>, to address this need.
 | 
			
		||||
            <code>make_shared</code> uses the global operator <code>new</code> to allocate memory,
 | 
			
		||||
            whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p>
 | 
			
		||||
        <p>
 | 
			
		||||
            The rationale for choosing the name <code>make_shared</code> is that the expression
 | 
			
		||||
            <code>make_shared<Widget>()</code> can be read aloud and conveys the intended meaning.</p>
 | 
			
		||||
        <h2><a name="Synopsis">Synopsis</a></h2>
 | 
			
		||||
        <pre>namespace boost {
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>make_shared and allocate_shared</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>make_shared and allocate_shared function templates</h1>
 | 
			
		||||
		<p><A href="#Introduction">Introduction</A><br>
 | 
			
		||||
			<A href="#Synopsis">Synopsis</A><br>
 | 
			
		||||
			<A href="#functions">Free Functions</A><br>
 | 
			
		||||
			<A href="#example">Example</A><br>
 | 
			
		||||
		<h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
		<p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a>
 | 
			
		||||
			can eliminate the need to use an explicit <code>delete</code>,
 | 
			
		||||
			but alone it provides no support in avoiding explicit <code>new</code>.
 | 
			
		||||
			There have been repeated requests from users for a factory function that creates
 | 
			
		||||
			an object of a given type and returns a <code>shared_ptr</code> to it.
 | 
			
		||||
			Besides convenience and style, such a function is also exception safe and
 | 
			
		||||
			considerably faster because it can use a single allocation for both the object
 | 
			
		||||
			and its corresponding control block, eliminating a significant portion of
 | 
			
		||||
			<code>shared_ptr</code>'s construction overhead.
 | 
			
		||||
			This eliminates one of the major efficiency complaints about <code>shared_ptr</code>.
 | 
			
		||||
		</p>
 | 
			
		||||
		<p>The header file <boost/make_shared.hpp> provides a family of overloaded function templates,
 | 
			
		||||
			<code>make_shared</code> and <code>allocate_shared</code>, to address this need.
 | 
			
		||||
			<code>make_shared</code> uses the global operator <code>new</code> to allocate memory,
 | 
			
		||||
			whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p>
 | 
			
		||||
		<p>
 | 
			
		||||
			The rationale for choosing the name <code>make_shared</code> is that the expression
 | 
			
		||||
			<code>make_shared<Widget>()</code> can be read aloud and conveys the intended meaning.</p>
 | 
			
		||||
		<h2><a name="Synopsis">Synopsis</a></h2>
 | 
			
		||||
		<pre>namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<typename T> class shared_ptr;
 | 
			
		||||
 | 
			
		||||
@@ -42,7 +41,7 @@
 | 
			
		||||
  template<typename T, typename A>
 | 
			
		||||
    shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & );
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )    // C++0x prototypes
 | 
			
		||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )	// C++0x prototypes
 | 
			
		||||
 | 
			
		||||
  template<typename T, typename... Args>
 | 
			
		||||
    shared_ptr<T> <a href="#functions">make_shared</a>( Args && ... args );
 | 
			
		||||
@@ -70,50 +69,51 @@
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
}</pre>
 | 
			
		||||
        <h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
        <pre>template<class T, class... Args>
 | 
			
		||||
		<h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
		<pre>template<class T, class... Args>
 | 
			
		||||
    shared_ptr<T> make_shared( Args && ... args );
 | 
			
		||||
template<class T, class A, class... Args>
 | 
			
		||||
    shared_ptr<T> allocate_shared( A const & a, Args && ... args );</pre>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <p><b>Requires:</b> The expression <code>new( pv ) T( std::forward<Args>(args)... )</code>,
 | 
			
		||||
                where <code>pv</code> is a <code>void*</code> pointing to storage suitable
 | 
			
		||||
                to hold an object of type <code>T</code>,
 | 
			
		||||
                shall be well-formed.  <code>A</code> shall be an <em>Allocator</em>,
 | 
			
		||||
                as described in section 20.1.5 (<strong>Allocator requirements</strong>) of the C++ Standard.
 | 
			
		||||
                The copy constructor and destructor of <code>A</code> shall not throw.</p>
 | 
			
		||||
            <p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
 | 
			
		||||
                and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
 | 
			
		||||
                or <code>new( pv ) T( std::forward<Args>(args)... )</code>.
 | 
			
		||||
                <code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory.
 | 
			
		||||
                If an exception is thrown, has no effect.</p>
 | 
			
		||||
            <p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address
 | 
			
		||||
                of the newly constructed object of type <code>T</code>.</p>
 | 
			
		||||
            <p><b>Postconditions:</b> <code>get() != 0 && use_count() == 1</code>.</p>
 | 
			
		||||
            <p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code>
 | 
			
		||||
                or the constructor of <code>T</code>.</p>
 | 
			
		||||
            <p><b>Notes:</b> This implementation allocates the memory required for the
 | 
			
		||||
                returned <code>shared_ptr</code> and an object of type <code>T</code> in a single
 | 
			
		||||
                allocation. This provides efficiency equivalent to an intrusive smart pointer.</p>
 | 
			
		||||
            <p>The prototypes shown above are used if your compiler supports rvalue references
 | 
			
		||||
                and variadic templates.  They perfectly forward the <code>args</code> parameters to
 | 
			
		||||
                the constructors of <code>T</code>.</p>
 | 
			
		||||
            <p>Otherwise, the implementation will fall back on
 | 
			
		||||
                forwarding the arguments to the constructors of <code>T</code> as const references.
 | 
			
		||||
                If you need to pass a non-const reference to a constructor of <code>T</code>,
 | 
			
		||||
                you may do so by wrapping the parameter in a call to <code>boost::ref</code>.
 | 
			
		||||
                In addition, you will be
 | 
			
		||||
                limited to a maximum of 9 arguments (not counting the allocator argument of
 | 
			
		||||
                allocate_shared).</p>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h2><a name="example">Example</a></h2>
 | 
			
		||||
        <pre>boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!");
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Requires:</b> The expression <code>new( pv ) T( std::forward<Args>(args)... )</code>,
 | 
			
		||||
				where <code>pv</code> is a <code>void*</code> pointing to storage suitable
 | 
			
		||||
				to hold an object of type <code>T</code>,
 | 
			
		||||
				shall be well-formed.  <code>A</code> shall be an <em>Allocator</em>,
 | 
			
		||||
				as described in section 20.1.5 (<stong>Allocator requirements</strong>) of the C++ Standard.
 | 
			
		||||
				The copy constructor and destructor of <code>A</code> shall not throw.</p>
 | 
			
		||||
			<p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
 | 
			
		||||
				and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
 | 
			
		||||
				or <code>new( pv ) T( std::forward<Args>(args)... )</code>.
 | 
			
		||||
				<code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory.
 | 
			
		||||
				If an exception is thrown, has no effect.</p>
 | 
			
		||||
			<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address
 | 
			
		||||
				of the newly constructed object of type <code>T</code>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() != 0 && use_count() == 1</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code>
 | 
			
		||||
				or the constructor of <code>T</code>.</p>
 | 
			
		||||
			<p><b>Notes:</b> This implementation allocates the memory required for the
 | 
			
		||||
			returned <code>shared_ptr</code> and an object of type <code>T</code> in a single
 | 
			
		||||
			allocation. This provides efficiency equivalent to an intrusive smart pointer.</p>
 | 
			
		||||
			<p>The prototypes shown above are used if your compiler supports rvalue references
 | 
			
		||||
			and variadic templates.  They perfectly forward the <code>args</code> parameters to
 | 
			
		||||
			the constructors of <code>T</code>.</p>
 | 
			
		||||
			<p>Otherwise, the implementation will fall back on
 | 
			
		||||
			forwarding the arguments to the constructors of <code>T</code> as const references.
 | 
			
		||||
			If you need to pass a non-const reference to a constructor of <code>T</code>,
 | 
			
		||||
			you may do so by wrapping the parameter in a call to <code>boost::ref</code>.
 | 
			
		||||
			In addition, you will be
 | 
			
		||||
			limited to a maximum of 9 arguments (not counting the allocator argument of
 | 
			
		||||
			allocate_shared).</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h2><a name="example">Example</a></h2>
 | 
			
		||||
		<pre>boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!");
 | 
			
		||||
std::cout << *x;</pre>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
 | 
			
		||||
            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>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>
 | 
			
		||||
			$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</p>
 | 
			
		||||
		<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
 | 
			
		||||
				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>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,273 +0,0 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <title>make_shared and allocate_shared for arrays</title>
 | 
			
		||||
    <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">make_shared and allocate_shared 
 | 
			
		||||
      for arrays</h1>
 | 
			
		||||
    <p><a href="#introduction">Introduction</a><br>
 | 
			
		||||
      <a href="#synopsis">Synopsis</a><br>
 | 
			
		||||
      <a href="#common">Common Requirements</a><br>
 | 
			
		||||
      <a href="#functions">Free Functions</a><br>
 | 
			
		||||
      <a href="#history">History</a><br>
 | 
			
		||||
      <a href="#references">References</a></p>
 | 
			
		||||
    <h2><a name="introduction">Introduction</a></h2>
 | 
			
		||||
    <p>Originally the Boost function templates <code>make_shared</code> and 
 | 
			
		||||
      <code>allocate_shared</code> were for efficient allocation of shared 
 | 
			
		||||
      objects only. There was a need to have efficient allocation of 
 | 
			
		||||
      shared arrays. One criticism of class template <code>shared_array</code> 
 | 
			
		||||
      was always the lack of a <a href="make_shared.html">make_shared</a> 
 | 
			
		||||
      utility which ensures only a single allocation.</p>
 | 
			
		||||
    <p>The header files <boost/smart_ptr/make_shared_array.hpp> and 
 | 
			
		||||
      <boost/smart_ptr/allocate_shared_array.hpp> provide function 
 | 
			
		||||
      templates, overloads of <code>make_shared</code> and 
 | 
			
		||||
      <code>allocate_shared</code> for array types, to address this need. 
 | 
			
		||||
      <code>make_shared</code> uses the global operator <code>new</code> to 
 | 
			
		||||
      allocate memory, whereas <code>allocate_shared</code> uses an 
 | 
			
		||||
      user-supplied allocator, allowing finer control.</p>
 | 
			
		||||
    <h2><a name="synopsis">Synopsis</a></h2>
 | 
			
		||||
    <pre>namespace boost {
 | 
			
		||||
    template<class U> // U is T[]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">make_shared</a>(size_t size);
 | 
			
		||||
 | 
			
		||||
    template<class U, class A> // U is T[]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size);
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is T[N]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">make_shared</a>();
 | 
			
		||||
 | 
			
		||||
    template<class U, class A> // U is T[N]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator);
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is T[]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, const T& value);
 | 
			
		||||
 | 
			
		||||
    template<class U, class A>  // U is T[]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, const T& value);
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is T[N]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">make_shared</a>(const T& value);
 | 
			
		||||
 | 
			
		||||
    template<class U, class A> // U is T[N]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, const T& value);
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is T[]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">make_shared_noinit</a>(size_t size);
 | 
			
		||||
 | 
			
		||||
    template<class U, class A> // U is T[]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator, size_t size);
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is T[N]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">make_shared_noinit</a>();
 | 
			
		||||
 | 
			
		||||
    template<class U, class A> // U is T[N]
 | 
			
		||||
    shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator);
 | 
			
		||||
}</pre>
 | 
			
		||||
    <h2><a name="common">Common Requirements</a></h2>
 | 
			
		||||
    <pre>template<class U>
 | 
			
		||||
    shared_ptr<U> make_shared(<em>args</em>);
 | 
			
		||||
template<class U, class A>
 | 
			
		||||
    shared_ptr<U> allocate_shared(const A& allocator, <em>args</em>);
 | 
			
		||||
template<class U>
 | 
			
		||||
    shared_ptr<U> make_shared_noinit(<em>args</em>);
 | 
			
		||||
template<class U, class A>
 | 
			
		||||
    shared_ptr<U> allocate_shared_noinit(const A& allocator, <em>args</em>);</pre>
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Requires:</b> <code>U</code> is of the form <code>T[]</code> or 
 | 
			
		||||
        <code>T[N]</code>. <code>A</code> shall be an <em>Allocator</em>, as 
 | 
			
		||||
        described in section 17.6.3.5 [<strong>Allocator 
 | 
			
		||||
        requirements</strong>] of the C++ Standard. The copy constructor and 
 | 
			
		||||
        destructor of <code>A</code> shall not throw exceptions.</p>
 | 
			
		||||
      <p><b>Effects:</b> Allocates memory for an object of type <code>U</code> 
 | 
			
		||||
        (or <code>T[size]</code> when <code>U</code> is <code>T[]</code>, 
 | 
			
		||||
        where <code>size</code> is determined from <code><em>args</em></code> 
 | 
			
		||||
        as specified by the concrete overload). The object is initialized as 
 | 
			
		||||
        specified by the concrete overload. The templates 
 | 
			
		||||
        <code>allocate_shared</code> and <code>allocate_shared_noinit</code>
 | 
			
		||||
        use a copy of <code>allocator</code> to allocate memory. If an 
 | 
			
		||||
        exception is thrown, the functions have no effect.</p>
 | 
			
		||||
      <p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and 
 | 
			
		||||
        owns the address of the newly constructed object.</p>
 | 
			
		||||
      <p><b>Postconditions:</b> <code>r.get() != 0 && 
 | 
			
		||||
        r.use_count() == 1</code>, where <code>r</code> is the return 
 | 
			
		||||
        value.</p>
 | 
			
		||||
      <p><b>Throws:</b> <code>bad_alloc</code>, an exception thrown from 
 | 
			
		||||
        <code>A::allocate</code>, or from the initialization of the 
 | 
			
		||||
        object.</p>
 | 
			
		||||
      <p><b>Remarks:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <p>This implementation performs no more than one memory 
 | 
			
		||||
          allocation. This provides efficiency to equivalent to an intrusive 
 | 
			
		||||
          smart pointer.</p>
 | 
			
		||||
        <p>When an object of an array type <code>T</code> is specified to be 
 | 
			
		||||
          initialized to a value of the same type <code>value</code>, this 
 | 
			
		||||
          shall be interpreted to mean that each array element of the object 
 | 
			
		||||
          is initialized to the corresponding element from 
 | 
			
		||||
          <code>value</code>.</p>
 | 
			
		||||
        <p>When an object of an array type is specified to be 
 | 
			
		||||
          value-initialized, this shall be interpreted to mean that each 
 | 
			
		||||
          array element of the object is value-initialized.</p>
 | 
			
		||||
        <p>Array elements are initialized in ascending order of their 
 | 
			
		||||
          addresses.</p>
 | 
			
		||||
        <p>When a subobject of a non-array type <code>T</code> is specified to 
 | 
			
		||||
          be initialized to a value <code>value</code>, 
 | 
			
		||||
          <code>make_shared</code> shall perform this initialization via the 
 | 
			
		||||
          expression <code>::new(ptr) T(value)</code>, where <code>ptr</code> 
 | 
			
		||||
          has type <code>void*</code> and points to storage suitable to hold 
 | 
			
		||||
          an object of type <code>T</code>.</p>
 | 
			
		||||
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
			
		||||
          be initialized to a value <code>value</code>, 
 | 
			
		||||
          <code>allocate_shared</code> shall perform this initialization via 
 | 
			
		||||
          the expression <code>allocator_traits<A2>::construct(a2, ptr, 
 | 
			
		||||
          value)</code>, where <code>ptr</code> points to storage suitable to 
 | 
			
		||||
          hold an object of type <code>T</code> and <code>a2</code> of type A2 
 | 
			
		||||
          is a rebound copy of the allocator <code>allocator</code> passed to
 | 
			
		||||
          <code>allocate_shared</code> such that its <code>value_type</code> 
 | 
			
		||||
          is <code>T</code>.</p>
 | 
			
		||||
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
			
		||||
          be value-initialized, <code>make_shared</code> shall perform this 
 | 
			
		||||
          initialization via the expression <code>::new(ptr) T()</code>, where 
 | 
			
		||||
          <code>ptr</code> has type <code>void*</code> and points to storage 
 | 
			
		||||
          suitable to hold an object of type <code>T</code>.</p>
 | 
			
		||||
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
			
		||||
          be value-initialized, <code>allocate_shared</code> shall perform 
 | 
			
		||||
          this initialization via the expression
 | 
			
		||||
          <code>allocator_traits<A2>::construct(a2, ptr)</code>, where 
 | 
			
		||||
          <code>ptr</code> points to storage suitable to hold an object 
 | 
			
		||||
          of type <code>T</code> and <code>a2</code> of type A2 is a rebound 
 | 
			
		||||
          copy of the allocator <code>allocator</code> passed to
 | 
			
		||||
          <code>allocate_shared</code> such that its <code>value_type</code> 
 | 
			
		||||
          is <code>T</code>.</p>
 | 
			
		||||
        <p>When a subobject of non-array type <code>T</code> is specified to 
 | 
			
		||||
          be default-initialized, <code>make_shared_noinit</code> and 
 | 
			
		||||
          <code>allocate_shared_noinit</code> shall perform this 
 | 
			
		||||
          initialization via the expression <code>::new(ptr) T</code>, where 
 | 
			
		||||
          <code>ptr</code> has type <code>void*</code> and points to storage 
 | 
			
		||||
          suitable to hold an object of type <code>T</code>.</p>
 | 
			
		||||
        <p>When the lifetime of the object managed by the return value ends, 
 | 
			
		||||
          or when the initialization of an array element throws an exception, 
 | 
			
		||||
          the initialized elements should be destroyed in the reverse order 
 | 
			
		||||
          of their construction.</p>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
      <p><b>Notes:</b> These functions will typically allocate more memory 
 | 
			
		||||
        than <code>sizeof(U)</code> to allow for internal bookkeeping 
 | 
			
		||||
        structures such as the reference counts.</p>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
    <pre>template<class U> 
 | 
			
		||||
    shared_ptr<U> make_shared(size_t size);
 | 
			
		||||
template<class U, class A> 
 | 
			
		||||
    shared_ptr<U> allocate_shared(const A& allocator, size_t size);</pre>
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized 
 | 
			
		||||
        object of type <code>T[size]</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>      
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
 | 
			
		||||
boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U> 
 | 
			
		||||
    shared_ptr<U> make_shared();
 | 
			
		||||
template<class U, class A> 
 | 
			
		||||
    shared_ptr<U> allocate_shared(const A& allocator);</pre>
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized 
 | 
			
		||||
        object of type <code>T[N]</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>();
 | 
			
		||||
boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>();</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U> 
 | 
			
		||||
    shared_ptr<U> make_shared(size_t size, const T& value);
 | 
			
		||||
template<class U, class A> 
 | 
			
		||||
    shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);</pre>
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A <code>shared_ptr</code> to an object of type 
 | 
			
		||||
        <code>T[size]</code>, where each array element of type <code>T</code> 
 | 
			
		||||
        is initialized to <code>value</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size, 1);
 | 
			
		||||
boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size, {1, 2});</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U> 
 | 
			
		||||
    shared_ptr<U> make_shared(const T& value);
 | 
			
		||||
template<class U, class A> 
 | 
			
		||||
    shared_ptr<U> allocate_shared(const A& allocator, const T& value);</pre>
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A <code>shared_ptr</code> to an object of type 
 | 
			
		||||
        <code>T[N]</code>, where each array element of type <code>T</code> is 
 | 
			
		||||
        initialized to <code>value</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>boost::shared_ptr<int[8]> a1 = boost::make_shared<int[8]>(1);
 | 
			
		||||
boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>({1, 2});</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U> 
 | 
			
		||||
    shared_ptr<U> make_shared_noinit(size_t size);
 | 
			
		||||
template<class U, class A> 
 | 
			
		||||
    shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);</pre>
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized 
 | 
			
		||||
        object of type <code>T[size]</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<int[]>(size);
 | 
			
		||||
boost::shared_ptr<int[][2]> a2 = boost::make_shared_noinit<int[][2]>(size);</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U> 
 | 
			
		||||
    shared_ptr<U> make_shared_noinit();
 | 
			
		||||
template<class U, class A> 
 | 
			
		||||
    shared_ptr<U> allocate_shared_noinit(const A& allocator);</pre>
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized 
 | 
			
		||||
        object of type <code>T[N]</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> These overloads shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>boost::shared_ptr<int[8]> a1 = boost::make_shared_noinit<int[8]>();
 | 
			
		||||
boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]>();</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <h2><a name="history">History</a></h2>
 | 
			
		||||
    <p>February 2014. Glen Fernandes updated overloads of make_shared and 
 | 
			
		||||
      allocate_shared to conform to the specification in C++ standard paper 
 | 
			
		||||
      <a href="#N3870">N3870</a>, including resolving C++ standard library 
 | 
			
		||||
      defect report 2070, and reduced the spatial overhead of the internal
 | 
			
		||||
      bookkeeping structures.</p>
 | 
			
		||||
    <p>November 2012. Glen Fernandes contributed implementations of 
 | 
			
		||||
      make_shared and allocate_shared for arrays.</p>
 | 
			
		||||
    <h2><a name="references">References</a></h2>
 | 
			
		||||
    <p><a name="N3870">N3870</a>,
 | 
			
		||||
      <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
 | 
			
		||||
      Extending make_shared to Support Arrays, Revision 1</a>, Peter Dimov 
 | 
			
		||||
      & Glen Fernandes, January, 2014.</p>
 | 
			
		||||
    <hr>
 | 
			
		||||
    <p>$Date$</p>
 | 
			
		||||
    <p><small>Copyright 2012-2014 Glen Fernandes. 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>
 | 
			
		||||
							
								
								
									
										152
									
								
								make_unique.html
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								make_unique.html
									
									
									
									
									
								
							@@ -1,152 +0,0 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <title>make_unique</title>
 | 
			
		||||
    <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">make_unique</h1>
 | 
			
		||||
    <p><a href="#introduction">Introduction</a><br>
 | 
			
		||||
      <a href="#synopsis">Synopsis</a><br>
 | 
			
		||||
      <a href="#common">Common Requirements</a><br>
 | 
			
		||||
      <a href="#functions">Free Functions</a><br>
 | 
			
		||||
      <a href="#history">History</a></p>
 | 
			
		||||
    <h2><a name="introduction">Introduction</a></h2>
 | 
			
		||||
    <p>The header file <boost/make_unique.hpp> provides overloaded 
 | 
			
		||||
      function template <code>make_unique</code> for convenient creation of 
 | 
			
		||||
      <code>unique_ptr</code> objects.</p>
 | 
			
		||||
    <h2><a name="synopsis">Synopsis</a></h2>
 | 
			
		||||
    <pre>namespace boost {
 | 
			
		||||
    template<class U> // U is not array
 | 
			
		||||
    unique_ptr<U> <a href="#functions">make_unique</a>();
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
 | 
			
		||||
    template<class U, class... Args> // U is not array
 | 
			
		||||
    unique_ptr<U> <a href="#functions">make_unique</a>(Args&&... args);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is not array
 | 
			
		||||
    unique_ptr<U> <a href="#functions">make_unique</a>(U&& value);
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is T[]
 | 
			
		||||
    unique_ptr<U> <a href="#functions">make_unique</a>(size_t size);
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is not array
 | 
			
		||||
    unique_ptr<U> <a href="#functions">make_unique_noinit</a>();
 | 
			
		||||
 | 
			
		||||
    template<class U> // U is T[]
 | 
			
		||||
    unique_ptr<U> <a href="#functions">make_unique_noinit</a>(size_t size);
 | 
			
		||||
}</pre>
 | 
			
		||||
    <h2><a name="common">Common Requirements</a></h2>
 | 
			
		||||
    <pre>template<class U>
 | 
			
		||||
    unique_ptr<U> make_unique(<em>args</em>);
 | 
			
		||||
template<class U>
 | 
			
		||||
    unique_ptr<U> make_unique_noinit(<em>args</em>);</pre> 
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Effects:</b> Allocates memory for an object of type <code>U</code> 
 | 
			
		||||
        (or <code>T[size]</code> when <code>U</code> is <code>T[]</code>, 
 | 
			
		||||
        where <code>size</code> is determined from <code>args</code> as 
 | 
			
		||||
        specified by the concrete overload). The object is initialized from 
 | 
			
		||||
        <code>args</code> as specified by the concrete overload. If an 
 | 
			
		||||
        exception is thrown, the functions have no effect.</p>
 | 
			
		||||
      <p><b>Returns:</b> A <code>unique_ptr</code> instance that stores and 
 | 
			
		||||
        owns the address of the newly constructed object.</p>
 | 
			
		||||
      <p><b>Postconditions:</b> <code>r.get() != 0</code>, where 
 | 
			
		||||
        <code>r</code> is the return value.</p>
 | 
			
		||||
      <p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from 
 | 
			
		||||
        the initialization of the object.</p>
 | 
			
		||||
      <p><b>Remarks:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <p>When an object of a non-array type <code>T</code> is specified to 
 | 
			
		||||
          be initialized to a value <code>value</code>, or to 
 | 
			
		||||
          <code>T(list...)</code>, where <code>list...</code> is a list of 
 | 
			
		||||
          constructor arguments, <code>make_unique</code> shall perform this 
 | 
			
		||||
          initialization via the expression <code>new T(value)</code> or 
 | 
			
		||||
          <code>new T(list...)</code> respectively.</p>
 | 
			
		||||
        <p>When an object of type <code>T</code> is specified to be 
 | 
			
		||||
          value-initialized, <code>make_unique</code> shall perform this 
 | 
			
		||||
          initialization via the expression <code>new T()</code>.</p>
 | 
			
		||||
        <p>When an object of type <code>T</code> is specified to be 
 | 
			
		||||
          default-initialized, <code>make_unique_noinit</code> shall perform 
 | 
			
		||||
          this initialization via the expression <code>new T</code>.</p>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
    <pre>template<class U, class... Args>
 | 
			
		||||
unique_ptr<U> make_unique(Args&&... args);</pre> 
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A unique_ptr to an object of type <code>U</code>, 
 | 
			
		||||
        initialized to <code>U(forward<Args>(args)...)</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> This overload shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is not an array type.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>unique_ptr<float> p1 = boost::make_unique<float>();
 | 
			
		||||
unique_ptr<point> p2 = boost::make_unique<point>(x, y);</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U>
 | 
			
		||||
unique_ptr<U> make_unique(U&& value);</pre> 
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A unique_ptr to an object of type <code>U</code>, 
 | 
			
		||||
        initialized to <code>move(value)</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> This overload shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is not an array type.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>unique_ptr<string> p1 = boost::make_unique<string>({'a', 'b'});
 | 
			
		||||
unique_ptr<point> p2 = boost::make_unique<point>({-10, 25});</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U>
 | 
			
		||||
unique_ptr<U> make_unique(size_t size);</pre> 
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A unique_ptr to a value-initialized object of type 
 | 
			
		||||
        <code>T[size]</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> This overload shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>unique_ptr<double[]> p1 = boost::make_unique<double[]>(4);
 | 
			
		||||
unique_ptr<int[][2]> p2 = boost::make_unique<int[][2]>(2);</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U>
 | 
			
		||||
unique_ptr<U> make_unique_noinit();</pre> 
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A unique_ptr to a default-initialized object of 
 | 
			
		||||
        type <code>U</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> This overload shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is not an array type.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>unique_ptr<float> p1 = boost::make_unique_noinit<float>();
 | 
			
		||||
unique_ptr<point> p2 = boost::make_unique_noinit<point>();</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <pre>template<class U>
 | 
			
		||||
unique_ptr<U> make_unique_noinit(size_t size);</pre> 
 | 
			
		||||
    <blockquote>
 | 
			
		||||
      <p><b>Returns:</b> A unique_ptr to a default-initialized object of 
 | 
			
		||||
        type <code>T[size]</code>.</p>
 | 
			
		||||
      <p><b>Remarks:</b> This overload shall only participate in overload 
 | 
			
		||||
        resolution when <code>U</code> is of the form <code>T[]</code>.</p>
 | 
			
		||||
      <p><b>Examples:</b></p>
 | 
			
		||||
      <blockquote>
 | 
			
		||||
        <pre>unique_ptr<double[]> p1 = boost::make_unique_noinit<double[]>(4);
 | 
			
		||||
unique_ptr<int[][2]> p2 = boost::make_unique_noinit<int[][2]>(2);</pre>
 | 
			
		||||
      </blockquote>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <h2><a name="history">History</a></h2>
 | 
			
		||||
    <p>January 2014. Glen Fernandes contributed implementations of 
 | 
			
		||||
      make_unique for objects and arrays.</p>
 | 
			
		||||
    <hr>
 | 
			
		||||
    <p>$Date$</p>
 | 
			
		||||
    <p><small>Copyright 2012-2014 Glen Fernandes. 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>
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
    "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>"
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,34 +1,33 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>pointer_cast</title>
 | 
			
		||||
        <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">pointer_cast</h1>
 | 
			
		||||
        <p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
 | 
			
		||||
            <code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>) 
 | 
			
		||||
            provide a way to write generic pointer castings for raw pointers. The functions 
 | 
			
		||||
            are defined in <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A>.</CITE></p>
 | 
			
		||||
        <P>There is test/example code in <CITE><A href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</A></CITE>.</p>
 | 
			
		||||
            <h2><a name="rationale">Rationale</a></h2>
 | 
			
		||||
        <P>Boost smart pointers usually overload those functions to provide a mechanism to 
 | 
			
		||||
            emulate pointers casts. For example, <code>boost::shared_ptr<...></code> implements 
 | 
			
		||||
            a static pointer cast this way:</P>
 | 
			
		||||
        <pre>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>pointer_cast.hpp</title>
 | 
			
		||||
	</head>
 | 
			
		||||
	<body>
 | 
			
		||||
		<h1><IMG height="86" alt="C++ Boost" src="../../boost.png" width="277" align="middle" border="0">Pointer 
 | 
			
		||||
			cast functions</h1>
 | 
			
		||||
		<p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
 | 
			
		||||
			<code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>) 
 | 
			
		||||
			provide a way to write generic pointer castings for raw pointers. The functions 
 | 
			
		||||
			are defined in <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A>.</CITE></p>
 | 
			
		||||
		<P>There is test/example code in <CITE><A href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</A></CITE>.</p>
 | 
			
		||||
			<h2><a name="rationale">Rationale</a></h2>
 | 
			
		||||
		<P>Boost smart pointers usually overload those functions to provide a mechanism to 
 | 
			
		||||
			emulate pointers casts. For example, <code>boost::shared_ptr<...></code> implements 
 | 
			
		||||
			a static pointer cast this way:</P>
 | 
			
		||||
		<pre>
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
    shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r);
 | 
			
		||||
</pre>
 | 
			
		||||
        <P>Pointer cast functions from <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE>
 | 
			
		||||
            are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>,
 | 
			
		||||
            <code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code>
 | 
			
		||||
            for raw pointers. This way when developing pointer type independent classes, 
 | 
			
		||||
            for example, memory managers or shared memory compatible classes, the same code 
 | 
			
		||||
            can be used for raw and smart pointers.</p>
 | 
			
		||||
            <H2><A name="synopsis">Synopsis</A></H2>
 | 
			
		||||
            <BLOCKQUOTE>
 | 
			
		||||
                <PRE>
 | 
			
		||||
		<P>Pointer cast functions from <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE>
 | 
			
		||||
			are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>,
 | 
			
		||||
			<code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code>
 | 
			
		||||
			for raw pointers. This way when developing pointer type independent classes, 
 | 
			
		||||
			for example, memory managers or shared memory compatible classes, the same code 
 | 
			
		||||
			can be used for raw and smart pointers.</p>
 | 
			
		||||
			<H2><A name="synopsis">Synopsis</A></H2>
 | 
			
		||||
			<BLOCKQUOTE>
 | 
			
		||||
				<PRE>
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
@@ -49,12 +48,12 @@ inline T* reinterpret_pointer_cast(U *ptr)
 | 
			
		||||
  
 | 
			
		||||
} // namespace boost
 | 
			
		||||
</PRE>
 | 
			
		||||
            </BLOCKQUOTE>
 | 
			
		||||
        <P>As you can see from the above synopsis, the pointer cast functions are just 
 | 
			
		||||
            wrappers around standard C++ cast operators.</P>
 | 
			
		||||
        <H2><A name="example">Example</A></H2>
 | 
			
		||||
        <BLOCKQUOTE>
 | 
			
		||||
            <PRE>
 | 
			
		||||
			</BLOCKQUOTE>
 | 
			
		||||
		<P>As you can see from the above synopsis, the pointer cast functions are just 
 | 
			
		||||
			wrappers around standard C++ cast operators.</P>
 | 
			
		||||
		<H2><A name="example">Example</A></H2>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<PRE>
 | 
			
		||||
#include <boost/pointer_cast.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -94,13 +93,13 @@ int main()
 | 
			
		||||
   delete ptr;
 | 
			
		||||
   return 0;
 | 
			
		||||
}</PRE>
 | 
			
		||||
        </BLOCKQUOTE>
 | 
			
		||||
        <P>The example demonstrates how the generic pointer casts help us create pointer 
 | 
			
		||||
            independent code.</P>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to 
 | 
			
		||||
            the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt">
 | 
			
		||||
            LICENSE_1_0.txt</A> or a copy at <<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>>.)</p>
 | 
			
		||||
    </body>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<P>The example demonstrates how the generic pointer casts help us create pointer 
 | 
			
		||||
			independent code.</P>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>Revised: $Date$</p>
 | 
			
		||||
		<p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to 
 | 
			
		||||
			the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt">
 | 
			
		||||
				LICENSE_1_0.txt</A> or a copy at <<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>>.)</p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +1,33 @@
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>pointer_to_other</title>
 | 
			
		||||
        <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">pointer_to_other</h1>
 | 
			
		||||
        <p>
 | 
			
		||||
            The pointer to other utility provides a way, given a source pointer type, 
 | 
			
		||||
            to obtain a pointer of the same type to another pointee type. The utility is 
 | 
			
		||||
            defined in <cite><a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a>.</cite></p>
 | 
			
		||||
        <p>There is test/example code in <cite><a href="test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a></cite>.</p>
 | 
			
		||||
        <h2><a name="contents">Contents</a></h2>
 | 
			
		||||
        <ul>
 | 
			
		||||
            <li>
 | 
			
		||||
                <a href="#rationale">Rationale</a>
 | 
			
		||||
            <li>
 | 
			
		||||
                <a href="#synopsis">Synopsis</a>
 | 
			
		||||
            <li>
 | 
			
		||||
                <a href="#example">Example</a></li>
 | 
			
		||||
        </ul>
 | 
			
		||||
        <h2><a name="rationale">Rationale</a></h2>
 | 
			
		||||
        <p>When building pointer independent classes, like memory managers, allocators, or 
 | 
			
		||||
            containers, there is often a need to define pointers generically, so that if a 
 | 
			
		||||
            template parameter represents a pointer (for example, a raw or smart pointer to 
 | 
			
		||||
            an int), we can define another pointer of the same type to another pointee (a 
 | 
			
		||||
            raw or smart pointer to a float.)</p>
 | 
			
		||||
        <pre>template <class IntPtr>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>pointer_to_other.hpp</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="#ffffff" text="#000000">
 | 
			
		||||
		<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Header
 | 
			
		||||
			<a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a></h1>
 | 
			
		||||
		<p>
 | 
			
		||||
			The pointer to other utility provides a way, given a source pointer type, 
 | 
			
		||||
			to obtain a pointer of the same type to another pointee type. The utility is 
 | 
			
		||||
			defined in <cite><a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a>.</cite></p>
 | 
			
		||||
		<p>There is test/example code in <cite><a href="test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a></cite>.</p>
 | 
			
		||||
		<h2><a name="contents">Contents</a></h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				<a href="#rationale">Rationale</a>
 | 
			
		||||
			<li>
 | 
			
		||||
				<a href="#synopsis">Synopsis</a>
 | 
			
		||||
			<li>
 | 
			
		||||
				<a href="#example">Example</a></li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<h2><a name="rationale">Rationale</a></h2>
 | 
			
		||||
		<p>When building pointer independent classes, like memory managers, allocators, or 
 | 
			
		||||
			containers, there is often a need to define pointers generically, so that if a 
 | 
			
		||||
			template parameter represents a pointer (for example, a raw or smart pointer to 
 | 
			
		||||
			an int), we can define another pointer of the same type to another pointee (a 
 | 
			
		||||
			raw or smart pointer to a float.)</p>
 | 
			
		||||
		<pre>template <class IntPtr>
 | 
			
		||||
class FloatPointerHolder
 | 
			
		||||
{   
 | 
			
		||||
   <em>// Let's define a pointer to a float</em>
 | 
			
		||||
@@ -35,8 +35,8 @@ class FloatPointerHolder
 | 
			
		||||
      <IntPtr, float>::type float_ptr_t;
 | 
			
		||||
   float_ptr_t float_ptr;
 | 
			
		||||
};</pre>
 | 
			
		||||
        <h2><a name="synopsis">Synopsis</a></h2>
 | 
			
		||||
        <pre>
 | 
			
		||||
		<h2><a name="synopsis">Synopsis</a></h2>
 | 
			
		||||
		<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
template<class T, class U>
 | 
			
		||||
@@ -69,10 +69,10 @@ struct pointer_to_other< T*, U >
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} <em>// namespace boost</em></pre>
 | 
			
		||||
        <p>If these definitions are not correct for a specific smart pointer, we can define 
 | 
			
		||||
            a specialization of pointer_to_other.</p>
 | 
			
		||||
        <h2><a name="example">Example</a></h2>
 | 
			
		||||
        <pre><em>// Let's define a memory allocator that can
 | 
			
		||||
		<p>If these definitions are not correct for a specific smart pointer, we can define 
 | 
			
		||||
			a specialization of pointer_to_other.</p>
 | 
			
		||||
		<h2><a name="example">Example</a></h2>
 | 
			
		||||
		<pre><em>// Let's define a memory allocator that can
 | 
			
		||||
// work with raw and smart pointers</em>
 | 
			
		||||
 | 
			
		||||
#include <boost/pointer_to_other.hpp>
 | 
			
		||||
@@ -97,12 +97,12 @@ class memory_allocator
 | 
			
		||||
 | 
			
		||||
   block_ptr_t free_blocks;
 | 
			
		||||
};</pre>
 | 
			
		||||
        <p>As we can see, using pointer_to_other we can create pointer independent code.</p>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification, 
 | 
			
		||||
            and distribution are subject to the Boost Software License, Version 1.0.<br>
 | 
			
		||||
            (See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a 
 | 
			
		||||
            copy at < <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</small></p>
 | 
			
		||||
    </body>
 | 
			
		||||
		<p>As we can see, using pointer_to_other we can create pointer independent code.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>Last revised: $Date$</p>
 | 
			
		||||
		<p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification, 
 | 
			
		||||
				and distribution are subject to the Boost Software License, Version 1.0.<br>
 | 
			
		||||
				(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a 
 | 
			
		||||
				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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										183
									
								
								scoped_array.htm
									
									
									
									
									
								
							
							
						
						
									
										183
									
								
								scoped_array.htm
									
									
									
									
									
								
							@@ -1,38 +1,38 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>scoped_array</title>
 | 
			
		||||
        <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">scoped_array class template</h1>
 | 
			
		||||
        <p>The <b>scoped_array</b> class template stores a pointer to a dynamically 
 | 
			
		||||
            allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
 | 
			
		||||
            expression.) The array pointed to is guaranteed to be deleted, either on 
 | 
			
		||||
            destruction of the <b>scoped_array</b>, or via an explicit <b>reset</b>.</p>
 | 
			
		||||
        <p>The <b>scoped_array</b> template is a simple solution for simple needs. It 
 | 
			
		||||
            supplies a basic "resource acquisition is initialization" facility, without 
 | 
			
		||||
            shared-ownership or transfer-of-ownership semantics. Both its name and 
 | 
			
		||||
            enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
 | 
			
		||||
            noncopyable</a>) signal its intent to retain ownership solely within the 
 | 
			
		||||
            current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>, 
 | 
			
		||||
            it is safer than <b>shared_array</b> for pointers which should not be copied.</p>
 | 
			
		||||
        <p>Because <b>scoped_array</b> is so simple, in its usual implementation every 
 | 
			
		||||
            operation is as fast as a built-in array pointer and it has no more space 
 | 
			
		||||
            overhead that a built-in array pointer.</p>
 | 
			
		||||
        <p>It cannot be used in C++ standard library containers. See <a href="shared_array.htm">
 | 
			
		||||
            <b>shared_array</b></a> if <b>scoped_array</b> does not meet your needs.</p>
 | 
			
		||||
        <p>It cannot correctly hold a pointer to a single object. See <a href="scoped_ptr.htm"><b>scoped_ptr</b></a>
 | 
			
		||||
            for that usage.</p>
 | 
			
		||||
        <p>A <b>std::vector</b> is an alternative to a <b>scoped_array</b> that is a bit 
 | 
			
		||||
            heavier duty but far more flexible. A <b>boost::array</b> is an alternative 
 | 
			
		||||
            that does not use dynamic allocation.</p>
 | 
			
		||||
        <p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
            to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
            common requirements</a>.</p>
 | 
			
		||||
        <h2>Synopsis</h2>
 | 
			
		||||
        <pre>namespace boost {
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>scoped_array</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="#ffffff" text="#000000">
 | 
			
		||||
		<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
 | 
			
		||||
					border="0"></A>scoped_array class template</h1>
 | 
			
		||||
		<p>The <b>scoped_array</b> class template stores a pointer to a dynamically 
 | 
			
		||||
			allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
 | 
			
		||||
			expression.) The array pointed to is guaranteed to be deleted, either on 
 | 
			
		||||
			destruction of the <b>scoped_array</b>, or via an explicit <b>reset</b>.</p>
 | 
			
		||||
		<p>The <b>scoped_array</b> template is a simple solution for simple needs. It 
 | 
			
		||||
			supplies a basic "resource acquisition is initialization" facility, without 
 | 
			
		||||
			shared-ownership or transfer-of-ownership semantics. Both its name and 
 | 
			
		||||
			enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
 | 
			
		||||
				noncopyable</a>) signal its intent to retain ownership solely within the 
 | 
			
		||||
			current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>, 
 | 
			
		||||
			it is safer than <b>shared_array</b> for pointers which should not be copied.</p>
 | 
			
		||||
		<p>Because <b>scoped_array</b> is so simple, in its usual implementation every 
 | 
			
		||||
			operation is as fast as a built-in array pointer and it has no more space 
 | 
			
		||||
			overhead that a built-in array pointer.</p>
 | 
			
		||||
		<p>It cannot be used in C++ standard library containers. See <a href="shared_array.htm">
 | 
			
		||||
				<b>shared_array</b></a> if <b>scoped_array</b> does not meet your needs.</p>
 | 
			
		||||
		<p>It cannot correctly hold a pointer to a single object. See <a href="scoped_ptr.htm"><b>scoped_ptr</b></a>
 | 
			
		||||
			for that usage.</p>
 | 
			
		||||
		<p>A <b>std::vector</b> is an alternative to a <b>scoped_array</b> that is a bit 
 | 
			
		||||
			heavier duty but far more flexible. A <b>boost::array</b> is an alternative 
 | 
			
		||||
			that does not use dynamic allocation.</p>
 | 
			
		||||
		<p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
			to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
				common requirements</a>.</p>
 | 
			
		||||
		<h2>Synopsis</h2>
 | 
			
		||||
		<pre>namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class scoped_array : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> {
 | 
			
		||||
 | 
			
		||||
@@ -55,61 +55,62 @@
 | 
			
		||||
  template<class T> void <a href="#free-swap">swap</a>(scoped_array<T> & a, scoped_array<T> & b); // never throws
 | 
			
		||||
 | 
			
		||||
}</pre>
 | 
			
		||||
        <h2>Members</h2>
 | 
			
		||||
        <h3>
 | 
			
		||||
            <a name="element_type">element_type</a></h3>
 | 
			
		||||
        <pre>typedef T element_type;</pre>
 | 
			
		||||
        <p>Provides the type of the stored pointer.</p>
 | 
			
		||||
        <h3><a name="ctor">constructors</a></h3>
 | 
			
		||||
        <pre>explicit scoped_array(T * p = 0); // never throws</pre>
 | 
			
		||||
        <p>Constructs a <b>scoped_array</b>, storing a copy of <b>p</b>, which must have 
 | 
			
		||||
            been allocated via a C++ <b>new</b>[] expression or be 0. <b>T</b> is not 
 | 
			
		||||
            required be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
            common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
        <pre>~scoped_array(); // never throws</pre>
 | 
			
		||||
        <p>Deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on 
 | 
			
		||||
            a pointer with a value of 0 is harmless. The guarantee that this does not throw 
 | 
			
		||||
            exceptions depends on the requirement that the deleted array's objects' 
 | 
			
		||||
            destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
            common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="reset">reset</a></h3>
 | 
			
		||||
        <pre>void reset(T * p = 0); // never throws</pre>
 | 
			
		||||
        <p>
 | 
			
		||||
            Deletes the array pointed to by the stored pointer and then stores a copy of p, 
 | 
			
		||||
            which must have been allocated via a C++ <b>new[]</b> expression or be 0. The 
 | 
			
		||||
            guarantee that this does not throw exceptions depends on the requirement that 
 | 
			
		||||
            the deleted array's objects' destructors do not throw exceptions. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="operator[]">subscripting</a></h3>
 | 
			
		||||
        <pre>T & operator[](std::ptrdiff_t i) const; // never throws</pre>
 | 
			
		||||
        <p>Returns a reference to element <b>i</b> of the array pointed to by the stored 
 | 
			
		||||
            pointer. Behavior is undefined and almost certainly undesirable if the stored 
 | 
			
		||||
            pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the 
 | 
			
		||||
            number of elements in the array.</p>
 | 
			
		||||
        <h3><a name="get">get</a></h3>
 | 
			
		||||
        <pre>T * get() const; // never throws</pre>
 | 
			
		||||
        <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
        <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
        <p>Returns an unspecified value that, when used in boolean contexts, is equivalent 
 | 
			
		||||
            to <code>get() != 0</code>.</p>
 | 
			
		||||
        <h3><a name="swap">swap</a></h3>
 | 
			
		||||
        <pre>void swap(scoped_array & b); // never throws</pre>
 | 
			
		||||
        <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
            complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
            requirements</a>.</p>
 | 
			
		||||
        <h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
        <h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
        <pre>template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b); // never throws</pre>
 | 
			
		||||
        <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. 
 | 
			
		||||
            Provided as an aid to generic programming.</p>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
            Copyright 2002-2005 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>
 | 
			
		||||
		<h2>Members</h2>
 | 
			
		||||
		<h3>
 | 
			
		||||
			<a name="element_type">element_type</a></h3>
 | 
			
		||||
		<pre>typedef T element_type;</pre>
 | 
			
		||||
		<p>Provides the type of the stored pointer.</p>
 | 
			
		||||
		<h3><a name="ctor">constructors</a></h3>
 | 
			
		||||
		<pre>explicit scoped_array(T * p = 0); // never throws</pre>
 | 
			
		||||
		<p>Constructs a <b>scoped_array</b>, storing a copy of <b>p</b>, which must have 
 | 
			
		||||
			been allocated via a C++ <b>new</b>[] expression or be 0. <b>T</b> is not 
 | 
			
		||||
			required be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
				common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
		<pre>~scoped_array(); // never throws</pre>
 | 
			
		||||
		<p>Deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on 
 | 
			
		||||
			a pointer with a value of 0 is harmless. The guarantee that this does not throw 
 | 
			
		||||
			exceptions depends on the requirement that the deleted array's objects' 
 | 
			
		||||
			destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
				common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="reset">reset</a></h3>
 | 
			
		||||
		<pre>void reset(T * p = 0); // never throws</pre>
 | 
			
		||||
		<p>
 | 
			
		||||
			Deletes the array pointed to by the stored pointer and then stores a copy of p, 
 | 
			
		||||
			which must have been allocated via a C++ <b>new[]</b> expression or be 0. The 
 | 
			
		||||
			guarantee that this does not throw exceptions depends on the requirement that 
 | 
			
		||||
			the deleted array's objects' destructors do not throw exceptions. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="operator[]">subscripting</a></h3>
 | 
			
		||||
		<pre>T & operator[](std::ptrdiff_t i) const; // never throws</pre>
 | 
			
		||||
		<p>Returns a reference to element <b>i</b> of the array pointed to by the stored 
 | 
			
		||||
			pointer. Behavior is undefined and almost certainly undesirable if the stored 
 | 
			
		||||
			pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the 
 | 
			
		||||
			number of elements in the array.</p>
 | 
			
		||||
		<h3><a name="get">get</a></h3>
 | 
			
		||||
		<pre>T * get() const; // never throws</pre>
 | 
			
		||||
		<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
		<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
		<p>Returns an unspecified value that, when used in boolean contexts, is equivalent 
 | 
			
		||||
			to <code>get() != 0</code>.</p>
 | 
			
		||||
		<h3><a name="swap">swap</a></h3>
 | 
			
		||||
		<pre>void swap(scoped_array & b); // never throws</pre>
 | 
			
		||||
		<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
			complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
				requirements</a>.</p>
 | 
			
		||||
		<h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
		<h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
		<pre>template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b); // never throws</pre>
 | 
			
		||||
		<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. 
 | 
			
		||||
			Provided as an aid to generic programming.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan--> 
 | 
			
		||||
			09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										271
									
								
								scoped_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										271
									
								
								scoped_ptr.htm
									
									
									
									
									
								
							@@ -1,38 +1,38 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>scoped_ptr</title>
 | 
			
		||||
        <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">scoped_ptr class template</h1>
 | 
			
		||||
        <p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated 
 | 
			
		||||
            object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.) 
 | 
			
		||||
            The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>, 
 | 
			
		||||
            or via an explicit <b>reset</b>. See the <a href="#example">example</a>.</p>
 | 
			
		||||
        <p>The <b>scoped_ptr</b> template is a simple solution for simple needs. It 
 | 
			
		||||
            supplies a basic "resource acquisition is initialization" facility, without 
 | 
			
		||||
            shared-ownership or transfer-of-ownership semantics. Both its name and 
 | 
			
		||||
            enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
 | 
			
		||||
            noncopyable</a>) signal its intent to retain ownership solely within the 
 | 
			
		||||
            current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>, 
 | 
			
		||||
            it is safer than <b>shared_ptr</b> or <b>std::auto_ptr</b> for pointers which 
 | 
			
		||||
            should not be copied.</p>
 | 
			
		||||
        <p>Because <b>scoped_ptr</b> is simple, in its usual implementation every operation 
 | 
			
		||||
            is as fast as for a built-in pointer and it has no more space overhead that a 
 | 
			
		||||
            built-in pointer.</p>
 | 
			
		||||
        <p><STRONG>scoped_ptr</STRONG> cannot be used in C++ Standard Library containers. 
 | 
			
		||||
            Use <a href="shared_ptr.htm"><b>shared_ptr</b></a> if you need a smart pointer 
 | 
			
		||||
            that can.</p>
 | 
			
		||||
        <p><STRONG>scoped_ptr</STRONG> cannot correctly hold a pointer to a dynamically 
 | 
			
		||||
            allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for 
 | 
			
		||||
            that usage.</p>
 | 
			
		||||
        <p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
            to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
            common requirements</a>.</p>
 | 
			
		||||
        <h2>Synopsis</h2>
 | 
			
		||||
        <pre>namespace boost {
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>scoped_ptr</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="#ffffff" text="#000000">
 | 
			
		||||
		<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
 | 
			
		||||
					border="0"></A>scoped_ptr class template</h1>
 | 
			
		||||
		<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated 
 | 
			
		||||
			object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.) 
 | 
			
		||||
			The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>, 
 | 
			
		||||
			or via an explicit <b>reset</b>. See the <a href="#example">example</a>.</p>
 | 
			
		||||
		<p>The <b>scoped_ptr</b> template is a simple solution for simple needs. It 
 | 
			
		||||
			supplies a basic "resource acquisition is initialization" facility, without 
 | 
			
		||||
			shared-ownership or transfer-of-ownership semantics. Both its name and 
 | 
			
		||||
			enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
 | 
			
		||||
				noncopyable</a>) signal its intent to retain ownership solely within the 
 | 
			
		||||
			current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>, 
 | 
			
		||||
			it is safer than <b>shared_ptr</b> or <b>std::auto_ptr</b> for pointers which 
 | 
			
		||||
			should not be copied.</p>
 | 
			
		||||
		<p>Because <b>scoped_ptr</b> is simple, in its usual implementation every operation 
 | 
			
		||||
			is as fast as for a built-in pointer and it has no more space overhead that a 
 | 
			
		||||
			built-in pointer.</p>
 | 
			
		||||
		<p><STRONG>scoped_ptr</STRONG> cannot be used in C++ Standard Library containers. 
 | 
			
		||||
			Use <a href="shared_ptr.htm"><b>shared_ptr</b></a> if you need a smart pointer 
 | 
			
		||||
			that can.</p>
 | 
			
		||||
		<p><STRONG>scoped_ptr</STRONG> cannot correctly hold a pointer to a dynamically 
 | 
			
		||||
			allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for 
 | 
			
		||||
			that usage.</p>
 | 
			
		||||
		<p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
			to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
				common requirements</a>.</p>
 | 
			
		||||
		<h2>Synopsis</h2>
 | 
			
		||||
		<pre>namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class scoped_ptr : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> {
 | 
			
		||||
 | 
			
		||||
@@ -56,60 +56,60 @@
 | 
			
		||||
  template<class T> void <a href="#free-swap">swap</a>(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws
 | 
			
		||||
 | 
			
		||||
}</pre>
 | 
			
		||||
        <h2>Members</h2>
 | 
			
		||||
        <h3><a name="element_type">element_type</a></h3>
 | 
			
		||||
        <pre>typedef T element_type;</pre>
 | 
			
		||||
        <p>Provides the type of the stored pointer.</p>
 | 
			
		||||
        <h3><a name="constructors">constructors</a></h3>
 | 
			
		||||
        <pre>explicit scoped_ptr(T * p = 0); // never throws</pre>
 | 
			
		||||
        <p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been 
 | 
			
		||||
            allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be 
 | 
			
		||||
            a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
            requirements</a>.</p>
 | 
			
		||||
        <h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
        <pre>~scoped_ptr(); // never throws</pre>
 | 
			
		||||
        <p>Destroys the object pointed to by the stored pointer, if any, as if by using <tt>delete 
 | 
			
		||||
            this->get()</tt>.</p>
 | 
			
		||||
        <P>
 | 
			
		||||
            The guarantee that this does not throw exceptions depends on the requirement 
 | 
			
		||||
            that the deleted object's destructor does not throw exceptions. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</P>
 | 
			
		||||
        <h3><a name="reset">reset</a></h3>
 | 
			
		||||
        <pre>void reset(T * p = 0); // never throws</pre>
 | 
			
		||||
        <p>
 | 
			
		||||
            Deletes the object pointed to by the stored pointer and then stores a copy of 
 | 
			
		||||
            p, which must have been allocated via a C++ <b>new</b> expression or be 0. The 
 | 
			
		||||
            guarantee that this does not throw exceptions depends on the requirement that 
 | 
			
		||||
            the deleted object's destructor does not throw exceptions. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="indirection">indirection</a></h3>
 | 
			
		||||
        <pre>T & operator*() const; // never throws</pre>
 | 
			
		||||
        <p>Returns a reference to the object pointed to by the stored pointer. Behavior is 
 | 
			
		||||
            undefined if the stored pointer is 0.</p>
 | 
			
		||||
        <pre>T * operator->() const; // never throws</pre>
 | 
			
		||||
        <p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p>
 | 
			
		||||
        <h3><a name="get">get</a></h3>
 | 
			
		||||
        <pre>T * get() const; // never throws</pre>
 | 
			
		||||
        <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
        <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
        <p>Returns an unspecified value that, when used in boolean contexts, is equivalent 
 | 
			
		||||
            to <code>get() != 0</code>.</p>
 | 
			
		||||
        <h3><a name="swap">swap</a></h3>
 | 
			
		||||
        <pre>void swap(scoped_ptr & b); // never throws</pre>
 | 
			
		||||
        <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
            complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
            requirements</a>.</p>
 | 
			
		||||
        <h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
        <h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
        <pre>template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws</pre>
 | 
			
		||||
        <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. 
 | 
			
		||||
            Provided as an aid to generic programming.</p>
 | 
			
		||||
        <h2><a name="example">Example</a></h2>
 | 
			
		||||
        <p>Here's an example that uses <b>scoped_ptr</b>.</p>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <pre>#include <boost/scoped_ptr.hpp>
 | 
			
		||||
		<h2>Members</h2>
 | 
			
		||||
		<h3><a name="element_type">element_type</a></h3>
 | 
			
		||||
		<pre>typedef T element_type;</pre>
 | 
			
		||||
		<p>Provides the type of the stored pointer.</p>
 | 
			
		||||
		<h3><a name="constructors">constructors</a></h3>
 | 
			
		||||
		<pre>explicit scoped_ptr(T * p = 0); // never throws</pre>
 | 
			
		||||
		<p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been 
 | 
			
		||||
			allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be 
 | 
			
		||||
			a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
				requirements</a>.</p>
 | 
			
		||||
		<h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
		<pre>~scoped_ptr(); // never throws</pre>
 | 
			
		||||
		<p>Destroys the object pointed to by the stored pointer, if any, as if by using <tt>delete 
 | 
			
		||||
				this->get()</tt>.</p>
 | 
			
		||||
		<P>
 | 
			
		||||
			The guarantee that this does not throw exceptions depends on the requirement 
 | 
			
		||||
			that the deleted object's destructor does not throw exceptions. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</P>
 | 
			
		||||
		<h3><a name="reset">reset</a></h3>
 | 
			
		||||
		<pre>void reset(T * p = 0); // never throws</pre>
 | 
			
		||||
		<p>
 | 
			
		||||
			Deletes the object pointed to by the stored pointer and then stores a copy of 
 | 
			
		||||
			p, which must have been allocated via a C++ <b>new</b> expression or be 0. The 
 | 
			
		||||
			guarantee that this does not throw exceptions depends on the requirement that 
 | 
			
		||||
			the deleted object's destructor does not throw exceptions. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="indirection">indirection</a></h3>
 | 
			
		||||
		<pre>T & operator*() const; // never throws</pre>
 | 
			
		||||
		<p>Returns a reference to the object pointed to by the stored pointer. Behavior is 
 | 
			
		||||
			undefined if the stored pointer is 0.</p>
 | 
			
		||||
		<pre>T * operator->() const; // never throws</pre>
 | 
			
		||||
		<p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p>
 | 
			
		||||
		<h3><a name="get">get</a></h3>
 | 
			
		||||
		<pre>T * get() const; // never throws</pre>
 | 
			
		||||
		<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
		<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
		<p>Returns an unspecified value that, when used in boolean contexts, is equivalent 
 | 
			
		||||
			to <code>get() != 0</code>.</p>
 | 
			
		||||
		<h3><a name="swap">swap</a></h3>
 | 
			
		||||
		<pre>void swap(scoped_ptr & b); // never throws</pre>
 | 
			
		||||
		<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
			complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
				requirements</a>.</p>
 | 
			
		||||
		<h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
		<h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
		<pre>template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b); // never throws</pre>
 | 
			
		||||
		<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. 
 | 
			
		||||
			Provided as an aid to generic programming.</p>
 | 
			
		||||
		<h2><a name="example">Example</a></h2>
 | 
			
		||||
		<p>Here's an example that uses <b>scoped_ptr</b>.</p>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<pre>#include <boost/scoped_ptr.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } };
 | 
			
		||||
@@ -128,53 +128,54 @@ int main()
 | 
			
		||||
    std::cout << my_instance.add_one() << '\n';
 | 
			
		||||
    std::cout << my_instance.add_one() << '\n';
 | 
			
		||||
}</pre>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <p>The example program produces the beginning of a child's nursery rhyme:</p>
 | 
			
		||||
        <blockquote>
 | 
			
		||||
            <pre>1
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<p>The example program produces the beginning of a child's nursery rhyme:</p>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<pre>1
 | 
			
		||||
2
 | 
			
		||||
Buckle my shoe</pre>
 | 
			
		||||
        </blockquote>
 | 
			
		||||
        <h2>Rationale</h2>
 | 
			
		||||
        <p>The primary reason to use <b>scoped_ptr</b> rather than <b>auto_ptr</b> is to 
 | 
			
		||||
            let readers of your code know that you intend "resource acquisition is 
 | 
			
		||||
            initialization" to be applied only for the current scope, and have no intent to 
 | 
			
		||||
            transfer ownership.</p>
 | 
			
		||||
        <p>A secondary reason to use <b>scoped_ptr</b> is to prevent a later maintenance 
 | 
			
		||||
            programmer from adding a function that transfers ownership by returning the <b>auto_ptr</b>, 
 | 
			
		||||
            because the maintenance programmer saw <b>auto_ptr</b>, and assumed ownership 
 | 
			
		||||
            could safely be transferred.</p>
 | 
			
		||||
        <p>Think of <b>bool</b> vs <b>int</b>. We all know that under the covers <b>bool</b>
 | 
			
		||||
            is usually just an <b>int</b>. Indeed, some argued against including <b>bool</b>
 | 
			
		||||
            in the C++ standard because of that. But by coding <b>bool</b> rather than <b>int</b>, 
 | 
			
		||||
            you tell your readers what your intent is. Same with <b>scoped_ptr</b>; by 
 | 
			
		||||
            using it you are signaling intent.</p>
 | 
			
		||||
        <p>It has been suggested that <b>scoped_ptr<T></b> is equivalent to <b>std::auto_ptr<T> 
 | 
			
		||||
            const</b>. Ed Brey pointed out, however, that <b>reset</b> will not work on 
 | 
			
		||||
            a <b>std::auto_ptr<T> const.</b></p>
 | 
			
		||||
        <h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
 | 
			
		||||
        <p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called 
 | 
			
		||||
            pimpl) idiom which avoids exposing the body (implementation) in the header 
 | 
			
		||||
            file.</p>
 | 
			
		||||
        <p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
 | 
			
		||||
            sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>, 
 | 
			
		||||
            which uses a <b>scoped_ptr<></b> to an incomplete type to hide the 
 | 
			
		||||
            implementation. The instantiation of member functions which require a complete 
 | 
			
		||||
            type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
 | 
			
		||||
            implementation file.</p>
 | 
			
		||||
        <h2>Frequently Asked Questions</h2>
 | 
			
		||||
        <p><b>Q</b>. Why doesn't <b>scoped_ptr</b> have a release() member?<br>
 | 
			
		||||
            <b>A</b>. When reading source code, it is valuable to be able to draw 
 | 
			
		||||
            conclusions about program behavior based on the types being used. If <STRONG>scoped_ptr</STRONG>
 | 
			
		||||
            had a release() member, it would become possible to transfer ownership of the 
 | 
			
		||||
            held pointer, weakening its role as a way of limiting resource lifetime to a 
 | 
			
		||||
            given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership 
 | 
			
		||||
            is required. (supplied by Dave Abrahams)</p>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date</p>
 | 
			
		||||
        <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
            Copyright 2002-2005 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>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h2>Rationale</h2>
 | 
			
		||||
		<p>The primary reason to use <b>scoped_ptr</b> rather than <b>auto_ptr</b> is to 
 | 
			
		||||
			let readers of your code know that you intend "resource acquisition is 
 | 
			
		||||
			initialization" to be applied only for the current scope, and have no intent to 
 | 
			
		||||
			transfer ownership.</p>
 | 
			
		||||
		<p>A secondary reason to use <b>scoped_ptr</b> is to prevent a later maintenance 
 | 
			
		||||
			programmer from adding a function that transfers ownership by returning the <b>auto_ptr</b>, 
 | 
			
		||||
			because the maintenance programmer saw <b>auto_ptr</b>, and assumed ownership 
 | 
			
		||||
			could safely be transferred.</p>
 | 
			
		||||
		<p>Think of <b>bool</b> vs <b>int</b>. We all know that under the covers <b>bool</b>
 | 
			
		||||
			is usually just an <b>int</b>. Indeed, some argued against including <b>bool</b>
 | 
			
		||||
			in the C++ standard because of that. But by coding <b>bool</b> rather than <b>int</b>, 
 | 
			
		||||
			you tell your readers what your intent is. Same with <b>scoped_ptr</b>; by 
 | 
			
		||||
			using it you are signaling intent.</p>
 | 
			
		||||
		<p>It has been suggested that <b>scoped_ptr<T></b> is equivalent to <b>std::auto_ptr<T> 
 | 
			
		||||
				const</b>. Ed Brey pointed out, however, that <b>reset</b> will not work on 
 | 
			
		||||
			a <b>std::auto_ptr<T> const.</b></p>
 | 
			
		||||
		<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
 | 
			
		||||
		<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called 
 | 
			
		||||
			pimpl) idiom which avoids exposing the body (implementation) in the header 
 | 
			
		||||
			file.</p>
 | 
			
		||||
		<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
 | 
			
		||||
			sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>, 
 | 
			
		||||
			which uses a <b>scoped_ptr<></b> to an incomplete type to hide the 
 | 
			
		||||
			implementation. The instantiation of member functions which require a complete 
 | 
			
		||||
			type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
 | 
			
		||||
			implementation file.</p>
 | 
			
		||||
		<h2>Frequently Asked Questions</h2>
 | 
			
		||||
		<p><b>Q</b>. Why doesn't <b>scoped_ptr</b> have a release() member?<br>
 | 
			
		||||
			<b>A</b>. When reading source code, it is valuable to be able to draw 
 | 
			
		||||
			conclusions about program behavior based on the types being used. If <STRONG>scoped_ptr</STRONG>
 | 
			
		||||
			had a release() member, it would become possible to transfer ownership of the 
 | 
			
		||||
			held pointer, weakening its role as a way of limiting resource lifetime to a 
 | 
			
		||||
			given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership 
 | 
			
		||||
			is required. (supplied by Dave Abrahams)</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan --> 
 | 
			
		||||
			09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										276
									
								
								shared_array.htm
									
									
									
									
									
								
							
							
						
						
									
										276
									
								
								shared_array.htm
									
									
									
									
									
								
							@@ -1,35 +1,35 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>shared_array</title>
 | 
			
		||||
        <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">shared_array class template</h1>
 | 
			
		||||
        <p>The <b>shared_array</b> class template stores a pointer to a dynamically 
 | 
			
		||||
            allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
 | 
			
		||||
            expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
 | 
			
		||||
            pointing to it is destroyed or reset.</p>
 | 
			
		||||
        <p>Every <b>shared_array</b> meets the <b>CopyConstructible</b> and <b>Assignable</b>
 | 
			
		||||
            requirements of the C++ Standard Library, and so can be used in standard 
 | 
			
		||||
            library containers. Comparison operators are supplied so that <b>shared_array</b>
 | 
			
		||||
            works with the standard library's associative containers.</p>
 | 
			
		||||
        <p>Normally, a <b>shared_array</b> cannot correctly hold a pointer to an object 
 | 
			
		||||
            that has been allocated with the non-array form of <STRONG>new</STRONG>. See <a href="shared_ptr.htm">
 | 
			
		||||
            <b>shared_ptr</b></a> for that usage.</p>
 | 
			
		||||
        <p>Because the implementation uses reference counting, cycles of <b>shared_array</b>
 | 
			
		||||
            instances will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_array</b>
 | 
			
		||||
            to <b>A</b>, which directly or indirectly holds a <b>shared_array</b> back to <b>A</b>,
 | 
			
		||||
            <b>A</b>'s use count will be 2. Destruction of the original <b>shared_array</b> 
 | 
			
		||||
            will leave <b>A</b> dangling with a use count of 1.</p>
 | 
			
		||||
        <p>A <b>shared_ptr</b> to a <b>std::vector</b> is an alternative to a <b>shared_array</b>
 | 
			
		||||
            that is a bit heavier duty but far more flexible.</p>
 | 
			
		||||
        <p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
            to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
            common requirements</a>.</p>
 | 
			
		||||
        <h2>Synopsis</h2>
 | 
			
		||||
        <pre>namespace boost {
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>shared_array</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="#ffffff" text="#000000">
 | 
			
		||||
		<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
 | 
			
		||||
					border="0"></A>shared_array class template</h1>
 | 
			
		||||
		<p>The <b>shared_array</b> class template stores a pointer to a dynamically 
 | 
			
		||||
			allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
 | 
			
		||||
			expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
 | 
			
		||||
			pointing to it is destroyed or reset.</p>
 | 
			
		||||
		<p>Every <b>shared_array</b> meets the <b>CopyConstructible</b> and <b>Assignable</b>
 | 
			
		||||
			requirements of the C++ Standard Library, and so can be used in standard 
 | 
			
		||||
			library containers. Comparison operators are supplied so that <b>shared_array</b>
 | 
			
		||||
			works with the standard library's associative containers.</p>
 | 
			
		||||
		<p>Normally, a <b>shared_array</b> cannot correctly hold a pointer to an object 
 | 
			
		||||
			that has been allocated with the non-array form of <STRONG>new</STRONG>. See <a href="shared_ptr.htm">
 | 
			
		||||
				<b>shared_ptr</b></a> for that usage.</p>
 | 
			
		||||
		<p>Because the implementation uses reference counting, cycles of <b>shared_array</b>
 | 
			
		||||
			instances will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_array</b>
 | 
			
		||||
			to <b>A</b>, which directly or indirectly holds a <b>shared_array</b> back to <b>A</b>,
 | 
			
		||||
			<b>A</b>'s use count will be 2. Destruction of the original <b>shared_array</b> 
 | 
			
		||||
			will leave <b>A</b> dangling with a use count of 1.</p>
 | 
			
		||||
		<p>A <b>shared_ptr</b> to a <b>std::vector</b> is an alternative to a <b>shared_array</b>
 | 
			
		||||
			that is a bit heavier duty but far more flexible.</p>
 | 
			
		||||
		<p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
			to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
				common requirements</a>.</p>
 | 
			
		||||
		<h2>Synopsis</h2>
 | 
			
		||||
		<pre>namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<class T> class shared_array {
 | 
			
		||||
 | 
			
		||||
@@ -68,116 +68,118 @@
 | 
			
		||||
  template<class T> void <a href="#free-swap">swap</a>(shared_array<T> & a, shared_array<T> & b); // never throws
 | 
			
		||||
 | 
			
		||||
}</pre>
 | 
			
		||||
        <h2>Members</h2>
 | 
			
		||||
        <h3><a name="element_type">element_type</a></h3>
 | 
			
		||||
        <pre>typedef T element_type;</pre>
 | 
			
		||||
        <p>Provides the type of the stored pointer.</p>
 | 
			
		||||
        <h3><a name="constructors">constructors</a></h3>
 | 
			
		||||
        <pre>explicit shared_array(T * p = 0);</pre>
 | 
			
		||||
        <p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b>, which must be a 
 | 
			
		||||
            pointer to an array that was allocated via a C++ <b>new[]</b> expression or be 
 | 
			
		||||
            0. Afterwards, the <a href="#use_count">use count</a> is 1 (even if p == 0; see <a href="#destructor">
 | 
			
		||||
            ~shared_array</a>). The only exception which may be thrown by this 
 | 
			
		||||
            constructor is <b>std::bad_alloc</b>. If an exception is thrown, <b>delete[] p</b>
 | 
			
		||||
            is called.</p>
 | 
			
		||||
        <pre>template<class D> shared_array(T * p, D d);</pre>
 | 
			
		||||
        <p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b> and of <b>d</b>. 
 | 
			
		||||
            Afterwards, the <a href="#use_count">use count</a> is 1. <b>D</b>'s copy 
 | 
			
		||||
            constructor and destructor must not throw. When the the time comes to delete 
 | 
			
		||||
            the array pointed to by <b>p</b>, the object <b>d</b> is used in the statement <b>d(p)</b>. 
 | 
			
		||||
            Invoking the object <b>d</b> with parameter <b>p</b> in this way must not 
 | 
			
		||||
            throw. The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>. 
 | 
			
		||||
            If an exception is thrown, <b>d(p)</b> is called.</p>
 | 
			
		||||
        <pre>shared_array(shared_array const & r); // never throws</pre>
 | 
			
		||||
        <p>Constructs a <b>shared_array</b>, as if by storing a copy of the pointer stored 
 | 
			
		||||
            in <b>r</b>. Afterwards, the <a href="#use_count">use count</a> for all copies 
 | 
			
		||||
            is 1 more than the initial use count.</p>
 | 
			
		||||
        <h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
        <pre>~shared_array(); // never throws</pre>
 | 
			
		||||
        <p>Decrements the <a href="#use_count">use count</a>. Then, if the use count is 0, 
 | 
			
		||||
            deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on 
 | 
			
		||||
            a pointer with a value of 0 is harmless. <b>T</b> need not be a complete type. 
 | 
			
		||||
            The guarantee that this does not throw exceptions depends on the requirement 
 | 
			
		||||
            that the deleted object's destructor does not throw exceptions. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="assignment">assignment</a></h3>
 | 
			
		||||
        <pre>shared_array & operator=(shared_array const & r); // never throws</pre>
 | 
			
		||||
        <p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, 
 | 
			
		||||
            then replaces this <b>shared_array</b> with the new one, destroying the 
 | 
			
		||||
            replaced object.</p>
 | 
			
		||||
        <h3><a name="reset">reset</a></h3>
 | 
			
		||||
        <pre>void reset(T * p = 0);</pre>
 | 
			
		||||
        <p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, 
 | 
			
		||||
            then replaces this <b>shared_array</b> with the new one, destroying the 
 | 
			
		||||
            replaced object. The only exception which may be thrown is <b>std::bad_alloc</b>. 
 | 
			
		||||
            If an exception is thrown, <b>delete[] p</b> is called.</p>
 | 
			
		||||
        <pre>template<class D> void reset(T * p, D d);</pre>
 | 
			
		||||
        <p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, 
 | 
			
		||||
            then replaces this <b>shared_array</b> with the new one, destroying the 
 | 
			
		||||
            replaced object. <b>D</b>'s copy constructor must not throw. The only exception 
 | 
			
		||||
            which may be thrown is <b>std::bad_alloc</b>. If an exception is thrown, <b>d(p)</b>
 | 
			
		||||
            is called.</p>
 | 
			
		||||
        <h3><a name="indexing">indexing</a></h3>
 | 
			
		||||
        <pre>T & operator[](std::ptrdiff_t i) const; // never throws</pre>
 | 
			
		||||
        <p>Returns a reference to element <b>i</b> of the array pointed to by the stored 
 | 
			
		||||
            pointer. Behavior is undefined and almost certainly undesirable if the stored 
 | 
			
		||||
            pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the 
 | 
			
		||||
            number of elements in the array.</p>
 | 
			
		||||
        <h3><a name="get">get</a></h3>
 | 
			
		||||
        <pre>T * get() const; // never throws</pre>
 | 
			
		||||
        <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="unique">unique</a></h3>
 | 
			
		||||
        <pre>bool unique() const; // never throws</pre>
 | 
			
		||||
        <p>Returns true if no other <b>shared_array</b> is sharing ownership of the stored 
 | 
			
		||||
            pointer, false otherwise. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
            pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h3><a name="use_count">use_count</a></h3>
 | 
			
		||||
        <pre>long use_count() const; // never throws</pre>
 | 
			
		||||
        <p>Returns the number of <b>shared_array</b> objects sharing ownership of the 
 | 
			
		||||
            stored pointer. <b>T</b> need not be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
            common requirements</a>.</p>
 | 
			
		||||
        <p>Because <b>use_count</b> is not necessarily efficient to implement for 
 | 
			
		||||
            implementations of <b>shared_array</b> that do not use an explicit reference 
 | 
			
		||||
            count, it might be removed from some future version. Thus it should be used for 
 | 
			
		||||
            debugging purposes only, and not production code.</p>
 | 
			
		||||
        <h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
        <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
        <p>Returns an unspecified value that, when used in boolean contexts, is equivalent 
 | 
			
		||||
            to <code>get() != 0</code>.</p>
 | 
			
		||||
        <h3><a name="swap">swap</a></h3>
 | 
			
		||||
        <pre>void swap(shared_ptr & b); // never throws</pre>
 | 
			
		||||
        <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
            complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
            requirements</a>.</p>
 | 
			
		||||
        <h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
        <h3><a name="comparison">comparison</a></h3>
 | 
			
		||||
        <pre>template<class T>
 | 
			
		||||
		<h2>Members</h2>
 | 
			
		||||
		<h3><a name="element_type">element_type</a></h3>
 | 
			
		||||
		<pre>typedef T element_type;</pre>
 | 
			
		||||
		<p>Provides the type of the stored pointer.</p>
 | 
			
		||||
		<h3><a name="constructors">constructors</a></h3>
 | 
			
		||||
		<pre>explicit shared_array(T * p = 0);</pre>
 | 
			
		||||
		<p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b>, which must be a 
 | 
			
		||||
			pointer to an array that was allocated via a C++ <b>new[]</b> expression or be 
 | 
			
		||||
			0. Afterwards, the <a href="#use_count">use count</a> is 1 (even if p == 0; see <a href="#destructor">
 | 
			
		||||
				~shared_array</a>). The only exception which may be thrown by this 
 | 
			
		||||
			constructor is <b>std::bad_alloc</b>. If an exception is thrown, <b>delete[] p</b>
 | 
			
		||||
			is called.</p>
 | 
			
		||||
		<pre>template<class D> shared_array(T * p, D d);</pre>
 | 
			
		||||
		<p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b> and of <b>d</b>. 
 | 
			
		||||
			Afterwards, the <a href="#use_count">use count</a> is 1. <b>D</b>'s copy 
 | 
			
		||||
			constructor and destructor must not throw. When the the time comes to delete 
 | 
			
		||||
			the array pointed to by <b>p</b>, the object <b>d</b> is used in the statement <b>d(p)</b>. 
 | 
			
		||||
			Invoking the object <b>d</b> with parameter <b>p</b> in this way must not 
 | 
			
		||||
			throw. The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>. 
 | 
			
		||||
			If an exception is thrown, <b>d(p)</b> is called.</p>
 | 
			
		||||
		<pre>shared_array(shared_array const & r); // never throws</pre>
 | 
			
		||||
		<p>Constructs a <b>shared_array</b>, as if by storing a copy of the pointer stored 
 | 
			
		||||
			in <b>r</b>. Afterwards, the <a href="#use_count">use count</a> for all copies 
 | 
			
		||||
			is 1 more than the initial use count.</p>
 | 
			
		||||
		<h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
		<pre>~shared_array(); // never throws</pre>
 | 
			
		||||
		<p>Decrements the <a href="#use_count">use count</a>. Then, if the use count is 0, 
 | 
			
		||||
			deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on 
 | 
			
		||||
			a pointer with a value of 0 is harmless. <b>T</b> need not be a complete type. 
 | 
			
		||||
			The guarantee that this does not throw exceptions depends on the requirement 
 | 
			
		||||
			that the deleted object's destructor does not throw exceptions. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="assignment">assignment</a></h3>
 | 
			
		||||
		<pre>shared_array & operator=(shared_array const & r); // never throws</pre>
 | 
			
		||||
		<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, 
 | 
			
		||||
			then replaces this <b>shared_array</b> with the new one, destroying the 
 | 
			
		||||
			replaced object.</p>
 | 
			
		||||
		<h3><a name="reset">reset</a></h3>
 | 
			
		||||
		<pre>void reset(T * p = 0);</pre>
 | 
			
		||||
		<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, 
 | 
			
		||||
			then replaces this <b>shared_array</b> with the new one, destroying the 
 | 
			
		||||
			replaced object. The only exception which may be thrown is <b>std::bad_alloc</b>. 
 | 
			
		||||
			If an exception is thrown, <b>delete[] p</b> is called.</p>
 | 
			
		||||
		<pre>template<class D> void reset(T * p, D d);</pre>
 | 
			
		||||
		<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, 
 | 
			
		||||
			then replaces this <b>shared_array</b> with the new one, destroying the 
 | 
			
		||||
			replaced object. <b>D</b>'s copy constructor must not throw. The only exception 
 | 
			
		||||
			which may be thrown is <b>std::bad_alloc</b>. If an exception is thrown, <b>d(p)</b>
 | 
			
		||||
			is called.</p>
 | 
			
		||||
		<h3><a name="indexing">indexing</a></h3>
 | 
			
		||||
		<pre>T & operator[](std::ptrdiff_t i) const; // never throws</pre>
 | 
			
		||||
		<p>Returns a reference to element <b>i</b> of the array pointed to by the stored 
 | 
			
		||||
			pointer. Behavior is undefined and almost certainly undesirable if the stored 
 | 
			
		||||
			pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the 
 | 
			
		||||
			number of elements in the array.</p>
 | 
			
		||||
		<h3><a name="get">get</a></h3>
 | 
			
		||||
		<pre>T * get() const; // never throws</pre>
 | 
			
		||||
		<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="unique">unique</a></h3>
 | 
			
		||||
		<pre>bool unique() const; // never throws</pre>
 | 
			
		||||
		<p>Returns true if no other <b>shared_array</b> is sharing ownership of the stored 
 | 
			
		||||
			pointer, false otherwise. <b>T</b> need not be a complete type. See the smart 
 | 
			
		||||
			pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h3><a name="use_count">use_count</a></h3>
 | 
			
		||||
		<pre>long use_count() const; // never throws</pre>
 | 
			
		||||
		<p>Returns the number of <b>shared_array</b> objects sharing ownership of the 
 | 
			
		||||
			stored pointer. <b>T</b> need not be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
 | 
			
		||||
				common requirements</a>.</p>
 | 
			
		||||
		<p>Because <b>use_count</b> is not necessarily efficient to implement for 
 | 
			
		||||
			implementations of <b>shared_array</b> that do not use an explicit reference 
 | 
			
		||||
			count, it might be removed from some future version. Thus it should be used for 
 | 
			
		||||
			debugging purposes only, and not production code.</p>
 | 
			
		||||
		<h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
		<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
		<p>Returns an unspecified value that, when used in boolean contexts, is equivalent 
 | 
			
		||||
			to <code>get() != 0</code>.</p>
 | 
			
		||||
		<h3><a name="swap">swap</a></h3>
 | 
			
		||||
		<pre>void swap(shared_ptr & b); // never throws</pre>
 | 
			
		||||
		<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
			complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
				requirements</a>.</p>
 | 
			
		||||
		<h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
		<h3><a name="comparison">comparison</a></h3>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  bool operator==(shared_array<T> const & a, shared_array<T> const & b); // never throws
 | 
			
		||||
template<class T>
 | 
			
		||||
  bool operator!=(shared_array<T> const & a, shared_array<T> const & b); // never throws
 | 
			
		||||
template<class T>
 | 
			
		||||
  bool operator<(shared_array<T> const & a, shared_array<T> const & b); // never throws</pre>
 | 
			
		||||
        <p>Compares the stored pointers of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
            complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
            requirements</a>.</p>
 | 
			
		||||
        <p>The <b>operator<</b> overload is provided to define an ordering so that <b>shared_array</b>
 | 
			
		||||
            objects can be used in associative containers such as <b>std::map</b>. The 
 | 
			
		||||
            implementation uses <b>std::less<T *></b> to perform the comparison. This 
 | 
			
		||||
            ensures that the comparison is handled correctly, since the standard mandates 
 | 
			
		||||
            that relational operations on pointers are unspecified (5.9 [expr.rel] 
 | 
			
		||||
            paragraph 2) but <b>std::less<></b> on pointers is well-defined (20.3.3 
 | 
			
		||||
            [lib.comparisons] paragraph 8).</p>
 | 
			
		||||
        <h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
        <pre>template<class T>
 | 
			
		||||
		<p>Compares the stored pointers of the two smart pointers. <b>T</b> need not be a 
 | 
			
		||||
			complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common 
 | 
			
		||||
				requirements</a>.</p>
 | 
			
		||||
		<p>The <b>operator<</b> overload is provided to define an ordering so that <b>shared_array</b>
 | 
			
		||||
			objects can be used in associative containers such as <b>std::map</b>. The 
 | 
			
		||||
			implementation uses <b>std::less<T *></b> to perform the comparison. This 
 | 
			
		||||
			ensures that the comparison is handled correctly, since the standard mandates 
 | 
			
		||||
			that relational operations on pointers are unspecified (5.9 [expr.rel] 
 | 
			
		||||
			paragraph 2) but <b>std::less<></b> on pointers is well-defined (20.3.3 
 | 
			
		||||
			[lib.comparisons] paragraph 8).</p>
 | 
			
		||||
		<h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  void swap(shared_array<T> & a, shared_array<T> & b) // never throws</pre>
 | 
			
		||||
        <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. 
 | 
			
		||||
            Provided as an aid to generic programming.</p>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
            Copyright 2002-2005 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>
 | 
			
		||||
		<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. 
 | 
			
		||||
			Provided as an aid to generic programming.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>Revised 
 | 
			
		||||
			<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan --> 
 | 
			
		||||
			09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1350
									
								
								shared_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										1350
									
								
								shared_ptr.htm
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										411
									
								
								smart_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										411
									
								
								smart_ptr.htm
									
									
									
									
									
								
							@@ -1,221 +1,196 @@
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>Smart Pointers</title>
 | 
			
		||||
        <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">Smart Pointers</h1>
 | 
			
		||||
        <p><a href="#Introduction">Introduction</a><br>
 | 
			
		||||
            <a href="#common_requirements">Common Requirements</a><br>
 | 
			
		||||
            <a href="#Exception_Safety">Exception Safety</a><br>
 | 
			
		||||
            <a href="#Exception-specifications">Exception-specifications</a><br>
 | 
			
		||||
            <a href="#History">History and Acknowledgements</a><br>
 | 
			
		||||
            <a href="#References">References</a></p>
 | 
			
		||||
        <h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
        <p>Smart pointers are objects which store pointers to dynamically allocated (heap)
 | 
			
		||||
            objects. They behave much like built-in C++ pointers except that they
 | 
			
		||||
            automatically delete the object pointed to at the appropriate time. Smart
 | 
			
		||||
            pointers are particularly useful in the face of exceptions as they ensure
 | 
			
		||||
            proper destruction of dynamically allocated objects. They can also be used to
 | 
			
		||||
            keep track of dynamically allocated objects shared by multiple owners.</p>
 | 
			
		||||
        <p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
 | 
			
		||||
            responsible for deletion of the object when it is no longer needed.</p>
 | 
			
		||||
        <p>The smart pointer library provides six smart pointer class templates:</p>
 | 
			
		||||
        <div align="left">
 | 
			
		||||
            <table border="1" cellpadding="4" cellspacing="0">
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="scoped_ptr.htm"><b>scoped_ptr</b></a></td>
 | 
			
		||||
                    <td><a href="../../boost/scoped_ptr.hpp"><boost/scoped_ptr.hpp></a></td>
 | 
			
		||||
                    <td>Simple sole ownership of single objects. Noncopyable.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="scoped_array.htm"><b>scoped_array</b></a></td>
 | 
			
		||||
                    <td><a href="../../boost/scoped_array.hpp"><boost/scoped_array.hpp></a></td>
 | 
			
		||||
                    <td>Simple sole ownership of arrays. Noncopyable.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
 | 
			
		||||
                    <td><a href="../../boost/shared_ptr.hpp"><boost/shared_ptr.hpp></a></td>
 | 
			
		||||
                    <td>Object ownership shared among multiple pointers.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="shared_array.htm"><b>shared_array</b></a></td>
 | 
			
		||||
                    <td><a href="../../boost/shared_array.hpp"><boost/shared_array.hpp></a></td>
 | 
			
		||||
                    <td>Array ownership shared among multiple pointers.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="weak_ptr.htm"><b>weak_ptr</b></a></td>
 | 
			
		||||
                    <td><a href="../../boost/weak_ptr.hpp"><boost/weak_ptr.hpp></a></td>
 | 
			
		||||
                    <td>Non-owning observers of an object owned by <b>shared_ptr</b>.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="intrusive_ptr.html"><b>intrusive_ptr</b></a></td>
 | 
			
		||||
                    <td><a href="../../boost/intrusive_ptr.hpp"><boost/intrusive_ptr.hpp></a></td>
 | 
			
		||||
                    <td>Shared ownership of objects with an embedded reference count.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
        <p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
 | 
			
		||||
        <p>They are examples of the "resource acquisition is initialization" idiom
 | 
			
		||||
            described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
 | 
			
		||||
            Section 14.4, Resource Management.</p>
 | 
			
		||||
        <p>Additionally, the smart pointer library provides efficient factory functions
 | 
			
		||||
            for creating smart pointer objects:</p>
 | 
			
		||||
        <div align="left">
 | 
			
		||||
            <table border="1" cellpadding="4" cellspacing="0">
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="make_shared.html"><b>make_shared, allocate_shared</b></a> for objects</td>
 | 
			
		||||
                    <td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
 | 
			
		||||
                    <td>Efficient creation of <code>shared_ptr</code> objects.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="make_shared_array.html"><b>make_shared, allocate_shared</b></a> for arrays</td>
 | 
			
		||||
                    <td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
 | 
			
		||||
                    <td>Efficient creation of <code>shared_ptr</code> arrays.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td><a href="make_unique.html"><b>make_unique</b></a></td>
 | 
			
		||||
                    <td><a href="../../boost/make_unique.hpp"><boost/make_unique.hpp></a></td>
 | 
			
		||||
                    <td>Creation of <code>unique_ptr</code> objects and arrays.</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
        <p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
 | 
			
		||||
            provided to verify correct operation.</p>
 | 
			
		||||
        <p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
 | 
			
		||||
            the Boost smart pointer library describes some of the changes since earlier
 | 
			
		||||
            versions of the smart pointer implementation.</p>
 | 
			
		||||
        <p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
 | 
			
		||||
            to those curious about performance issues.</p>
 | 
			
		||||
        <P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
 | 
			
		||||
            some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P>
 | 
			
		||||
        <h2><a name="common_requirements">Common Requirements</a></h2>
 | 
			
		||||
        <p>These smart pointer class templates have a template parameter, <b>T</b>, which
 | 
			
		||||
            specifies the type of the object pointed to by the smart pointer. The behavior
 | 
			
		||||
            of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
 | 
			
		||||
            for objects of type <b>T</b> throw exceptions.</p>
 | 
			
		||||
        <p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
 | 
			
		||||
            Unless otherwise specified, it is required that <b>T</b> be a complete type at
 | 
			
		||||
            points of smart pointer instantiation. Implementations are required to diagnose
 | 
			
		||||
            (treat as an error) all violations of this requirement, including deletion of
 | 
			
		||||
            an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
 | 
			
		||||
            <b>checked_delete</b></a> function template.</p>
 | 
			
		||||
        <P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
 | 
			
		||||
            its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
 | 
			
		||||
        <h3>Rationale</h3>
 | 
			
		||||
        <p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
 | 
			
		||||
            handle-body (also called pimpl) and similar idioms. In these idioms a smart
 | 
			
		||||
            pointer may appear in translation units where <b>T</b> is an incomplete type.
 | 
			
		||||
            This separates interface from implementation and hides implementation from
 | 
			
		||||
            translation units which merely use the interface. Examples described in the
 | 
			
		||||
            documentation for specific smart pointers illustrate use of smart pointers in
 | 
			
		||||
            these idioms.</p>
 | 
			
		||||
        <p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
 | 
			
		||||
            destruction time, but <b>shared_ptr</b> does not.</p>
 | 
			
		||||
        <h2><a name="Exception_Safety">Exception Safety</a></h2>
 | 
			
		||||
        <p>Several functions in these smart pointer classes are specified as having "no
 | 
			
		||||
            effect" or "no effect except such-and-such" if an exception is thrown. This
 | 
			
		||||
            means that when an exception is thrown by an object of one of these classes,
 | 
			
		||||
            the entire program state remains the same as it was prior to the function call
 | 
			
		||||
            which resulted in the exception being thrown. This amounts to a guarantee that
 | 
			
		||||
            there are no detectable side effects. Other functions never throw exceptions.
 | 
			
		||||
            The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
 | 
			
		||||
            the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
 | 
			
		||||
            and that is thrown only by functions which are explicitly documented as
 | 
			
		||||
            possibly throwing <b>std::bad_alloc</b>.</p>
 | 
			
		||||
        <h2><a name="Exception-specifications">Exception-specifications</a></h2>
 | 
			
		||||
        <p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
 | 
			
		||||
            exception-specification rationale</a>.</p>
 | 
			
		||||
        <p>All the smart pointer templates contain member functions which can never throw
 | 
			
		||||
            exceptions, because they neither throw exceptions themselves nor call other
 | 
			
		||||
            functions which may throw exceptions. These members are indicated by a comment: <code>
 | 
			
		||||
            // never throws</code>.
 | 
			
		||||
        </p>
 | 
			
		||||
        <p>Functions which destroy objects of the pointed to type are prohibited from
 | 
			
		||||
            throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
 | 
			
		||||
        <h2><a name="History">History</a> and Acknowledgements</h2>
 | 
			
		||||
        <p>February 2014. Glen Fernandes updated overloads of <b>make_shared</b> and 
 | 
			
		||||
            <b>allocate_shared</b> to conform to the specification in C++ standard paper 
 | 
			
		||||
            <a href="#D&F-14">[D&F-14]</a>, and implemented <b>make_unique</b> for 
 | 
			
		||||
            arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and 
 | 
			
		||||
            array implementations, respectively, to resolve C++ standard library defect 
 | 
			
		||||
            2070.</p>
 | 
			
		||||
        <p>November 2012. Glen Fernandes provided implementations of <b>make_shared</b> 
 | 
			
		||||
            and <b>allocate_shared</b> for arrays. They achieve a single allocation for an
 | 
			
		||||
            array that can be initialized with constructor arguments or initializer lists 
 | 
			
		||||
            as well as overloads for default initialization and no value initialization. 
 | 
			
		||||
            See the <a href="make_shared_array.html">make_shared and allocate_shared for 
 | 
			
		||||
            arrays</a> page for more information.</p>
 | 
			
		||||
        <p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
 | 
			
		||||
            bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
 | 
			
		||||
            See the <a href="compatibility.htm">compatibility</a> page for a summary of the
 | 
			
		||||
            changes.</p>
 | 
			
		||||
        <p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
 | 
			
		||||
            Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
 | 
			
		||||
            Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
 | 
			
		||||
            others.</p>
 | 
			
		||||
        <p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
 | 
			
		||||
            and <b>std::less</b> specializations for shared types.</p>
 | 
			
		||||
        <p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p>
 | 
			
		||||
        <p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
 | 
			
		||||
            number of suggestions resulting in numerous improvements.</p>
 | 
			
		||||
        <p>October 1998. Beman Dawes proposed reviving the original semantics under the
 | 
			
		||||
            names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
 | 
			
		||||
            Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl,
 | 
			
		||||
            Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
 | 
			
		||||
            class names were finalized, it was decided that there was no need to exactly
 | 
			
		||||
            follow the <b>std::auto_ptr</b> interface, and various function signatures and
 | 
			
		||||
            semantics were finalized.</p>
 | 
			
		||||
        <p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
 | 
			
		||||
            and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
 | 
			
		||||
            The implementation questions revolved around the reference count which must be
 | 
			
		||||
            kept, either attached to the pointed to object, or detached elsewhere. Each of
 | 
			
		||||
            those variants have themselves two major variants:
 | 
			
		||||
            <ul>
 | 
			
		||||
                <li>
 | 
			
		||||
                Direct detached: the shared_ptr contains a pointer to the object, and a pointer
 | 
			
		||||
                to the count.
 | 
			
		||||
                <li>
 | 
			
		||||
                Indirect detached: the shared_ptr contains a pointer to a helper object, which
 | 
			
		||||
                in turn contains a pointer to the object and the count.
 | 
			
		||||
                <li>
 | 
			
		||||
                Embedded attached: the count is a member of the object pointed to.
 | 
			
		||||
                <li>
 | 
			
		||||
                Placement attached: the count is attached via operator new manipulations.</li>
 | 
			
		||||
            </ul>
 | 
			
		||||
        <p>Each implementation technique has advantages and disadvantages. We went so far
 | 
			
		||||
            as to run various timings of the direct and indirect approaches, and found that
 | 
			
		||||
            at least on Intel Pentium chips there was very little measurable difference.
 | 
			
		||||
            Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
 | 
			
		||||
            Kühl suggested an elegant partial template specialization technique to allow
 | 
			
		||||
            users to choose which implementation they preferred, and that was also
 | 
			
		||||
            experimented with.</p>
 | 
			
		||||
        <p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
 | 
			
		||||
            users", and in the end we choose to supply only the direct implementation.</p>
 | 
			
		||||
        <p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b>
 | 
			
		||||
            and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b>
 | 
			
		||||
            and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
 | 
			
		||||
            cases where the Library Working Group's recommendations were not followed by
 | 
			
		||||
            the full committee, <b>counted_ptr</b> was rejected and surprising
 | 
			
		||||
            transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
 | 
			
		||||
        <h2><a name="References">References</a></h2>
 | 
			
		||||
        <p>[<a name="D&F-14">D&F-14</a>] Peter Dimov & Glen Fernandes, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
 | 
			
		||||
            Extending make_shared to Support Arrays, Revision 1</a>, C++ committee document N3870,
 | 
			
		||||
            January, 2014.</p>
 | 
			
		||||
        <p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
 | 
			
		||||
            Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
 | 
			
		||||
            July, 1994.</p>
 | 
			
		||||
        <p>[<a name="E&D-94">E&D-94</a>] John R. Ellis & David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
 | 
			
		||||
            Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
 | 
			
		||||
            February, 1994. This paper includes an extensive discussion of weak pointers
 | 
			
		||||
            and an extensive bibliography.</p>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
 | 
			
		||||
            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>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>Smart Pointers</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="#ffffff" text="#000000">
 | 
			
		||||
		<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
 | 
			
		||||
					border="0"></A>Smart Pointers</h1>
 | 
			
		||||
		<p><a href="#Introduction">Introduction</a><br>
 | 
			
		||||
			<a href="#common_requirements">Common Requirements</a><br>
 | 
			
		||||
			<a href="#Exception_Safety">Exception Safety</a><br>
 | 
			
		||||
			<a href="#Exception-specifications">Exception-specifications</a><br>
 | 
			
		||||
			<a href="#History">History and Acknowledgements</a><br>
 | 
			
		||||
			<a href="#References">References</a></p>
 | 
			
		||||
		<h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
		<p>Smart pointers are objects which store pointers to dynamically allocated (heap)
 | 
			
		||||
			objects. They behave much like built-in C++ pointers except that they
 | 
			
		||||
			automatically delete the object pointed to at the appropriate time. Smart
 | 
			
		||||
			pointers are particularly useful in the face of exceptions as they ensure
 | 
			
		||||
			proper destruction of dynamically allocated objects. They can also be used to
 | 
			
		||||
			keep track of dynamically allocated objects shared by multiple owners.</p>
 | 
			
		||||
		<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
 | 
			
		||||
			responsible for deletion of the object when it is no longer needed.</p>
 | 
			
		||||
		<p>The smart pointer library provides six smart pointer class templates:</p>
 | 
			
		||||
		<div align="left">
 | 
			
		||||
			<table border="1" cellpadding="4" cellspacing="0">
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="scoped_ptr.htm"><b>scoped_ptr</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/scoped_ptr.hpp"><boost/scoped_ptr.hpp></a></td>
 | 
			
		||||
					<td>Simple sole ownership of single objects. Noncopyable.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="scoped_array.htm"><b>scoped_array</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/scoped_array.hpp"><boost/scoped_array.hpp></a></td>
 | 
			
		||||
					<td>Simple sole ownership of arrays. Noncopyable.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/shared_ptr.hpp"><boost/shared_ptr.hpp></a></td>
 | 
			
		||||
					<td>Object ownership shared among multiple pointers.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="shared_array.htm"><b>shared_array</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/shared_array.hpp"><boost/shared_array.hpp></a></td>
 | 
			
		||||
					<td>Array ownership shared among multiple pointers.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="weak_ptr.htm"><b>weak_ptr</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/weak_ptr.hpp"><boost/weak_ptr.hpp></a></td>
 | 
			
		||||
					<td>Non-owning observers of an object owned by <b>shared_ptr</b>.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="intrusive_ptr.html"><b>intrusive_ptr</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/intrusive_ptr.hpp"><boost/intrusive_ptr.hpp></a></td>
 | 
			
		||||
					<td>Shared ownership of objects with an embedded reference count.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
			</table>
 | 
			
		||||
		</div>
 | 
			
		||||
		<p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
 | 
			
		||||
		<p>They are examples of the "resource acquisition is initialization" idiom
 | 
			
		||||
			described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
 | 
			
		||||
			Section 14.4, Resource Management.</p>
 | 
			
		||||
		<p>Additionally, the smart pointer library provides efficient factory functions
 | 
			
		||||
			for creating <code>shared_ptr</code> objects:</p>
 | 
			
		||||
		<div align="left">
 | 
			
		||||
			<table border="1" cellpadding="4" cellspacing="0">
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="make_shared.html"><b>make_shared and allocate_shared</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
 | 
			
		||||
					<td>Efficient creation of <code>shared_ptr</code> objects.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
			</table>
 | 
			
		||||
		</div>
 | 
			
		||||
		<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
 | 
			
		||||
			provided to verify correct operation.</p>
 | 
			
		||||
		<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
 | 
			
		||||
			the Boost smart pointer library describes some of the changes since earlier
 | 
			
		||||
			versions of the smart pointer implementation.</p>
 | 
			
		||||
		<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
 | 
			
		||||
			to those curious about performance issues.</p>
 | 
			
		||||
		<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
 | 
			
		||||
			some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P>
 | 
			
		||||
		<h2><a name="common_requirements">Common Requirements</a></h2>
 | 
			
		||||
		<p>These smart pointer class templates have a template parameter, <b>T</b>, which
 | 
			
		||||
			specifies the type of the object pointed to by the smart pointer. The behavior
 | 
			
		||||
			of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
 | 
			
		||||
			for objects of type <b>T</b> throw exceptions.</p>
 | 
			
		||||
		<p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
 | 
			
		||||
			Unless otherwise specified, it is required that <b>T</b> be a complete type at
 | 
			
		||||
			points of smart pointer instantiation. Implementations are required to diagnose
 | 
			
		||||
			(treat as an error) all violations of this requirement, including deletion of
 | 
			
		||||
			an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
 | 
			
		||||
				<b>checked_delete</b></a> function template.</p>
 | 
			
		||||
		<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
 | 
			
		||||
			its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
 | 
			
		||||
		<h3>Rationale</h3>
 | 
			
		||||
		<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
 | 
			
		||||
			handle-body (also called pimpl) and similar idioms. In these idioms a smart
 | 
			
		||||
			pointer may appear in translation units where <b>T</b> is an incomplete type.
 | 
			
		||||
			This separates interface from implementation and hides implementation from
 | 
			
		||||
			translation units which merely use the interface. Examples described in the
 | 
			
		||||
			documentation for specific smart pointers illustrate use of smart pointers in
 | 
			
		||||
			these idioms.</p>
 | 
			
		||||
		<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
 | 
			
		||||
			destruction time, but <b>shared_ptr</b> does not.</p>
 | 
			
		||||
		<h2><a name="Exception_Safety">Exception Safety</a></h2>
 | 
			
		||||
		<p>Several functions in these smart pointer classes are specified as having "no
 | 
			
		||||
			effect" or "no effect except such-and-such" if an exception is thrown. This
 | 
			
		||||
			means that when an exception is thrown by an object of one of these classes,
 | 
			
		||||
			the entire program state remains the same as it was prior to the function call
 | 
			
		||||
			which resulted in the exception being thrown. This amounts to a guarantee that
 | 
			
		||||
			there are no detectable side effects. Other functions never throw exceptions.
 | 
			
		||||
			The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
 | 
			
		||||
			the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
 | 
			
		||||
			and that is thrown only by functions which are explicitly documented as
 | 
			
		||||
			possibly throwing <b>std::bad_alloc</b>.</p>
 | 
			
		||||
		<h2><a name="Exception-specifications">Exception-specifications</a></h2>
 | 
			
		||||
		<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
 | 
			
		||||
				exception-specification rationale</a>.</p>
 | 
			
		||||
		<p>All the smart pointer templates contain member functions which can never throw
 | 
			
		||||
			exceptions, because they neither throw exceptions themselves nor call other
 | 
			
		||||
			functions which may throw exceptions. These members are indicated by a comment: <code>
 | 
			
		||||
				// never throws</code>.
 | 
			
		||||
		</p>
 | 
			
		||||
		<p>Functions which destroy objects of the pointed to type are prohibited from
 | 
			
		||||
			throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h2><a name="History">History</a> and Acknowledgements</h2>
 | 
			
		||||
		<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
 | 
			
		||||
			bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
 | 
			
		||||
			See the <a href="compatibility.htm">compatibility</a> page for a summary of the
 | 
			
		||||
			changes.</p>
 | 
			
		||||
		<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
 | 
			
		||||
			Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
 | 
			
		||||
			Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
 | 
			
		||||
			others.</p>
 | 
			
		||||
		<p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
 | 
			
		||||
			and <b>std::less</b> specializations for shared types.</p>
 | 
			
		||||
		<p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p>
 | 
			
		||||
		<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
 | 
			
		||||
			number of suggestions resulting in numerous improvements.</p>
 | 
			
		||||
		<p>October 1998. Beman Dawes proposed reviving the original semantics under the
 | 
			
		||||
			names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
 | 
			
		||||
			Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl,
 | 
			
		||||
			Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
 | 
			
		||||
			class names were finalized, it was decided that there was no need to exactly
 | 
			
		||||
			follow the <b>std::auto_ptr</b> interface, and various function signatures and
 | 
			
		||||
			semantics were finalized.</p>
 | 
			
		||||
		<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
 | 
			
		||||
			and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
 | 
			
		||||
			The implementation questions revolved around the reference count which must be
 | 
			
		||||
			kept, either attached to the pointed to object, or detached elsewhere. Each of
 | 
			
		||||
			those variants have themselves two major variants:
 | 
			
		||||
			<ul>
 | 
			
		||||
				<li>
 | 
			
		||||
				Direct detached: the shared_ptr contains a pointer to the object, and a pointer
 | 
			
		||||
				to the count.
 | 
			
		||||
				<li>
 | 
			
		||||
				Indirect detached: the shared_ptr contains a pointer to a helper object, which
 | 
			
		||||
				in turn contains a pointer to the object and the count.
 | 
			
		||||
				<li>
 | 
			
		||||
				Embedded attached: the count is a member of the object pointed to.
 | 
			
		||||
				<li>
 | 
			
		||||
					Placement attached: the count is attached via operator new manipulations.</li>
 | 
			
		||||
			</ul>
 | 
			
		||||
		<p>Each implementation technique has advantages and disadvantages. We went so far
 | 
			
		||||
			as to run various timings of the direct and indirect approaches, and found that
 | 
			
		||||
			at least on Intel Pentium chips there was very little measurable difference.
 | 
			
		||||
			Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
 | 
			
		||||
			Kühl suggested an elegant partial template specialization technique to allow
 | 
			
		||||
			users to choose which implementation they preferred, and that was also
 | 
			
		||||
			experimented with.</p>
 | 
			
		||||
		<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
 | 
			
		||||
			users", and in the end we choose to supply only the direct implementation.</p>
 | 
			
		||||
		<p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b>
 | 
			
		||||
			and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b>
 | 
			
		||||
			and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
 | 
			
		||||
			cases where the Library Working Group's recommendations were not followed by
 | 
			
		||||
			the full committee, <b>counted_ptr</b> was rejected and surprising
 | 
			
		||||
			transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
 | 
			
		||||
		<h2><a name="References">References</a></h2>
 | 
			
		||||
		<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
 | 
			
		||||
				Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
 | 
			
		||||
			July, 1994.</p>
 | 
			
		||||
		<p>[<a name="E&D-94">E&D-94</a>] John R. Ellis & David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
 | 
			
		||||
				Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
 | 
			
		||||
			February, 1994. This paper includes an extensive discussion of weak pointers
 | 
			
		||||
			and an extensive bibliography.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>$Date$</p>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
 | 
			
		||||
			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>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,9 @@
 | 
			
		||||
<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">Smart Pointer Timings</h1>
 | 
			
		||||
<body bgcolor="#FFFFFF">
 | 
			
		||||
 | 
			
		||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Smart Pointer Timings</h1>
 | 
			
		||||
 | 
			
		||||
<p>In late January 2000, Mark Borgerding put forward a suggestion to boost for 
 | 
			
		||||
  a new design of smart pointer whereby an intrusive doubly linked list is used 
 | 
			
		||||
@@ -533,8 +533,9 @@ Gavin Collings,
 | 
			
		||||
    spreads its information as in the case of linked pointer.</li>
 | 
			
		||||
</ul>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>$Date$</p>
 | 
			
		||||
<p>© Copyright Gavin Collings 2000. Permission to copy, use, modify, sell
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->19 August 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" -->
 | 
			
		||||
</p>
 | 
			
		||||
<p><EFBFBD> Copyright Gavin Collings 2000. Permission to copy, use, modify, sell
 | 
			
		||||
and distribute this document is granted provided this copyright notice appears in all
 | 
			
		||||
copies. This document is provided "as is" without express or implied warranty,
 | 
			
		||||
and with no claim as to its suitability for any purpose.</p>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,67 +1,67 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <title>Smart Pointer Programming Techniques</title>
 | 
			
		||||
        <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">Smart Pointer Programming Techniques</h1>
 | 
			
		||||
        <p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
 | 
			
		||||
            <A href="#pimpl">The "Pimpl" idiom</A><br>
 | 
			
		||||
            <A href="#abstract">Using abstract classes for implementation hiding</A><br>
 | 
			
		||||
            <A href="#preventing_delete">Preventing <code>delete px.get()</code></A><br>
 | 
			
		||||
            <A href="#array">Using a <code>shared_ptr</code> to hold a pointer to an array</A><br>
 | 
			
		||||
            <A href="#encapsulation">Encapsulating allocation details, wrapping factory 
 | 
			
		||||
                functions</A><br>
 | 
			
		||||
            <A href="#static">Using a <code>shared_ptr</code> to hold a pointer to a statically 
 | 
			
		||||
                allocated object</A><br>
 | 
			
		||||
            <A href="#com">Using a <code>shared_ptr</code> to hold a pointer to a COM object</A><br>
 | 
			
		||||
            <A href="#intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object 
 | 
			
		||||
                with an embedded reference count</A><br>
 | 
			
		||||
            <A href="#another_sp">Using a <code>shared_ptr</code> to hold another shared 
 | 
			
		||||
                ownership smart pointer</A><br>
 | 
			
		||||
            <A href="#from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A><br>
 | 
			
		||||
            <A href="#in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>) 
 | 
			
		||||
                to <code>this</code> in a constructor</A><br>
 | 
			
		||||
            <A href="#from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A><br>
 | 
			
		||||
            <A href="#handle">Using <code>shared_ptr</code> as a smart counted handle</A><br>
 | 
			
		||||
            <A href="#on_block_exit">Using <code>shared_ptr</code> to execute code on block 
 | 
			
		||||
                exit</A><br>
 | 
			
		||||
            <A href="#pvoid">Using <code>shared_ptr<void></code> to hold an arbitrary 
 | 
			
		||||
                object</A><br>
 | 
			
		||||
            <A href="#extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
 | 
			
		||||
                instances</A><br>
 | 
			
		||||
            <A href="#as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A><br>
 | 
			
		||||
            <A href="#wrapper">Using <code>shared_ptr</code> to wrap member function calls</A><br>
 | 
			
		||||
            <A href="#delayed">Delayed deallocation</A><br>
 | 
			
		||||
            <A href="#weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A><br>
 | 
			
		||||
        </p>
 | 
			
		||||
        <h2><A name="incomplete">Using incomplete classes for implementation hiding</A></h2>
 | 
			
		||||
        <p>A proven technique (that works in C, too) for separating interface from 
 | 
			
		||||
            implementation is to use a pointer to an incomplete class as an opaque handle:</p>
 | 
			
		||||
        <pre>class FILE;
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>Smart Pointer Programming Techniques</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>Smart Pointer Programming Techniques</h1>
 | 
			
		||||
		<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
 | 
			
		||||
			<A href="#pimpl">The "Pimpl" idiom</A><br>
 | 
			
		||||
			<A href="#abstract">Using abstract classes for implementation hiding</A><br>
 | 
			
		||||
			<A href="#preventing_delete">Preventing <code>delete px.get()</code></A><br>
 | 
			
		||||
			<A href="#array">Using a <code>shared_ptr</code> to hold a pointer to an array</A><br>
 | 
			
		||||
			<A href="#encapsulation">Encapsulating allocation details, wrapping factory 
 | 
			
		||||
				functions</A><br>
 | 
			
		||||
			<A href="#static">Using a <code>shared_ptr</code> to hold a pointer to a statically 
 | 
			
		||||
				allocated object</A><br>
 | 
			
		||||
			<A href="#com">Using a <code>shared_ptr</code> to hold a pointer to a COM object</A><br>
 | 
			
		||||
			<A href="#intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object 
 | 
			
		||||
				with an embedded reference count</A><br>
 | 
			
		||||
			<A href="#another_sp">Using a <code>shared_ptr</code> to hold another shared 
 | 
			
		||||
				ownership smart pointer</A><br>
 | 
			
		||||
			<A href="#from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A><br>
 | 
			
		||||
			<A href="#in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>) 
 | 
			
		||||
				to <code>this</code> in a constructor</A><br>
 | 
			
		||||
			<A href="#from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A><br>
 | 
			
		||||
			<A href="#handle">Using <code>shared_ptr</code> as a smart counted handle</A><br>
 | 
			
		||||
			<A href="#on_block_exit">Using <code>shared_ptr</code> to execute code on block 
 | 
			
		||||
				exit</A><br>
 | 
			
		||||
			<A href="#pvoid">Using <code>shared_ptr<void></code> to hold an arbitrary 
 | 
			
		||||
				object</A><br>
 | 
			
		||||
			<A href="#extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
 | 
			
		||||
				instances</A><br>
 | 
			
		||||
			<A href="#as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A><br>
 | 
			
		||||
			<A href="#wrapper">Using <code>shared_ptr</code> to wrap member function calls</A><br>
 | 
			
		||||
			<A href="#delayed">Delayed deallocation</A><br>
 | 
			
		||||
			<A href="#weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A><br>
 | 
			
		||||
		</p>
 | 
			
		||||
		<h2><A name="incomplete">Using incomplete classes for implementation hiding</A></h2>
 | 
			
		||||
		<p>A proven technique (that works in C, too) for separating interface from 
 | 
			
		||||
			implementation is to use a pointer to an incomplete class as an opaque handle:</p>
 | 
			
		||||
		<pre>class FILE;
 | 
			
		||||
 | 
			
		||||
FILE * fopen(char const * name, char const * mode);
 | 
			
		||||
void fread(FILE * f, void * data, size_t size);
 | 
			
		||||
void fclose(FILE * f);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>It is possible to express the above interface using <code>shared_ptr</code>, 
 | 
			
		||||
            eliminating the need to manually call <code>fclose</code>:</p>
 | 
			
		||||
        <pre>class FILE;
 | 
			
		||||
		<p>It is possible to express the above interface using <code>shared_ptr</code>, 
 | 
			
		||||
			eliminating the need to manually call <code>fclose</code>:</p>
 | 
			
		||||
		<pre>class FILE;
 | 
			
		||||
 | 
			
		||||
shared_ptr<FILE> fopen(char const * name, char const * mode);
 | 
			
		||||
void fread(shared_ptr<FILE> f, void * data, size_t size);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>This technique relies on <code>shared_ptr</code>'s ability to execute a custom 
 | 
			
		||||
            deleter, eliminating the explicit call to <code>fclose</code>, and on the fact 
 | 
			
		||||
            that <code>shared_ptr<X></code> can be copied and destroyed when <code>X</code>
 | 
			
		||||
            is incomplete.</p>
 | 
			
		||||
        <h2><A name="pimpl">The "Pimpl" idiom</A></h2>
 | 
			
		||||
        <p>A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom. 
 | 
			
		||||
            The incomplete class is not exposed to the user; it is hidden behind a 
 | 
			
		||||
            forwarding facade. <code>shared_ptr</code> can be used to implement a "Pimpl":</p>
 | 
			
		||||
        <pre>// file.hpp:
 | 
			
		||||
		<p>This technique relies on <code>shared_ptr</code>'s ability to execute a custom 
 | 
			
		||||
			deleter, eliminating the explicit call to <code>fclose</code>, and on the fact 
 | 
			
		||||
			that <code>shared_ptr<X></code> can be copied and destroyed when <code>X</code>
 | 
			
		||||
			is incomplete.</p>
 | 
			
		||||
		<h2><A name="pimpl">The "Pimpl" idiom</A></h2>
 | 
			
		||||
		<p>A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom. 
 | 
			
		||||
			The incomplete class is not exposed to the user; it is hidden behind a 
 | 
			
		||||
			forwarding facade. <code>shared_ptr</code> can be used to implement a "Pimpl":</p>
 | 
			
		||||
		<pre>// file.hpp:
 | 
			
		||||
 | 
			
		||||
class file
 | 
			
		||||
{
 | 
			
		||||
@@ -79,7 +79,7 @@ public:
 | 
			
		||||
    void read(void * data, size_t size);
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <pre>// file.cpp:
 | 
			
		||||
		<pre>// file.cpp:
 | 
			
		||||
 | 
			
		||||
#include "file.hpp"
 | 
			
		||||
 | 
			
		||||
@@ -108,17 +108,17 @@ void file::read(void * data, size_t size)
 | 
			
		||||
    pimpl_->read(data, size);
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>The key thing to note here is that the compiler-generated copy constructor, 
 | 
			
		||||
            assignment operator, and destructor all have a sensible meaning. As a result, <code>
 | 
			
		||||
                file</code> is <code>CopyConstructible</code> and <code>Assignable</code>, 
 | 
			
		||||
            allowing its use in standard containers.</p>
 | 
			
		||||
        <h2><A name="abstract">Using abstract classes for implementation hiding</A></h2>
 | 
			
		||||
        <p>Another widely used C++ idiom for separating inteface and implementation is to 
 | 
			
		||||
            use abstract base classes and factory functions. The abstract classes are 
 | 
			
		||||
            sometimes called "interfaces" and the pattern is known as "interface-based 
 | 
			
		||||
            programming". Again, <code>shared_ptr</code> can be used as the return type of 
 | 
			
		||||
            the factory functions:</p>
 | 
			
		||||
        <pre>// X.hpp:
 | 
			
		||||
		<p>The key thing to note here is that the compiler-generated copy constructor, 
 | 
			
		||||
			assignment operator, and destructor all have a sensible meaning. As a result, <code>
 | 
			
		||||
				file</code> is <code>CopyConstructible</code> and <code>Assignable</code>, 
 | 
			
		||||
			allowing its use in standard containers.</p>
 | 
			
		||||
		<h2><A name="abstract">Using abstract classes for implementation hiding</A></h2>
 | 
			
		||||
		<p>Another widely used C++ idiom for separating inteface and implementation is to 
 | 
			
		||||
			use abstract base classes and factory functions. The abstract classes are 
 | 
			
		||||
			sometimes called "interfaces" and the pattern is known as "interface-based 
 | 
			
		||||
			programming". Again, <code>shared_ptr</code> can be used as the return type of 
 | 
			
		||||
			the factory functions:</p>
 | 
			
		||||
		<pre>// X.hpp:
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
@@ -134,7 +134,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
shared_ptr<X> createX();
 | 
			
		||||
</pre>
 | 
			
		||||
        <pre>-- X.cpp:
 | 
			
		||||
		<pre>-- X.cpp:
 | 
			
		||||
 | 
			
		||||
class X_impl: public X
 | 
			
		||||
{
 | 
			
		||||
@@ -162,18 +162,18 @@ shared_ptr<X> createX()
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>A key property of shared_ptr is that the allocation, construction, deallocation, 
 | 
			
		||||
            and destruction details are captured at the point of construction, inside the 
 | 
			
		||||
            factory function. Note the protected and nonvirtual destructor in the example 
 | 
			
		||||
            above. The client code cannot, and does not need to, delete a pointer to <code>X</code>; 
 | 
			
		||||
            the <code>shared_ptr<X></code> instance returned from <code>createX</code>
 | 
			
		||||
            will correctly call <code>~X_impl</code>.</p>
 | 
			
		||||
        <h2><A name="preventing_delete">Preventing <code>delete px.get()</code></A></h2>
 | 
			
		||||
        <p>It is often desirable to prevent client code from deleting a pointer that is 
 | 
			
		||||
            being managed by <code>shared_ptr</code>. The previous technique showed one 
 | 
			
		||||
            possible approach, using a protected destructor. Another alternative is to use 
 | 
			
		||||
            a private deleter:</p>
 | 
			
		||||
        <pre>class X
 | 
			
		||||
		<p>A key property of shared_ptr is that the allocation, construction, deallocation, 
 | 
			
		||||
			and destruction details are captured at the point of construction, inside the 
 | 
			
		||||
			factory function. Note the protected and nonvirtual destructor in the example 
 | 
			
		||||
			above. The client code cannot, and does not need to, delete a pointer to <code>X</code>; 
 | 
			
		||||
			the <code>shared_ptr<X></code> instance returned from <code>createX</code>
 | 
			
		||||
			will correctly call <code>~X_impl</code>.</p>
 | 
			
		||||
		<h2><A name="preventing_delete">Preventing <code>delete px.get()</code></A></h2>
 | 
			
		||||
		<p>It is often desirable to prevent client code from deleting a pointer that is 
 | 
			
		||||
			being managed by <code>shared_ptr</code>. The previous technique showed one 
 | 
			
		||||
			possible approach, using a protected destructor. Another alternative is to use 
 | 
			
		||||
			a private deleter:</p>
 | 
			
		||||
		<pre>class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -198,48 +198,48 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="array">Using a <code>shared_ptr</code> to hold a pointer to an array</A></h2>
 | 
			
		||||
        <p>A <code>shared_ptr</code> can be used to hold a pointer to an array allocated 
 | 
			
		||||
            with <code>new[]</code>:</p>
 | 
			
		||||
        <pre>shared_ptr<X> px(new X[1], <A href="../utility/checked_delete.html" >checked_array_deleter</A><X>());
 | 
			
		||||
		<h2><A name="array">Using a <code>shared_ptr</code> to hold a pointer to an array</A></h2>
 | 
			
		||||
		<p>A <code>shared_ptr</code> can be used to hold a pointer to an array allocated 
 | 
			
		||||
			with <code>new[]</code>:</p>
 | 
			
		||||
		<pre>shared_ptr<X> px(new X[1], <A href="../utility/checked_delete.html" >checked_array_deleter</A><X>());
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Note, however, that <code><A href="shared_array.htm">shared_array</A></code> is 
 | 
			
		||||
            often preferable, if this is an option. It has an array-specific interface, 
 | 
			
		||||
            without <code>operator*</code> and <code>operator-></code>, and does not 
 | 
			
		||||
            allow pointer conversions.</p>
 | 
			
		||||
        <h2><A name="encapsulation">Encapsulating allocation details, wrapping factory 
 | 
			
		||||
                functions</A></h2>
 | 
			
		||||
        <p><code>shared_ptr</code> can be used in creating C++ wrappers over existing C 
 | 
			
		||||
            style library interfaces that return raw pointers from their factory functions 
 | 
			
		||||
            to encapsulate allocation details. As an example, consider this interface, 
 | 
			
		||||
            where <code>CreateX</code> might allocate <code>X</code> from its own private 
 | 
			
		||||
            heap, <code>~X</code> may be inaccessible, or <code>X</code> may be incomplete:</p>
 | 
			
		||||
        <pre>X * CreateX();
 | 
			
		||||
		<p>Note, however, that <code><A href="shared_array.htm">shared_array</A></code> is 
 | 
			
		||||
			often preferable, if this is an option. It has an array-specific interface, 
 | 
			
		||||
			without <code>operator*</code> and <code>operator-></code>, and does not 
 | 
			
		||||
			allow pointer conversions.</p>
 | 
			
		||||
		<h2><A name="encapsulation">Encapsulating allocation details, wrapping factory 
 | 
			
		||||
				functions</A></h2>
 | 
			
		||||
		<p><code>shared_ptr</code> can be used in creating C++ wrappers over existing C 
 | 
			
		||||
			style library interfaces that return raw pointers from their factory functions 
 | 
			
		||||
			to encapsulate allocation details. As an example, consider this interface, 
 | 
			
		||||
			where <code>CreateX</code> might allocate <code>X</code> from its own private 
 | 
			
		||||
			heap, <code>~X</code> may be inaccessible, or <code>X</code> may be incomplete:</p>
 | 
			
		||||
		<pre>X * CreateX();
 | 
			
		||||
void DestroyX(X *);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>The only way to reliably destroy a pointer returned by <code>CreateX</code> is 
 | 
			
		||||
            to call <code>DestroyX</code>.</p>
 | 
			
		||||
        <P>Here is how a <code>shared_ptr</code>-based wrapper may look like:</P>
 | 
			
		||||
        <pre>shared_ptr<X> createX()
 | 
			
		||||
		<p>The only way to reliably destroy a pointer returned by <code>CreateX</code> is 
 | 
			
		||||
			to call <code>DestroyX</code>.</p>
 | 
			
		||||
		<P>Here is how a <code>shared_ptr</code>-based wrapper may look like:</P>
 | 
			
		||||
		<pre>shared_ptr<X> createX()
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<X> px(CreateX(), DestroyX);
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Client code that calls <code>createX</code> still does not need to know how the 
 | 
			
		||||
            object has been allocated, but now the destruction is automatic.</p>
 | 
			
		||||
        <h2><A name="static">Using a <code>shared_ptr</code> to hold a pointer to a statically 
 | 
			
		||||
                allocated object</A></h2>
 | 
			
		||||
        <p>Sometimes it is desirable to create a <code>shared_ptr</code> to an already 
 | 
			
		||||
            existing object, so that the <code>shared_ptr</code> does not attempt to 
 | 
			
		||||
            destroy the object when there are no more references left. As an example, the 
 | 
			
		||||
            factory function:</p>
 | 
			
		||||
        <pre>shared_ptr<X> createX();
 | 
			
		||||
		<p>Client code that calls <code>createX</code> still does not need to know how the 
 | 
			
		||||
			object has been allocated, but now the destruction is automatic.</p>
 | 
			
		||||
		<h2><A name="static">Using a <code>shared_ptr</code> to hold a pointer to a statically 
 | 
			
		||||
				allocated object</A></h2>
 | 
			
		||||
		<p>Sometimes it is desirable to create a <code>shared_ptr</code> to an already 
 | 
			
		||||
			existing object, so that the <code>shared_ptr</code> does not attempt to 
 | 
			
		||||
			destroy the object when there are no more references left. As an example, the 
 | 
			
		||||
			factory function:</p>
 | 
			
		||||
		<pre>shared_ptr<X> createX();
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>in certain situations may need to return a pointer to a statically allocated <code>X</code>
 | 
			
		||||
            instance.</p>
 | 
			
		||||
        <P>The solution is to use a custom deleter that does nothing:</P>
 | 
			
		||||
        <pre>struct null_deleter
 | 
			
		||||
		<p>in certain situations may need to return a pointer to a statically allocated <code>X</code>
 | 
			
		||||
			instance.</p>
 | 
			
		||||
		<P>The solution is to use a custom deleter that does nothing:</P>
 | 
			
		||||
		<pre>struct null_deleter
 | 
			
		||||
{
 | 
			
		||||
    void operator()(void const *) const
 | 
			
		||||
    {
 | 
			
		||||
@@ -254,33 +254,33 @@ shared_ptr<X> createX()
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>The same technique works for any object known to outlive the pointer.</p>
 | 
			
		||||
        <h2><A name="com">Using a <code>shared_ptr</code> to hold a pointer to a COM Object</A></h2>
 | 
			
		||||
        <p>Background: COM objects have an embedded reference count and two member 
 | 
			
		||||
            functions that manipulate it. <code>AddRef()</code> increments the count. <code>Release()</code>
 | 
			
		||||
            decrements the count and destroys itself when the count drops to zero.</p>
 | 
			
		||||
        <P>It is possible to hold a pointer to a COM object in a <code>shared_ptr</code>:</P>
 | 
			
		||||
        <pre>shared_ptr<IWhatever> make_shared_from_COM(IWhatever * p)
 | 
			
		||||
		<p>The same technique works for any object known to outlive the pointer.</p>
 | 
			
		||||
		<h2><A name="com">Using a <code>shared_ptr</code> to hold a pointer to a COM Object</A></h2>
 | 
			
		||||
		<p>Background: COM objects have an embedded reference count and two member 
 | 
			
		||||
			functions that manipulate it. <code>AddRef()</code> increments the count. <code>Release()</code>
 | 
			
		||||
			decrements the count and destroys itself when the count drops to zero.</p>
 | 
			
		||||
		<P>It is possible to hold a pointer to a COM object in a <code>shared_ptr</code>:</P>
 | 
			
		||||
		<pre>shared_ptr<IWhatever> make_shared_from_COM(IWhatever * p)
 | 
			
		||||
{
 | 
			
		||||
    p->AddRef();
 | 
			
		||||
    shared_ptr<IWhatever> pw(p, <A href="../bind/mem_fn.html" >mem_fn</A>(&IWhatever::Release));
 | 
			
		||||
    return pw;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Note, however, that <code>shared_ptr</code> copies created from <code>pw</code> will 
 | 
			
		||||
            not "register" in the embedded count of the COM object; they will share the 
 | 
			
		||||
            single reference created in <code>make_shared_from_COM</code>. Weak pointers 
 | 
			
		||||
            created from <code>pw</code> will be invalidated when the last <code>shared_ptr</code>
 | 
			
		||||
            is destroyed, regardless of whether the COM object itself is still alive.</p>
 | 
			
		||||
        <P>As <A href="../bind/mem_fn.html#Q3">explained</A> in the <code>mem_fn</code> documentation, 
 | 
			
		||||
            you need to <A href="../bind/mem_fn.html#stdcall">#define 
 | 
			
		||||
                BOOST_MEM_FN_ENABLE_STDCALL</A> first.</P>
 | 
			
		||||
        <h2><A name="intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object 
 | 
			
		||||
                with an embedded reference count</A></h2>
 | 
			
		||||
        <p>This is a generalization of the above technique. The example assumes that the 
 | 
			
		||||
            object implements the two functions required by <code><A href="intrusive_ptr.html">intrusive_ptr</A></code>,
 | 
			
		||||
            <code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code>:</p>
 | 
			
		||||
        <pre>template<class T> struct intrusive_deleter
 | 
			
		||||
		<p>Note, however, that <code>shared_ptr</code> copies created from <code>pw</code> will 
 | 
			
		||||
			not "register" in the embedded count of the COM object; they will share the 
 | 
			
		||||
			single reference created in <code>make_shared_from_COM</code>. Weak pointers 
 | 
			
		||||
			created from <code>pw</code> will be invalidated when the last <code>shared_ptr</code>
 | 
			
		||||
			is destroyed, regardless of whether the COM object itself is still alive.</p>
 | 
			
		||||
		<P>As <A href="../bind/mem_fn.html#Q3">explained</A> in the <code>mem_fn</code> documentation, 
 | 
			
		||||
			you need to <A href="../bind/mem_fn.html#stdcall">#define 
 | 
			
		||||
				BOOST_MEM_FN_ENABLE_STDCALL</A> first.</P>
 | 
			
		||||
		<h2><A name="intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object 
 | 
			
		||||
				with an embedded reference count</A></h2>
 | 
			
		||||
		<p>This is a generalization of the above technique. The example assumes that the 
 | 
			
		||||
			object implements the two functions required by <code><A href="intrusive_ptr.html">intrusive_ptr</A></code>,
 | 
			
		||||
			<code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code>:</p>
 | 
			
		||||
		<pre>template<class T> struct intrusive_deleter
 | 
			
		||||
{
 | 
			
		||||
    void operator()(T * p)
 | 
			
		||||
    {
 | 
			
		||||
@@ -295,15 +295,15 @@ shared_ptr<X> make_shared_from_intrusive(X * p)
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="another_sp">Using a <code>shared_ptr</code> to hold another shared 
 | 
			
		||||
                ownership smart pointer</A></h2>
 | 
			
		||||
        <p>One of the design goals of <code>shared_ptr</code> is to be used in library 
 | 
			
		||||
            interfaces. It is possible to encounter a situation where a library takes a <code>shared_ptr</code>
 | 
			
		||||
            argument, but the object at hand is being managed by a different reference 
 | 
			
		||||
            counted or linked smart pointer.</p>
 | 
			
		||||
        <P>It is possible to exploit <code>shared_ptr</code>'s custom deleter feature to 
 | 
			
		||||
            wrap this existing smart pointer behind a <code>shared_ptr</code> facade:</P>
 | 
			
		||||
        <pre>template<class P> struct smart_pointer_deleter
 | 
			
		||||
		<h2><A name="another_sp">Using a <code>shared_ptr</code> to hold another shared 
 | 
			
		||||
				ownership smart pointer</A></h2>
 | 
			
		||||
		<p>One of the design goals of <code>shared_ptr</code> is to be used in library 
 | 
			
		||||
			interfaces. It is possible to encounter a situation where a library takes a <code>shared_ptr</code>
 | 
			
		||||
			argument, but the object at hand is being managed by a different reference 
 | 
			
		||||
			counted or linked smart pointer.</p>
 | 
			
		||||
		<P>It is possible to exploit <code>shared_ptr</code>'s custom deleter feature to 
 | 
			
		||||
			wrap this existing smart pointer behind a <code>shared_ptr</code> facade:</P>
 | 
			
		||||
		<pre>template<class P> struct smart_pointer_deleter
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -332,17 +332,17 @@ shared_ptr<X> make_shared_from_another(another_ptr<X> qx)
 | 
			
		||||
    return px;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>One subtle point is that deleters are not allowed to throw exceptions, and the 
 | 
			
		||||
            above example as written assumes that <code>p_.reset()</code> doesn't throw. If 
 | 
			
		||||
            this is not the case, <code>p_.reset()</code> should be wrapped in a <code>try {} 
 | 
			
		||||
                catch(...) {}</code> block that ignores exceptions. In the (usually 
 | 
			
		||||
            unlikely) event when an exception is thrown and ignored, <code>p_</code> will 
 | 
			
		||||
            be released when the lifetime of the deleter ends. This happens when all 
 | 
			
		||||
            references, including weak pointers, are destroyed or reset.</p>
 | 
			
		||||
        <P>Another twist is that it is possible, given the above <code>shared_ptr</code> instance, 
 | 
			
		||||
            to recover the original smart pointer, using <code><A href="shared_ptr.htm#get_deleter">
 | 
			
		||||
                    get_deleter</A></code>:</P>
 | 
			
		||||
        <pre>void extract_another_from_shared(shared_ptr<X> px)
 | 
			
		||||
		<p>One subtle point is that deleters are not allowed to throw exceptions, and the 
 | 
			
		||||
			above example as written assumes that <code>p_.reset()</code> doesn't throw. If 
 | 
			
		||||
			this is not the case, <code>p_.reset()</code> should be wrapped in a <code>try {} 
 | 
			
		||||
				catch(...) {}</code> block that ignores exceptions. In the (usually 
 | 
			
		||||
			unlikely) event when an exception is thrown and ignored, <code>p_</code> will 
 | 
			
		||||
			be released when the lifetime of the deleter ends. This happens when all 
 | 
			
		||||
			references, including weak pointers, are destroyed or reset.</p>
 | 
			
		||||
		<P>Another twist is that it is possible, given the above <code>shared_ptr</code> instance, 
 | 
			
		||||
			to recover the original smart pointer, using <code><A href="shared_ptr.htm#get_deleter">
 | 
			
		||||
					get_deleter</A></code>:</P>
 | 
			
		||||
		<pre>void extract_another_from_shared(shared_ptr<X> px)
 | 
			
		||||
{
 | 
			
		||||
    typedef smart_pointer_deleter< another_ptr<X> > deleter;
 | 
			
		||||
 | 
			
		||||
@@ -356,37 +356,37 @@ shared_ptr<X> make_shared_from_another(another_ptr<X> qx)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A></h2>
 | 
			
		||||
        <p>Sometimes it is necessary to obtain a <code>shared_ptr</code> given a raw 
 | 
			
		||||
            pointer to an object that is already managed by another <code>shared_ptr</code> 
 | 
			
		||||
            instance. Example:</p>
 | 
			
		||||
        <pre>void f(X * p)
 | 
			
		||||
		<h2><A name="from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A></h2>
 | 
			
		||||
		<p>Sometimes it is necessary to obtain a <code>shared_ptr</code> given a raw 
 | 
			
		||||
			pointer to an object that is already managed by another <code>shared_ptr</code> 
 | 
			
		||||
			instance. Example:</p>
 | 
			
		||||
		<pre>void f(X * p)
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<X> px(<i>???</i>);
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Inside <code>f</code>, we'd like to create a <code>shared_ptr</code> to <code>*p</code>.</p>
 | 
			
		||||
        <P>In the general case, this problem has no solution. One approach is to modify <code>f</code>
 | 
			
		||||
            to take a <code>shared_ptr</code>, if possible:</P>
 | 
			
		||||
        <pre>void f(shared_ptr<X> px);
 | 
			
		||||
		<p>Inside <code>f</code>, we'd like to create a <code>shared_ptr</code> to <code>*p</code>.</p>
 | 
			
		||||
		<P>In the general case, this problem has no solution. One approach is to modify <code>f</code>
 | 
			
		||||
			to take a <code>shared_ptr</code>, if possible:</P>
 | 
			
		||||
		<pre>void f(shared_ptr<X> px);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>The same transformation can be used for nonvirtual member functions, to convert 
 | 
			
		||||
            the implicit <code>this</code>:</p>
 | 
			
		||||
        <pre>void X::f(int m);
 | 
			
		||||
		<p>The same transformation can be used for nonvirtual member functions, to convert 
 | 
			
		||||
			the implicit <code>this</code>:</p>
 | 
			
		||||
		<pre>void X::f(int m);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>would become a free function with a <code>shared_ptr</code> first argument:</p>
 | 
			
		||||
        <pre>void f(shared_ptr<X> this_, int m);
 | 
			
		||||
		<p>would become a free function with a <code>shared_ptr</code> first argument:</p>
 | 
			
		||||
		<pre>void f(shared_ptr<X> this_, int m);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>If <code>f</code> cannot be changed, but <code>X</code> uses intrusive counting, 
 | 
			
		||||
            use <code><A href="#intrusive">make_shared_from_intrusive</A></code> described 
 | 
			
		||||
            above. Or, if it's known that the <code>shared_ptr</code> created in <code>f</code>
 | 
			
		||||
            will never outlive the object, use <A href="#static">a null deleter</A>.</p>
 | 
			
		||||
        <h2><A name="in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>) 
 | 
			
		||||
                to <code>this</code> in a constructor</A></h2>
 | 
			
		||||
        <p>Some designs require objects to register themselves on construction with a 
 | 
			
		||||
            central authority. When the registration routines take a shared_ptr, this leads 
 | 
			
		||||
            to the question how could a constructor obtain a shared_ptr to this:</p>
 | 
			
		||||
        <pre>class X
 | 
			
		||||
		<p>If <code>f</code> cannot be changed, but <code>X</code> uses intrusive counting, 
 | 
			
		||||
			use <code><A href="#intrusive">make_shared_from_intrusive</A></code> described 
 | 
			
		||||
			above. Or, if it's known that the <code>shared_ptr</code> created in <code>f</code>
 | 
			
		||||
			will never outlive the object, use <A href="#static">a null deleter</A>.</p>
 | 
			
		||||
		<h2><A name="in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>) 
 | 
			
		||||
				to <code>this</code> in a constructor</A></h2>
 | 
			
		||||
		<p>Some designs require objects to register themselves on construction with a 
 | 
			
		||||
			central authority. When the registration routines take a shared_ptr, this leads 
 | 
			
		||||
			to the question how could a constructor obtain a shared_ptr to this:</p>
 | 
			
		||||
		<pre>class X
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
@@ -396,19 +396,19 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>In the general case, the problem cannot be solved. The <code>X</code> instance 
 | 
			
		||||
            being constructed can be an automatic variable or a static variable; it can be 
 | 
			
		||||
            created on the heap:</p>
 | 
			
		||||
        <pre>shared_ptr<X> px(new X);</pre>
 | 
			
		||||
        <P>but at construction time, <code>px</code> does not exist yet, and it is 
 | 
			
		||||
            impossible to create another <code>shared_ptr</code> instance that shares 
 | 
			
		||||
            ownership with it.</P>
 | 
			
		||||
        <P>Depending on context, if the inner <code>shared_ptr</code> <code>this_</code> doesn't 
 | 
			
		||||
            need to keep the object alive, use a <code>null_deleter</code> as explained <A href="#static">
 | 
			
		||||
                here</A> and <A href="#weak_without_shared">here</A>. If <code>X</code> is 
 | 
			
		||||
            supposed to always live on the heap, and be managed by a <code>shared_ptr</code>, 
 | 
			
		||||
            use a static factory function:</P>
 | 
			
		||||
        <pre>class X
 | 
			
		||||
		<p>In the general case, the problem cannot be solved. The <code>X</code> instance 
 | 
			
		||||
			being constructed can be an automatic variable or a static variable; it can be 
 | 
			
		||||
			created on the heap:</p>
 | 
			
		||||
		<pre>shared_ptr<X> px(new X);</pre>
 | 
			
		||||
		<P>but at construction time, <code>px</code> does not exist yet, and it is 
 | 
			
		||||
			impossible to create another <code>shared_ptr</code> instance that shares 
 | 
			
		||||
			ownership with it.</P>
 | 
			
		||||
		<P>Depending on context, if the inner <code>shared_ptr</code> <code>this_</code> doesn't 
 | 
			
		||||
			need to keep the object alive, use a <code>null_deleter</code> as explained <A href="#static">
 | 
			
		||||
				here</A> and <A href="#weak_without_shared">here</A>. If <code>X</code> is 
 | 
			
		||||
			supposed to always live on the heap, and be managed by a <code>shared_ptr</code>, 
 | 
			
		||||
			use a static factory function:</P>
 | 
			
		||||
		<pre>class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -424,13 +424,13 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A></h2>
 | 
			
		||||
        <p>Sometimes it is needed to obtain a <code>shared_ptr</code> from <code>this</code>
 | 
			
		||||
            in a virtual member function under the assumption that <code>this</code> is 
 | 
			
		||||
            already managed by a <code>shared_ptr</code>. The transformations <A href="#from_raw">
 | 
			
		||||
                described in the previous technique</A> cannot be applied.</p>
 | 
			
		||||
        <P>A typical example:</P>
 | 
			
		||||
        <pre>class X
 | 
			
		||||
		<h2><A name="from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A></h2>
 | 
			
		||||
		<p>Sometimes it is needed to obtain a <code>shared_ptr</code> from <code>this</code>
 | 
			
		||||
			in a virtual member function under the assumption that <code>this</code> is 
 | 
			
		||||
			already managed by a <code>shared_ptr</code>. The transformations <A href="#from_raw">
 | 
			
		||||
				described in the previous technique</A> cannot be applied.</p>
 | 
			
		||||
		<P>A typical example:</P>
 | 
			
		||||
		<pre>class X
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
@@ -469,8 +469,8 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>The solution is to keep a weak pointer to <code>this</code> as a member in <code>impl</code>:</p>
 | 
			
		||||
        <pre>class impl: public X, public Y
 | 
			
		||||
		<p>The solution is to keep a weak pointer to <code>this</code> as a member in <code>impl</code>:</p>
 | 
			
		||||
		<pre>class impl: public X, public Y
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -499,10 +499,10 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>The library now includes a helper class template <code><A href="enable_shared_from_this.html">
 | 
			
		||||
                    enable_shared_from_this</A></code> that can be used to encapsulate the 
 | 
			
		||||
            solution:</p>
 | 
			
		||||
        <pre>class impl: public X, public Y, public enable_shared_from_this<impl>
 | 
			
		||||
		<p>The library now includes a helper class template <code><A href="enable_shared_from_this.html">
 | 
			
		||||
					enable_shared_from_this</A></code> that can be used to encapsulate the 
 | 
			
		||||
			solution:</p>
 | 
			
		||||
		<pre>class impl: public X, public Y, public enable_shared_from_this<impl>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
@@ -519,19 +519,19 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member 
 | 
			
		||||
            in <code><A href="enable_shared_from_this.html">enable_shared_from_this</A></code>. 
 | 
			
		||||
            Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p>
 | 
			
		||||
        <h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2>
 | 
			
		||||
        <p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
 | 
			
		||||
                incomplete class technique</A> described above. An example:</p>
 | 
			
		||||
        <pre>typedef void * HANDLE;
 | 
			
		||||
		<p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member 
 | 
			
		||||
			in <code><A href="enable_shared_from_this.html">enable_shared_from_this</A></code>. 
 | 
			
		||||
			Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p>
 | 
			
		||||
		<h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2>
 | 
			
		||||
		<p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
 | 
			
		||||
				incomplete class technique</A> described above. An example:</p>
 | 
			
		||||
		<pre>typedef void * HANDLE;
 | 
			
		||||
HANDLE CreateProcess();
 | 
			
		||||
void CloseHandle(HANDLE);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Instead of a raw pointer, it is possible to use <code>shared_ptr</code> as the 
 | 
			
		||||
            handle and get reference counting and automatic resource management for free:</p>
 | 
			
		||||
        <pre>typedef shared_ptr<void> handle;
 | 
			
		||||
		<p>Instead of a raw pointer, it is possible to use <code>shared_ptr</code> as the 
 | 
			
		||||
			handle and get reference counting and automatic resource management for free:</p>
 | 
			
		||||
		<pre>typedef shared_ptr<void> handle;
 | 
			
		||||
 | 
			
		||||
handle createProcess()
 | 
			
		||||
{
 | 
			
		||||
@@ -539,42 +539,42 @@ handle createProcess()
 | 
			
		||||
    return pv;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="on_block_exit">Using <code>shared_ptr</code> to execute code on block exit</A></h2>
 | 
			
		||||
        <p><code>shared_ptr<void></code> can automatically execute cleanup code when 
 | 
			
		||||
            control leaves a scope.</p>
 | 
			
		||||
        <UL>
 | 
			
		||||
            <LI>
 | 
			
		||||
                Executing <code>f(p)</code>, where <code>p</code> is a pointer:</LI></UL>
 | 
			
		||||
        <pre>    shared_ptr<void> guard(p, f);
 | 
			
		||||
		<h2><A name="on_block_exit">Using <code>shared_ptr</code> to execute code on block exit</A></h2>
 | 
			
		||||
		<p><code>shared_ptr<void></code> can automatically execute cleanup code when 
 | 
			
		||||
			control leaves a scope.</p>
 | 
			
		||||
		<UL>
 | 
			
		||||
			<LI>
 | 
			
		||||
				Executing <code>f(p)</code>, where <code>p</code> is a pointer:</LI></UL>
 | 
			
		||||
		<pre>    shared_ptr<void> guard(p, f);
 | 
			
		||||
</pre>
 | 
			
		||||
        <UL>
 | 
			
		||||
            <LI>
 | 
			
		||||
                Executing arbitrary code: <code>f(x, y)</code>:</LI></UL>
 | 
			
		||||
        <pre>    shared_ptr<void> guard(static_cast<void*>(0), <A href="../bind/bind.html" >bind</A>(f, x, y));
 | 
			
		||||
		<UL>
 | 
			
		||||
			<LI>
 | 
			
		||||
				Executing arbitrary code: <code>f(x, y)</code>:</LI></UL>
 | 
			
		||||
		<pre>    shared_ptr<void> guard(static_cast<void*>(0), <A href="../bind/bind.html" >bind</A>(f, x, y));
 | 
			
		||||
</pre>
 | 
			
		||||
        <P>For a more thorough treatment, see the article "Simplify Your Exception-Safe 
 | 
			
		||||
            Code" by Andrei Alexandrescu and Petru Marginean, available online at <A href="http://www.cuj.com/experts/1812/alexandr.htm?topic=experts">
 | 
			
		||||
                http://www.cuj.com/experts/1812/alexandr.htm?topic=experts</A>.</P>
 | 
			
		||||
        <h2><A name="pvoid">Using <code>shared_ptr<void></code> to hold an arbitrary 
 | 
			
		||||
                object</A></h2>
 | 
			
		||||
        <p><code>shared_ptr<void></code> can act as a generic object pointer similar 
 | 
			
		||||
            to <code>void*</code>. When a <code>shared_ptr<void></code> instance 
 | 
			
		||||
            constructed as:</p>
 | 
			
		||||
        <pre>    shared_ptr<void> pv(new X);
 | 
			
		||||
		<P>For a more thorough treatment, see the article "Simplify Your Exception-Safe 
 | 
			
		||||
			Code" by Andrei Alexandrescu and Petru Marginean, available online at <A href="http://www.cuj.com/experts/1812/alexandr.htm?topic=experts">
 | 
			
		||||
				http://www.cuj.com/experts/1812/alexandr.htm?topic=experts</A>.</P>
 | 
			
		||||
		<h2><A name="pvoid">Using <code>shared_ptr<void></code> to hold an arbitrary 
 | 
			
		||||
				object</A></h2>
 | 
			
		||||
		<p><code>shared_ptr<void></code> can act as a generic object pointer similar 
 | 
			
		||||
			to <code>void*</code>. When a <code>shared_ptr<void></code> instance 
 | 
			
		||||
			constructed as:</p>
 | 
			
		||||
		<pre>    shared_ptr<void> pv(new X);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>is destroyed, it will correctly dispose of the <code>X</code> object by 
 | 
			
		||||
            executing <code>~X</code>.</p>
 | 
			
		||||
        <p>This propery can be used in much the same manner as a raw <code>void*</code> is 
 | 
			
		||||
            used to temporarily strip type information from an object pointer. A <code>shared_ptr<void></code>
 | 
			
		||||
            can later be cast back to the correct type by using <code><A href="shared_ptr.htm#static_pointer_cast">
 | 
			
		||||
                    static_pointer_cast</A></code>.</p>
 | 
			
		||||
        <h2><A name="extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
 | 
			
		||||
                instances</A></h2>
 | 
			
		||||
        <p><code>shared_ptr</code> and <code>weak_ptr</code> support <code>operator<</code>
 | 
			
		||||
            comparisons required by standard associative containers such as <code>std::map</code>. 
 | 
			
		||||
            This can be used to non-intrusively associate arbitrary data with objects 
 | 
			
		||||
            managed by <code>shared_ptr</code>:</p>
 | 
			
		||||
        <pre>typedef int Data;
 | 
			
		||||
		<p>is destroyed, it will correctly dispose of the <code>X</code> object by 
 | 
			
		||||
			executing <code>~X</code>.</p>
 | 
			
		||||
		<p>This propery can be used in much the same manner as a raw <code>void*</code> is 
 | 
			
		||||
			used to temporarily strip type information from an object pointer. A <code>shared_ptr<void></code>
 | 
			
		||||
			can later be cast back to the correct type by using <code><A href="shared_ptr.htm#static_pointer_cast">
 | 
			
		||||
					static_pointer_cast</A></code>.</p>
 | 
			
		||||
		<h2><A name="extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
 | 
			
		||||
				instances</A></h2>
 | 
			
		||||
		<p><code>shared_ptr</code> and <code>weak_ptr</code> support <code>operator<</code>
 | 
			
		||||
			comparisons required by standard associative containers such as <code>std::map</code>. 
 | 
			
		||||
			This can be used to non-intrusively associate arbitrary data with objects 
 | 
			
		||||
			managed by <code>shared_ptr</code>:</p>
 | 
			
		||||
		<pre>typedef int Data;
 | 
			
		||||
 | 
			
		||||
std::map< shared_ptr<void>, Data > userData;
 | 
			
		||||
// or std::map< weak_ptr<void>, Data > userData; to not affect the lifetime
 | 
			
		||||
@@ -585,11 +585,11 @@ shared_ptr<int> pi(new int(3));
 | 
			
		||||
userData[px] = 42;
 | 
			
		||||
userData[pi] = 91;
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A></h2>
 | 
			
		||||
        <p>Sometimes it's necessary to return a mutex lock from a function, and a 
 | 
			
		||||
            noncopyable lock cannot be returned by value. It is possible to use <code>shared_ptr</code>
 | 
			
		||||
            as a mutex lock:</p>
 | 
			
		||||
        <pre>class mutex
 | 
			
		||||
		<h2><A name="as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A></h2>
 | 
			
		||||
		<p>Sometimes it's necessary to return a mutex lock from a function, and a 
 | 
			
		||||
			noncopyable lock cannot be returned by value. It is possible to use <code>shared_ptr</code>
 | 
			
		||||
			as a mutex lock:</p>
 | 
			
		||||
		<pre>class mutex
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
@@ -603,9 +603,9 @@ shared_ptr<mutex> lock(mutex & m)
 | 
			
		||||
    return shared_ptr<mutex>(&m, mem_fn(&mutex::unlock));
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Better yet, the <code>shared_ptr</code> instance acting as a lock can be 
 | 
			
		||||
            encapsulated in a dedicated <code>shared_lock</code> class:</p>
 | 
			
		||||
        <pre>class shared_lock
 | 
			
		||||
		<p>Better yet, the <code>shared_ptr</code> instance acting as a lock can be 
 | 
			
		||||
			encapsulated in a dedicated <code>shared_lock</code> class:</p>
 | 
			
		||||
		<pre>class shared_lock
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -616,17 +616,17 @@ public:
 | 
			
		||||
    template<class Mutex> explicit shared_lock(Mutex & m): pv((m.lock(), &m), mem_fn(&Mutex::unlock)) {}
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <p><code>shared_lock</code> can now be used as:</p>
 | 
			
		||||
        <pre>    shared_lock lock(m);
 | 
			
		||||
		<p><code>shared_lock</code> can now be used as:</p>
 | 
			
		||||
		<pre>    shared_lock lock(m);
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Note that <code>shared_lock</code> is not templated on the mutex type, thanks to <code>
 | 
			
		||||
                shared_ptr<void></code>'s ability to hide type information.</p>
 | 
			
		||||
        <h2><A name="wrapper">Using <code>shared_ptr</code> to wrap member function calls</A></h2>
 | 
			
		||||
        <p><code>shared_ptr</code> implements the ownership semantics required from the <code>Wrap</code>/<code>CallProxy</code>
 | 
			
		||||
            scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function 
 | 
			
		||||
            Calls" (available online at <A href="http://www.stroustrup.com/wrapper.pdf">http://www.stroustrup.com/wrapper.pdf</A>). 
 | 
			
		||||
            An implementation is given below:</p>
 | 
			
		||||
        <pre>template<class T> class pointer
 | 
			
		||||
		<p>Note that <code>shared_lock</code> is not templated on the mutex type, thanks to <code>
 | 
			
		||||
				shared_ptr<void></code>'s ability to hide type information.</p>
 | 
			
		||||
		<h2><A name="wrapper">Using <code>shared_ptr</code> to wrap member function calls</A></h2>
 | 
			
		||||
		<p><code>shared_ptr</code> implements the ownership semantics required from the <code>Wrap</code>/<code>CallProxy</code>
 | 
			
		||||
			scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function 
 | 
			
		||||
			Calls" (available online at <A href="http://www.research.att.com/~bs/wrapper.pdf">http://www.research.att.com/~bs/wrapper.pdf</A>). 
 | 
			
		||||
			An implementation is given below:</p>
 | 
			
		||||
		<pre>template<class T> class pointer
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -669,10 +669,10 @@ int main()
 | 
			
		||||
    px->g();
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="delayed">Delayed deallocation</A></h2>
 | 
			
		||||
        <p>In some situations, a single <code>px.reset()</code> can trigger an expensive 
 | 
			
		||||
            deallocation in a performance-critical region:</p>
 | 
			
		||||
        <pre>class X; // ~X is expensive
 | 
			
		||||
		<h2><A name="delayed">Delayed deallocation</A></h2>
 | 
			
		||||
		<p>In some situations, a single <code>px.reset()</code> can trigger an expensive 
 | 
			
		||||
			deallocation in a performance-critical region:</p>
 | 
			
		||||
		<pre>class X; // ~X is expensive
 | 
			
		||||
 | 
			
		||||
class Y
 | 
			
		||||
{
 | 
			
		||||
@@ -686,10 +686,10 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>The solution is to postpone the potential deallocation by moving <code>px</code> 
 | 
			
		||||
            to a dedicated free list that can be periodically emptied when performance and 
 | 
			
		||||
            response times are not an issue:</p>
 | 
			
		||||
        <pre>vector< shared_ptr<void> > free_list;
 | 
			
		||||
		<p>The solution is to postpone the potential deallocation by moving <code>px</code> 
 | 
			
		||||
			to a dedicated free list that can be periodically emptied when performance and 
 | 
			
		||||
			response times are not an issue:</p>
 | 
			
		||||
		<pre>vector< shared_ptr<void> > free_list;
 | 
			
		||||
 | 
			
		||||
class Y
 | 
			
		||||
{
 | 
			
		||||
@@ -706,9 +706,9 @@ public:
 | 
			
		||||
 | 
			
		||||
// periodically invoke free_list.clear() when convenient
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>Another variation is to move the free list logic to the construction point by 
 | 
			
		||||
            using a delayed deleter:</p>
 | 
			
		||||
        <pre>struct delayed_deleter
 | 
			
		||||
		<p>Another variation is to move the free list logic to the construction point by 
 | 
			
		||||
			using a delayed deleter:</p>
 | 
			
		||||
		<pre>struct delayed_deleter
 | 
			
		||||
{
 | 
			
		||||
    template<class T> void operator()(T * p)
 | 
			
		||||
    {
 | 
			
		||||
@@ -723,9 +723,9 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <h2><A name="weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A></h2>
 | 
			
		||||
        <p>Make the object hold a <code>shared_ptr</code> to itself, using a <code>null_deleter</code>:</p>
 | 
			
		||||
        <pre>class X
 | 
			
		||||
		<h2><A name="weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A></h2>
 | 
			
		||||
		<p>Make the object hold a <code>shared_ptr</code> to itself, using a <code>null_deleter</code>:</p>
 | 
			
		||||
		<pre>class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
@@ -748,18 +748,18 @@ public:
 | 
			
		||||
 | 
			
		||||
    X & operator=(X const & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        i_ = rhs.i_;
 | 
			
		||||
	    i_ = rhs.i_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    weak_ptr<X> get_weak_ptr() const { return this_; }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
        <p>When the object's lifetime ends, <code>X::this_</code> will be destroyed, and 
 | 
			
		||||
            all weak pointers will automatically expire.</p>
 | 
			
		||||
        <hr>
 | 
			
		||||
        <p>$Date$</p>
 | 
			
		||||
        <p><small>Copyright © 2003 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>
 | 
			
		||||
		<p>When the object's lifetime ends, <code>X::this_</code> will be destroyed, and 
 | 
			
		||||
			all weak pointers will automatically expire.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>$Date$</p>
 | 
			
		||||
		<p><small>Copyright <EFBFBD> 2003 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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										120
									
								
								test/Jamfile.v2
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								test/Jamfile.v2
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
#  Boost.SmartPtr Library test Jamfile
 | 
			
		||||
#
 | 
			
		||||
#  Copyright (c) 2003-2013 Peter Dimov
 | 
			
		||||
#  Copyright (c) 2003-2007 Peter Dimov
 | 
			
		||||
#  Copyright (c) 2003 Dave Abrahams
 | 
			
		||||
#
 | 
			
		||||
#  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
@@ -21,7 +21,6 @@ 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 ]
 | 
			
		||||
@@ -47,7 +46,7 @@ import testing ;
 | 
			
		||||
          [ run spinlock_pool_test.cpp ]
 | 
			
		||||
          [ run make_shared_test.cpp ]
 | 
			
		||||
          [ run make_shared_perfect_forwarding_test.cpp ]
 | 
			
		||||
          [ run shared_ptr_convertible_test.cpp ]
 | 
			
		||||
          [ run sp_convertible_test.cpp ]
 | 
			
		||||
          [ run wp_convertible_test.cpp ]
 | 
			
		||||
          [ run ip_convertible_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_test.cpp ]
 | 
			
		||||
@@ -60,124 +59,11 @@ 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 ]
 | 
			
		||||
          [ compile-fail auto_ptr_lv_fail.cpp ]
 | 
			
		||||
          [ run atomic_count_test2.cpp ]
 | 
			
		||||
          [ run sp_typeinfo_test.cpp ]
 | 
			
		||||
          [ compile make_shared_fp_test.cpp ]
 | 
			
		||||
          [ run sp_hash_test.cpp ]
 | 
			
		||||
          [ run get_deleter_array_test.cpp ]
 | 
			
		||||
          [ run ip_hash_test.cpp ]
 | 
			
		||||
          [ run owner_less_test.cpp ]
 | 
			
		||||
          [ run sp_unique_ptr_test.cpp ]
 | 
			
		||||
          [ run sp_array_test.cpp ]
 | 
			
		||||
          [ compile sp_array_cv_test.cpp ]
 | 
			
		||||
          [ run sp_convertible_test.cpp ]
 | 
			
		||||
          [ run sp_array_n_test.cpp ]
 | 
			
		||||
          [ run sp_array_cast_test.cpp ]
 | 
			
		||||
          [ run sp_zero_compare_test.cpp ]
 | 
			
		||||
          [ run sp_nullptr_test.cpp ]
 | 
			
		||||
          [ run sa_nullptr_test.cpp ]
 | 
			
		||||
          [ run shared_ptr_alloc3_test.cpp ]
 | 
			
		||||
          [ run shared_ptr_alloc11_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_alloc11_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_construct11_test.cpp ]
 | 
			
		||||
          [ run sp_interlocked_test.cpp ]
 | 
			
		||||
 | 
			
		||||
          [ compile-fail array_fail_spa_sp_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_spa_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_spa_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wp_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_wpa_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wpa_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wp_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wp_wpa_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wpa_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_ap_spa_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_upa_sp_c.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_up_spa_c.cpp ]
 | 
			
		||||
 | 
			
		||||
          [ compile-fail array_fail_spa_sp_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_spa_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_spa_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wp_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_wpa_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wpa_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wp_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wp_wpa_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wpa_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_ap_spa_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_upa_sp_mc.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_up_spa_mc.cpp ]
 | 
			
		||||
 | 
			
		||||
          [ compile-fail array_fail_spa_sp_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_spa_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_spa_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wp_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_wpa_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wpa_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wp_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wp_wpa_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wpa_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_ap_spa_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_upa_sp_a.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_up_spa_a.cpp ]
 | 
			
		||||
 | 
			
		||||
          [ compile-fail array_fail_spa_sp_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_spa_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_spa_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wp_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_sp_wpa_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_spa_wpa_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wp_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wp_wpa_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_wpa_wpa_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_ap_spa_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_upa_sp_ma.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_up_spa_ma.cpp ]
 | 
			
		||||
 | 
			
		||||
          [ compile-fail array_fail_dereference.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_member_access.cpp ]
 | 
			
		||||
          [ compile-fail array_fail_array_access.cpp ]
 | 
			
		||||
 | 
			
		||||
          [ run make_shared_array_test.cpp ]
 | 
			
		||||
          [ run make_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
 | 
			
		||||
          [ run make_shared_array_throws_test.cpp ]
 | 
			
		||||
          [ run make_shared_array_esft_test.cpp ]
 | 
			
		||||
          [ run make_shared_array_noinit_test.cpp ]
 | 
			
		||||
          [ run make_shared_array_value_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_array_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
 | 
			
		||||
          [ run allocate_shared_array_throws_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_array_esft_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_array_noinit_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_array_value_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_array_construct_test.cpp ]
 | 
			
		||||
 | 
			
		||||
          [ run make_unique_test.cpp ]
 | 
			
		||||
          [ run make_unique_args_test.cpp ]
 | 
			
		||||
          [ run make_unique_value_test.cpp ]
 | 
			
		||||
          [ run make_unique_noinit_test.cpp ]
 | 
			
		||||
          [ run make_unique_throws_test.cpp ]
 | 
			
		||||
          [ 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 ]
 | 
			
		||||
        ;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,241 +0,0 @@
 | 
			
		||||
// allocate_shared_alloc11_test.cpp
 | 
			
		||||
//
 | 
			
		||||
// allocate_shared with a minimal C++11 allocator
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2007-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/detail/lightweight_test.hpp>
 | 
			
		||||
#include <boost/make_shared.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
template< class T > class cxx11_allocator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T value_type;
 | 
			
		||||
 | 
			
		||||
    cxx11_allocator()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class Y > cxx11_allocator( cxx11_allocator<Y> const & )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * allocate( std::size_t n )
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast< T* >( ::operator new( n * sizeof( T ) ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void deallocate( T * p, std::size_t n )
 | 
			
		||||
    {
 | 
			
		||||
        ::operator delete( p );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const & );
 | 
			
		||||
    X & operator=( X const & );
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t n )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ERROR( "private X::new called" );
 | 
			
		||||
        return ::operator new( n );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete( void * p )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ERROR( "private X::delete called" );
 | 
			
		||||
        ::operator delete( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static int instances;
 | 
			
		||||
 | 
			
		||||
    int v;
 | 
			
		||||
 | 
			
		||||
    explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~X()
 | 
			
		||||
    {
 | 
			
		||||
        --instances;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int X::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< int > pi = boost::allocate_shared< int >( cxx11_allocator<int>() );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( *pi == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< int > pi = boost::allocate_shared< int >( cxx11_allocator<int>(), 5 );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( *pi == 5 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>() );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 0 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // !defined( BOOST_NO_CXX11_ALLOCATOR )
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,160 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
 | 
			
		||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class creator {
 | 
			
		||||
public:
 | 
			
		||||
    typedef T value_type;
 | 
			
		||||
 | 
			
		||||
    creator() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename U>
 | 
			
		||||
    creator(const creator<U>&) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T* allocate(std::size_t size) {
 | 
			
		||||
        void* p1 = ::operator new(size * sizeof(T));
 | 
			
		||||
        return static_cast<T*>(p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void deallocate(T* memory, std::size_t) {
 | 
			
		||||
        void* p1 = memory;
 | 
			
		||||
        ::operator delete(p1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename U>
 | 
			
		||||
    void construct(U* memory) {
 | 
			
		||||
        void* p1 = memory;
 | 
			
		||||
        ::new(p1) U();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename U>
 | 
			
		||||
    void destroy(U* memory) {
 | 
			
		||||
        memory->~U();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class type {
 | 
			
		||||
    friend class creator<type>;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    static unsigned int instances;
 | 
			
		||||
    static const type object;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    explicit type() {
 | 
			
		||||
        instances++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type(const type&) {
 | 
			
		||||
        instances++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~type() {
 | 
			
		||||
        instances--;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned int type::instances;
 | 
			
		||||
const type type::object;
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(creator<void>(), 3);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[3]> a1 = boost::allocate_shared<type[3]>(creator<void>());
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[][2]> a1 = boost::allocate_shared<type[][2]>(creator<void>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 5);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared<type[2][2]>(creator<void>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 5);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(creator<void>(), 3);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[3]> a1 = boost::allocate_shared<const type[3]>(creator<void>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[][2]> a1 = boost::allocate_shared<const type[][2]>(creator<void>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 5);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 1);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[2][2]> a1 = boost::allocate_shared<const type[2][2]>(creator<void>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 5);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
#include <boost/smart_ptr/enable_shared_from_this.hpp>
 | 
			
		||||
 | 
			
		||||
class type 
 | 
			
		||||
    : public boost::enable_shared_from_this<type> {
 | 
			
		||||
public:
 | 
			
		||||
    static unsigned int instances;
 | 
			
		||||
 | 
			
		||||
    explicit type() {
 | 
			
		||||
        instances++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~type() {
 | 
			
		||||
        instances--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    type(const type&);
 | 
			
		||||
    type& operator=(const type&);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned int type::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
 | 
			
		||||
        try {
 | 
			
		||||
            a1[0].shared_from_this();
 | 
			
		||||
            BOOST_ERROR("shared_from_this did not throw");
 | 
			
		||||
        } catch (...) {
 | 
			
		||||
            BOOST_TEST(type::instances == 3);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3);
 | 
			
		||||
        try {
 | 
			
		||||
            a1[0].shared_from_this();
 | 
			
		||||
            BOOST_ERROR("shared_from_this did not throw");
 | 
			
		||||
        } catch (...) {
 | 
			
		||||
            BOOST_TEST(type::instances == 3);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,181 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
#include <boost/smart_ptr/weak_ptr.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
 | 
			
		||||
class type {
 | 
			
		||||
public:
 | 
			
		||||
    static unsigned int instances;
 | 
			
		||||
 | 
			
		||||
    explicit type() {
 | 
			
		||||
        instances++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~type() {
 | 
			
		||||
        instances--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    type(const type&);
 | 
			
		||||
    type& operator=(const type&);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned int type::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[]> a1 = boost::allocate_shared_noinit<int[]>(std::allocator<int>(), 3);
 | 
			
		||||
        int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[3]> a1 = boost::allocate_shared_noinit<int[3]>(std::allocator<int>());
 | 
			
		||||
        int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[][2]> a1 = boost::allocate_shared_noinit<int[][2]>(std::allocator<int>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[2][2]> a1 = boost::allocate_shared_noinit<int[2][2]>(std::allocator<int>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[]> a1 = boost::allocate_shared_noinit<const int[]>(std::allocator<int>(), 3);
 | 
			
		||||
        const int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[3]> a1 = boost::allocate_shared_noinit<const int[3]>(std::allocator<int>());
 | 
			
		||||
        const int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[][2]> a1 = boost::allocate_shared_noinit<const int[][2]>(std::allocator<int>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[2][2]> a1 = boost::allocate_shared_noinit<const int[2][2]>(std::allocator<int>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3);
 | 
			
		||||
        type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        boost::weak_ptr<type[]> w1 = a1;
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[3]> a1 = boost::allocate_shared_noinit<type[3]>(std::allocator<type>());
 | 
			
		||||
        type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        boost::weak_ptr<type[3]> w1 = a1;
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[][2]> a1 = boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared_noinit<type[2][2]>(std::allocator<type>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[]> a1 = boost::allocate_shared_noinit<const type[]>(std::allocator<type>(), 3);
 | 
			
		||||
        const type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[3]> a1 = boost::allocate_shared_noinit<const type[3]>(std::allocator<type>());
 | 
			
		||||
        const type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[][2]> a1 = boost::allocate_shared_noinit<const type[][2]>(std::allocator<type>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[2][2]> a1 = boost::allocate_shared_noinit<const type[2][2]>(std::allocator<type>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,209 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License,
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
#include <boost/smart_ptr/weak_ptr.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
 | 
			
		||||
class type {
 | 
			
		||||
public:
 | 
			
		||||
    static unsigned int instances;
 | 
			
		||||
 | 
			
		||||
    explicit type() {
 | 
			
		||||
        instances++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~type() {
 | 
			
		||||
        instances--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    type(const type&);
 | 
			
		||||
    type& operator=(const type&);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned int type::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[]> a1 = boost::allocate_shared<int[]>(std::allocator<int>(), 3);
 | 
			
		||||
        int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
        BOOST_TEST(a1[0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[2] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[3]> a1 = boost::allocate_shared<int[3]>(std::allocator<int>());
 | 
			
		||||
        int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
        BOOST_TEST(a1[0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[2] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[][2]> a1 = boost::allocate_shared<int[][2]>(std::allocator<int>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a1[0][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[0][1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][1] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[2][2]> a1 = boost::allocate_shared<int[2][2]>(std::allocator<int>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a1[0][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[0][1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][1] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), 3);
 | 
			
		||||
        const int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
        BOOST_TEST(a1[0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[2] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[3]> a1 = boost::allocate_shared<const int[3]>(std::allocator<int>());
 | 
			
		||||
        const int* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
 | 
			
		||||
        BOOST_TEST(a1[0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[2] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[][2]> a1 = boost::allocate_shared<const int[][2]>(std::allocator<int>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a1[0][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[0][1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][1] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[2][2]> a1 = boost::allocate_shared<const int[2][2]>(std::allocator<int>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a1[0][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[0][1] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][0] == 0);
 | 
			
		||||
        BOOST_TEST(a1[1][1] == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
 | 
			
		||||
        type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        boost::weak_ptr<type[]> w1 = a1;
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[3]> a1 = boost::allocate_shared<type[3]>(std::allocator<type>());
 | 
			
		||||
        type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        boost::weak_ptr<type[3]> w1 = a1;
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[][2]> a1 = boost::allocate_shared<type[][2]>(std::allocator<type>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared<type[2][2]>(std::allocator<type>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(std::allocator<type>(), 3);
 | 
			
		||||
        const type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[3]> a1 = boost::allocate_shared<const type[3]>(std::allocator<type>());
 | 
			
		||||
        const type* a2 = a1.get();
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(a2 != 0);
 | 
			
		||||
        BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
 | 
			
		||||
        BOOST_TEST(type::instances == 3);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[][2]> a1 = boost::allocate_shared<const type[][2]>(std::allocator<type>(), 2);
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const type[2][2]> a1 = boost::allocate_shared<const type[2][2]>(std::allocator<type>());
 | 
			
		||||
        BOOST_TEST(a1.get() != 0);
 | 
			
		||||
        BOOST_TEST(a1.use_count() == 1);
 | 
			
		||||
        BOOST_TEST(type::instances == 4);
 | 
			
		||||
        a1.reset();
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,100 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
 | 
			
		||||
class type {
 | 
			
		||||
public:
 | 
			
		||||
    static unsigned int instances;
 | 
			
		||||
 | 
			
		||||
    explicit type() {
 | 
			
		||||
        if (instances == 5) {
 | 
			
		||||
            throw true;
 | 
			
		||||
        }
 | 
			
		||||
        instances++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~type() {
 | 
			
		||||
        instances--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    type(const type&);
 | 
			
		||||
    type& operator=(const type&);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned int type::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared<type[]>(std::allocator<type>(), 6);
 | 
			
		||||
        BOOST_ERROR("allocate_shared did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared<type[][2]>(std::allocator<type>(), 3);
 | 
			
		||||
        BOOST_ERROR("allocate_shared did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared<type[6]>(std::allocator<type>());
 | 
			
		||||
        BOOST_ERROR("allocate_shared did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared<type[3][2]>(std::allocator<type>());
 | 
			
		||||
        BOOST_ERROR("allocate_shared did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 6);
 | 
			
		||||
        BOOST_ERROR("allocate_shared_noinit did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 3);
 | 
			
		||||
        BOOST_ERROR("allocate_shared_noinit did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared_noinit<type[6]>(std::allocator<type>());
 | 
			
		||||
        BOOST_ERROR("allocate_shared_noinit did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST(type::instances == 0);
 | 
			
		||||
    try {
 | 
			
		||||
        boost::allocate_shared_noinit<type[3][2]>(std::allocator<type>());
 | 
			
		||||
        BOOST_ERROR("allocate_shared_noinit did not throw");
 | 
			
		||||
    } catch (...) {
 | 
			
		||||
        BOOST_TEST(type::instances == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2012-2014 Glen Joseph Fernandes 
 | 
			
		||||
 * glenfe at live dot com
 | 
			
		||||
 *
 | 
			
		||||
 * Distributed under the Boost Software License, 
 | 
			
		||||
 * Version 1.0. (See accompanying file LICENSE_1_0.txt 
 | 
			
		||||
 * or copy at http://boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <boost/smart_ptr/allocate_shared_array.hpp>
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[]> a1 = boost::allocate_shared<int[]>(std::allocator<int>(), 4, 1);
 | 
			
		||||
        BOOST_TEST(a1[0] == 1);
 | 
			
		||||
        BOOST_TEST(a1[1] == 1);
 | 
			
		||||
        BOOST_TEST(a1[2] == 1);
 | 
			
		||||
        BOOST_TEST(a1[3] == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<int[4]> a1 = boost::allocate_shared<int[4]>(std::allocator<int>(), 1);
 | 
			
		||||
        BOOST_TEST(a1[0] == 1);
 | 
			
		||||
        BOOST_TEST(a1[1] == 1);
 | 
			
		||||
        BOOST_TEST(a1[2] == 1);
 | 
			
		||||
        BOOST_TEST(a1[3] == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), 4, 1);
 | 
			
		||||
        BOOST_TEST(a1[0] == 1);
 | 
			
		||||
        BOOST_TEST(a1[1] == 1);
 | 
			
		||||
        BOOST_TEST(a1[2] == 1);
 | 
			
		||||
        BOOST_TEST(a1[3] == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<const int[4]> a1 = boost::allocate_shared<const int[4]>(std::allocator<int>(), 1);
 | 
			
		||||
        BOOST_TEST(a1[0] == 1);
 | 
			
		||||
        BOOST_TEST(a1[1] == 1);
 | 
			
		||||
        BOOST_TEST(a1[2] == 1);
 | 
			
		||||
        BOOST_TEST(a1[3] == 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user