summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2007-12-15 22:28:29 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2007-12-15 22:28:29 +0000
commit92db39d4b13495690cabbbad892735449d4cfac2 (patch)
tree92904d7cb067d890b685151c36bb6d20140aed1b /libstdc++-v3
parent21b4a4b370454c754a4cd0bfd580a7c58165eb2d (diff)
downloadgcc-92db39d4b13495690cabbbad892735449d4cfac2.tar.gz
2007-12-15 Jonathan Wakely <jwakely-gcc@gmail.com>
* include/tr1_impl/boost_shared_ptr.h: Add support for allocators, aliasing, make_shared and rvalue-references. Move __shared_count and _Sp_counted_* classes to new headers. * include/tr1_impl/boost_sp_counted_base.h: New. * include/bits/boost_sp_shared_count.h: New. * include/tr1/boost_sp_shared_count.h: New. * include/std/memory, include/tr1/memory: Include new headers. * include/Makefile.am: Adjust. * include/Makefile.in: Regenerate. * docs/html/documentation.html: Link to shared_ptr notes. * docs/html/20_util/shared_ptr.html: New. * docs/html/17_intro/c++0x_status.html: Update shared_ptr status. * testsuite/20_util/shared_ptr/cons/alias.cc: New. * testsuite/20_util/shared_ptr/cons/alloc.cc: Likewise. * testsuite/20_util/shared_ptr/cons/move.cc: Likewise. * testsuite/20_util/shared_ptr/assign/move.cc: Likewise. * testsuite/20_util/shared_ptr/creation/alloc.cc: Likewise. * testsuite/20_util/shared_ptr/creation/make.cc: Likewise. * testsuite/20_util/shared_ptr/creation/dr402.cc: Likewise. * testsuite/20_util/shared_ptr/modifiers/reset_alloc.cc: Likewise. * testsuite/20_util/shared_ptr/assign/assign.cc: Duplicate tr1 test. * testsuite/20_util/shared_ptr/assign/auto_ptr.cc: Likewise. * testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc: Likewise. * testsuite/20_util/shared_ptr/assign/auto_ptr_rvalue_neg.cc: Likewise. * testsuite/20_util/shared_ptr/assign/dr541.cc: Likewise. * testsuite/20_util/shared_ptr/assign/shared_ptr.cc: Likewise. * testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc: Likewise. * testsuite/20_util/shared_ptr/casts/1.cc: Likewise. * testsuite/20_util/shared_ptr/comparison/cmp.cc: Likewise. * testsuite/20_util/shared_ptr/cons/auto_ptr.cc: Likewise. * testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc: Likewise. * testsuite/20_util/shared_ptr/cons/copy.cc: Likewise. * testsuite/20_util/shared_ptr/cons/default.cc: Likewise. * testsuite/20_util/shared_ptr/cons/pointer.cc: Likewise. * testsuite/20_util/shared_ptr/cons/weak_ptr.cc: Likewise. * testsuite/20_util/shared_ptr/cons/weak_ptr_expired.cc: Likewise. * testsuite/20_util/shared_ptr/dest/dest.cc: Likewise. * testsuite/20_util/shared_ptr/misc/24595.cc: Likewise. * testsuite/20_util/shared_ptr/misc/io.cc: Likewise. * testsuite/20_util/shared_ptr/misc/swap.cc: Likewise. * testsuite/20_util/shared_ptr/modifiers/24805.cc: Likewise. * testsuite/20_util/shared_ptr/modifiers/reset.cc: Likewise. * testsuite/20_util/shared_ptr/modifiers/reset_neg.cc: Likewise. * testsuite/20_util/shared_ptr/modifiers/swap.cc: Likewise. * testsuite/20_util/shared_ptr/modifiers/swap_neg.cc: Likewise. * testsuite/20_util/shared_ptr/observers/bool_conv.cc: Likewise. * testsuite/20_util/shared_ptr/observers/get.cc: Likewise. * testsuite/20_util/shared_ptr/observers/unique.cc: Likewise. * testsuite/20_util/shared_ptr/observers/use_count.cc: Likewise. * testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc: Likewise. * testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc: Likewise. * testsuite/20_util/shared_ptr/requirements/explicit_instantiation/ 1.cc: Likewise. * testsuite/20_util/shared_ptr/requirements/explicit_instantiation/ 2.cc: Likewise. * testsuite/20_util/shared_ptr/requirements/explicit_instantiation.cc: Remove. * testsuite/20_util/weak_ptr/lock/1.cc: Duplicate tr1 test. * testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc: Likewise. * testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc: Likewise. * testsuite/20_util/weak_ptr/requirements/explicit_instantiation.cc: Remove. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130977 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/docs/html/17_intro/c++0x_status.html20
-rw-r--r--libstdc++-v3/docs/html/20_util/shared_ptr.html419
-rw-r--r--libstdc++-v3/docs/html/documentation.html8
-rw-r--r--libstdc++-v3/include/Makefile.am3
-rw-r--r--libstdc++-v3/include/Makefile.in3
-rw-r--r--libstdc++-v3/include/bits/boost_sp_shared_count.h378
-rw-r--r--libstdc++-v3/include/std/memory4
-rw-r--r--libstdc++-v3/include/tr1/boost_sp_shared_count.h214
-rw-r--r--libstdc++-v3/include/tr1/memory4
-rw-r--r--libstdc++-v3/include/tr1_impl/boost_shared_ptr.h619
-rw-r--r--libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h244
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/assign.cc73
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc86
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc51
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_rvalue_neg.cc50
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/dr541.cc (renamed from libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation.cc)19
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/move.cc119
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr.cc97
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc53
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc46
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/comparison/cmp.cc85
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc108
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc.cc104
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc50
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc49
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/copy.cc137
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/default.cc47
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/move.cc165
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/pointer.cc81
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr.cc52
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr_expired.cc63
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc110
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/creation/dr402.cc48
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/creation/make.cc100
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/dest/dest.cc135
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/misc/24595.cc41
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/misc/io.cc53
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/misc/swap.cc52
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/24805.cc (renamed from libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation.cc)19
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset.cc90
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_alloc.cc64
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_neg.cc48
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap.cc52
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_neg.cc49
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc82
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/observers/get.cc82
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/observers/unique.cc82
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/observers/use_count.cc81
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc32
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc35
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc194
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc196
-rw-r--r--libstdc++-v3/testsuite/20_util/weak_ptr/lock/1.cc37
-rw-r--r--libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc32
-rw-r--r--libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc36
55 files changed, 4845 insertions, 356 deletions
diff --git a/libstdc++-v3/docs/html/17_intro/c++0x_status.html b/libstdc++-v3/docs/html/17_intro/c++0x_status.html
index e4e07e01f3b..cfc28ed44a5 100644
--- a/libstdc++-v3/docs/html/17_intro/c++0x_status.html
+++ b/libstdc++-v3/docs/html/17_intro/c++0x_status.html
@@ -567,7 +567,7 @@ particular release.
<td>done</td>
<td></td>
<td></td>
- <td><a href="tr1.html#1">1</a></td>
+ <td><a href="#1">1</a></td>
</tr>
<tr>
<td>20.6.6.2.1</td>
@@ -611,6 +611,16 @@ particular release.
</tr>
<tr>
<td>20.6.6.2.6</td>
+ <td><code>shared_ptr</code> creation</td>
+ <td>done</td>
+ <td></td>
+ <td></td>
+ <td>
+ <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm">N2351</a>
+ </td>
+ </tr>
+ <tr>
+ <td>20.6.6.2.7</td>
<td><code>shared_ptr</code> comparison</td>
<td>done</td>
<td></td>
@@ -618,7 +628,7 @@ particular release.
<td></td>
</tr>
<tr>
- <td>20.6.6.2.7</td>
+ <td>20.6.6.2.8</td>
<td><code>shared_ptr</code> I/O</td>
<td>done</td>
<td></td>
@@ -626,7 +636,7 @@ particular release.
<td></td>
</tr>
<tr>
- <td>20.6.6.2.8</td>
+ <td>20.6.6.2.9</td>
<td><code>shared_ptr</code> specialized algorithms</td>
<td>done</td>
<td></td>
@@ -634,7 +644,7 @@ particular release.
<td></td>
</tr>
<tr>
- <td>20.6.6.2.9</td>
+ <td>20.6.6.2.10</td>
<td><code>shared_ptr</code> casts</td>
<td>done</td>
<td></td>
@@ -642,7 +652,7 @@ particular release.
<td></td>
</tr>
<tr>
- <td>20.6.6.2.10</td>
+ <td>20.6.6.2.11</td>
<td><code>get_deleter</code></td>
<td>done</td>
<td></td>
diff --git a/libstdc++-v3/docs/html/20_util/shared_ptr.html b/libstdc++-v3/docs/html/20_util/shared_ptr.html
new file mode 100644
index 00000000000..6df2e6de635
--- /dev/null
+++ b/libstdc++-v3/docs/html/20_util/shared_ptr.html
@@ -0,0 +1,419 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, STL" />
+ <meta name="DESCRIPTION" content="Notes on the shared_ptr implementation." />
+ <title>Notes on the shared_ptr implementation.</title>
+<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
+<link rel="Start" href="../documentation.html" type="text/html"
+ title="GNU C++ Standard Library" />
+<link rel="Bookmark" href="howto.html" type="text/html" title="General Utilities" />
+<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
+<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
+</head>
+<body>
+<h1>
+Notes on the <code>shared_ptr</code> implementation.
+</h1>
+<em>
+prepared by Jonathan Wakely on November 11, 2007
+</em>
+
+<h2>
+1. Abstract
+</h2>
+<p>
+The shared_ptr class template stores a pointer, usually obtained via new,
+and implements shared ownership semantics.
+</p>
+
+<h2>
+2. What the standard says
+</h2>
+
+<blockquote>
+20.6.6.2 - Class template shared_ptr [util.smartptr.shared]
+</blockquote>
+
+<p>
+The standard deliberately doesn't require a reference-counted implementation,
+allowing other techniques such as a circular-linked-list.
+</p>
+
+<p>
+At the time of writing the C++0x working paper doesn't mention how threads
+affect shared_ptr, but it is likely to follow the existing practice set by
+<code>boost::shared_ptr</code>. The shared_ptr in libstdc++ is derived
+from Boost's, so the same rules apply.
+</p>
+
+<h2>
+3. Problems with shared_ptr: TR1 vs C++0x, thread safety.
+</h2>
+
+<p>
+The interface of <code>tr1::shared_ptr</code> was extended for C++0x with
+support for rvalue-references and the other features from N2351. As
+with other libstdc++ headers shared by TR1 and C++0x, boost_shared_ptr.h
+uses conditional compilation, based on the macros _GLIBCXX_INCLUDE_AS_CXX0X
+and _GLIBCXX_INCLUDE_AS_TR1, to enable and disable features.
+</p>
+
+<p>
+C++0x-only features are: rvalue-ref/move support, allocator support,
+aliasing constructor, make_shared &amp; allocate_shared. Additionally, the
+constructors taking auto_ptr parameters are deprecated in C++0x mode.
+</p>
+
+<p>
+The
+<a href="http://boost.org/libs/smart_ptr/shared_ptr.htm#ThreadSafety">Thread
+Safety</a> section of the Boost shared_ptr documentation says "shared_ptr
+objects offer the same level of thread safety as built-in types."
+The implementation must ensure that concurrent updates to separate shared_ptr
+instances are correct even when those instances share a reference count e.g.
+</p>
+<pre>
+shared_ptr&lt;A&gt; a(new A);
+shared_ptr&lt;A&gt; b(a);
+
+// Thread 1 // Thread 2
+ a.reset(); b.reset();
+</pre>
+<p>
+The dynamically-allocated object must be destroyed by exactly one of the
+threads. Weak references make things even more interesting.
+The shared state used to implement shared_ptr must be transparent to the
+user and invariants must be preserved at all times.
+The key pieces of shared state are the strong and weak reference counts.
+Updates to these need to be atomic and visible to all threads to ensure
+correct cleanup of the managed resource (which is, after all, shared_ptr's
+job!)
+On multi-processor systems memory synchronisation may be needed so that
+reference-count updates and the destruction of the managed resource are
+race-free.
+</p>
+
+<p>
+The function <code>_Sp_counted_base::_M_add_ref_lock()</code>, called when
+obtaining a shared_ptr from a weak_ptr, has to test if the managed
+resource still exists and either increment the reference count or throw
+<code>std::bad_weak_ptr</code>.
+In a multi-threaded program there is a potential race condition if the last
+reference is dropped (and the managed resource destroyed) between testing
+the reference count and incrementing it, which could result in a shared_ptr
+pointing to invalid memory.
+</p>
+<p>
+The Boost shared_ptr (as used in GCC) features a clever lock-free algorithm
+to avoid the race condition, but this relies on the processor supporting
+an atomic <em>Compare-And-Swap</em> instruction. For other platforms there
+are fall-backs using mutex locks. Boost (as of version 1.35) includes
+several different implementations and the preprocessor selects one based
+on the compiler, standard library, platform etc. For the version of
+shared_ptr in libstdc++ the compiler and library are fixed, which makes
+things much simpler: we have an atomic CAS or we don't, see Lock Policy
+below for details.
+</p>
+
+<h2>
+4. Design and Implementation Details
+</h2>
+
+<p>
+The shared_ptr code in libstdc++ was kindly donated to GCC by the Boost
+project and the original authors of the code. The basic design and
+algorithms are from Boost, the notes below describe details specific to
+the GCC implementation. Names have been uglified in this implementation,
+but the design should be recognisable to anyone familiar with the Boost
+1.32 shared_ptr.
+</p>
+
+<p>
+The basic design is an abstract base class, <code>_Sp_counted_base</code> that
+does the reference-counting and calls virtual functions when the count
+drops to zero.
+Derived classes override those functions to destroy resources in a context
+where the correct dynamic type is known. This is an application of the
+technique known as type erasure.
+</p>
+
+<h3>
+C++0x and TR1 Implementations
+</h3>
+
+<p>
+The classes derived from <code>_Sp_counted_base</code> (see Class Hierarchy
+below) and <code>__shared_count</code> are implemented separately for C++0x
+and TR1, in <tt>bits/boost_sp_shared_count.h</tt> and
+<tt>tr1/boost_sp_shared_count.h</tt> respectively. All other classes
+including <code>_Sp_counted_base</code> are shared by both implementations.
+</p>
+
+<p>
+The TR1 implementation is considered relatively stable, so is unlikely to
+change unless bug fixes require it to. If the code that is common to both
+C++0x and TR1 modes needs to diverge further then it might be necessary to
+duplicate additional classes and only make changes to the C++0x versions.
+</p>
+
+<h3>
+Lock Policy
+</h3>
+
+<p>
+Libstdc++ has a single <code>_Sp_counted_base</code> class, which is a
+template parameterized on the enum <code>__gnu_cxx::_Lock_policy</code>.
+The entire family of classes is parameterized on the lock policy, right up
+to <code>__shared_ptr</code>, <code>__weak_ptr</code> and
+<code>__enable_shared_from_this</code>. The actual
+<code>std::shared_ptr</code> class inherits from <code>__shared_ptr</code>
+with the lock policy parameter selected automatically based on the thread
+model and platform that libstdc++ is configured for, so that the best
+available template specialization will be used. This design is necessary
+because it would not be conforming for <code>std::shared_ptr</code> to have
+an extra template parameter, even if it had a default value.
+The available policies are:
+</p>
+
+<dl>
+<dt><code>_S_Atomic</code></dt>
+<dd>
+Selected when GCC supports a builtin atomic compare-and-swap
+operation on the target processor (see
+<a href="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html">Atomic
+Builtins</a>.)
+The reference counts are maintained using a lock-free algorithm and GCC's
+atomic builtins, which provide the required memory synchronisation.
+</dd>
+<dt><code>_S_Mutex</code></dt>
+<dd>
+The _Sp_counted_base specialization for this policy contains a mutex,
+which is locked in add_ref_lock(). This policy is used when GCC's atomic
+builtins aren't available so explicit memory barriers are needed in places.
+</dd>
+<dt><code>_S_Single</code></dt>
+<dd>
+This policy uses a non-reentrant add_ref_lock() with no locking. It is
+used when libstdc++ is built without <em>--enable-threads</em>.
+</dd>
+</dl>
+
+<p>
+For all three policies, reference count increments and decrements are done
+via the functions in <tt>&lt;ext/atomicity.h&gt;</tt>, which detect if the
+program is multi-threaded.
+If only one thread of execution exists in the program then less expensive
+non-atomic operations are used.
+</p>
+
+<h3>
+Class Hierarchy
+</h3>
+
+<p>
+A <code>shared_ptr&lt;T&gt;</code> contains a pointer of type <code>T*</code>
+and an object of type <code>__shared_count</code>. The shared_count contains
+a pointer of type <code>_Sp_counted_base*</code> which points to the object
+that maintains the reference-counts and destroys the managed resource.
+</p>
+
+<dl>
+<dt><code>_Sp_counted_base&lt;Lp&gt;</code></dt>
+<dd>
+The base of the hierarchy is parameterized on the lock policy alone.
+_Sp_counted_base doesn't depend on the type of pointer being managed,
+it only maintains the reference counts and calls virtual functions when
+the counts drop to zero. The managed object is destroyed when the last
+strong reference is dropped, but the _Sp_counted_base itself must exist
+until the last weak reference is dropped.
+</dd>
+<dt><code>_Sp_counted_base_impl&lt;Ptr, Deleter, Lp&gt;</code></dt>
+<dd>
+Inherits from _Sp_counted_base and stores a pointer of type <code>Ptr</code>
+and a deleter of type <code>Deleter</code>. <code>_Sp_deleter</code> is
+used when the user doesn't supply a custom deleter. Unlike Boost's, this
+default deleter is not "checked" because GCC already issues a warning if
+<code>delete</code> is used with an incomplete type.
+This is the only derived type used by <code>tr1::shared_ptr&lt;Ptr&gt;</code>
+and it is never used by <code>std::shared_ptr</code>, which uses one of
+the following types, depending on how the shared_ptr is constructed.
+</dd>
+<dt><code>_Sp_counted_ptr&lt;Ptr, Lp&gt;</code></dt>
+<dd>
+Inherits from _Sp_counted_base and stores a pointer of type <code>Ptr</code>,
+which is passed to <code>delete</code> when the last reference is dropped.
+This is the simplest form and is used when there is no custom deleter or
+allocator.
+</dd>
+<dt><code>_Sp_counted_deleter&lt;Ptr, Deleter, Alloc&gt;</code></dt>
+<dd>
+Inherits from _Sp_counted_ptr and adds support for custom deleter and
+allocator. Empty Base Optimization is used for the allocator. This class
+is used even when the user only provides a custom deleter, in which case
+<code>std::allocator</code> is used as the allocator.
+</dd>
+<dt><code>_Sp_counted_ptr_inplace&lt;Tp, Alloc, Lp&gt;</code></dt>
+<dd>
+Used by <code>allocate_shared</code> and <code>make_shared</code>.
+Contains aligned storage to hold an object of type <code>Tp</code>,
+which is constructed in-place with placement <code>new</code>.
+Has a variadic template constructor allowing any number of arguments to
+be forwarded to <code>Tp</code>'s constructor.
+Unlike the other _Sp_counted_* classes, this one is parameterized on the
+type of object, not the type of pointer; this is purely a convenience
+that simplifies the implementation slightly.
+</dd>
+</dl>
+
+<h3>
+Related functions and classes
+</h3>
+
+<dl>
+<dt><code>dynamic_pointer_cast</code>, <code>static_pointer_cast</code>,
+<code>const_pointer_cast</code></dt>
+<dd>
+As noted in N2351, these functions can be implemented non-intrusively using
+the alias constructor. However the aliasing constructor is only available
+in C++0x mode, so in TR1 mode these casts rely on three non-standard
+constructors in shared_ptr and __shared_ptr.
+In C++0x mode these constructors and the related tag types are not needed.
+</dd>
+<dt><code>enable_shared_from_this</code></dt>
+<dd>
+The clever overload to detect a base class of type
+<code>enable_shared_from_this</code> comes straight from Boost.
+There is an extra overload for <code>__enable_shared_from_this</code> to
+work smoothly with <code>__shared_ptr&lt;Tp, Lp&gt;</code> using any lock
+policy.
+</dd>
+<dt><code>make_shared</code>, <code>allocate_shared</code></dt>
+<dd>
+<code>make_shared</code> simply forwards to <code>allocate_shared</code>
+with <code>std::allocator</code> as the allocator.
+Although these functions can be implemented non-intrusively using the
+alias constructor, if they have access to the implementation then it is
+possible to save storage and reduce the number of heap allocations. The
+newly constructed object and the _Sp_counted_* can be allocated in a single
+block and the standard says implementations are "encouraged, but not required,"
+to do so. This implementation provides additional non-standard constructors
+(selected with the type <code>_Sp_make_shared_tag</code>) which create an
+object of type <code>_Sp_counted_ptr_inplace</code> to hold the new object.
+The returned <code>shared_ptr&lt;A&gt;</code> needs to know the address of the
+new <code>A</code> object embedded in the <code>_Sp_counted_ptr_inplace</code>,
+but it has no way to access it.
+This implementation uses a "covert channel" to return the address of the
+embedded object when <code>get_deleter&lt;_Sp_make_shared_tag&gt;()</code>
+is called. Users should not try to use this.
+As well as the extra constructors, this implementation also needs some
+members of _Sp_counted_deleter to be protected where they could otherwise
+be private.
+</dd>
+</dl>
+
+<h2>
+5. Examples
+</h2>
+
+<p>
+Examples of use can be found in the testsuite, under
+<tt>testsuite/tr1/2_general_utilities/shared_ptr</tt>.
+</p>
+
+<h2>
+6. Unresolved Issues
+</h2>
+
+<p>
+The resolution to C++ Standard Library issue <a
+href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#674">674</a>,
+"shared_ptr interface changes for consistency with N1856" will need to be
+implemented after it is accepted into the working paper. Issue <a
+href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#743">743</a>
+might also require changes.
+</p>
+
+<p>
+The _S_single policy uses atomics when used in MT code, because it uses
+the same dispatcher functions that check __gthread_active_p(). This could be
+addressed by providing template specialisations for some members of
+_Sp_counted_base&lt;_S_single&gt;.
+</p>
+
+<p>
+Unlike Boost, this implementation does not use separate classes for the
+pointer+deleter and pointer+deleter+allocator cases in C++0x mode, combining
+both into _Sp_counted_deleter and using std::allocator when the user doesn't
+specify an allocator.
+If it was found to be beneficial an additional class could easily be added.
+With the current implementation, the _Sp_counted_deleter and __shared_count
+constructors taking a custom deleter but no allocator are technically
+redundant and could be removed, changing callers to always specify an
+allocator. If a separate pointer+deleter class was added the __shared_count
+constructor would be needed, so it has been kept for now.
+</p>
+
+<p>
+The hack used to get the address of the managed object from
+_Sp_counted_ptr_inplace::_M_get_deleter() is accessible to users. This
+could be prevented if get_deleter&lt;_Sp_make_shared_tag&gt;() always
+returned NULL, since the hack only needs to work at a lower level, not
+in the public API. This wouldn't be difficult, but hasn't been done since
+there is no danger of accidental misuse: users already know they are
+relying on unsupported features if they refer to implementation details
+such as _Sp_make_shared_tag.
+</p>
+
+<p>
+tr1::_Sp_deleter could be a private member of tr1::__shared_count but it
+would alter the ABI.
+</p>
+
+<p>
+Exposing the alias constructor in TR1 mode could simplify the *_pointer_cast
+functions.
+Constructor could be private in TR1 mode, with the cast functions as friends.
+</p>
+
+<h2>
+7. Acknowledgments
+</h2>
+<p>
+The original authors of the Boost shared_ptr, which is really nice code
+to work with, Peter Dimov in particular for his help and invaluable advice
+on thread safety.
+Phillip Jordan and Paolo Carlini for the lock policy implementation.
+</p>
+
+
+<h2>
+8. Bibliography / Referenced Documents
+</h2>
+
+<p>
+N2351 Improving shared_ptr for C++0x, Revision 2
+<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm</a>
+</p>
+
+<p>
+N2456 C++ Standard Library Active Issues List (Revision R52)
+<a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2456.html">http://open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2456.html</a></p>
+<p>
+N2461 Working Draft, Standard for Programming Language C++
+<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf</a>
+</p>
+
+<p>
+Boost C++ Libraries documentation - shared_ptr class template
+<a href="http://boost.org/libs/smart_ptr/shared_ptr.htm">http://boost.org/libs/smart_ptr/shared_ptr.htm</a>
+</p>
+
+</body>
+</html>
+
diff --git a/libstdc++-v3/docs/html/documentation.html b/libstdc++-v3/docs/html/documentation.html
index 0c7dda3747f..c5413decd27 100644
--- a/libstdc++-v3/docs/html/documentation.html
+++ b/libstdc++-v3/docs/html/documentation.html
@@ -143,6 +143,12 @@ href="http://gcc.gnu.org/svn.html">web</a>.
<li><a href="20_util/howto.html#2"><code>auto_ptr</code> inside container classes</a></li>
</ul>
</li>
+ <li>shared_ptr
+ <ul>
+ <li><a href="20_util/shared_ptr.html">Notes on the <code>shared_ptr</code>
+ implementation</a></li>
+ </ul>
+ </li>
</ul>
</li>
</ul>
@@ -330,7 +336,7 @@ href="http://gcc.gnu.org/svn.html">web</a>.
<hr />
<br />
-<h2><a name="7" href="faq/index.html">Frequently Asked Questions</a></h2
+<h2><a name="7" href="faq/index.html">Frequently Asked Questions</a></h2>
<hr />
<br />
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 9eee09016f5..a4a4d3e481d 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -77,6 +77,7 @@ bits_headers = \
${bits_srcdir}/basic_string.h \
${bits_srcdir}/basic_string.tcc \
${bits_srcdir}/boost_concept_check.h \
+ ${bits_srcdir}/boost_sp_shared_count.h \
${bits_srcdir}/char_traits.h \
${bits_srcdir}/codecvt.h \
${bits_srcdir}/concept_check.h \
@@ -515,6 +516,7 @@ tr1_headers = \
${tr1_srcdir}/array \
${tr1_srcdir}/bessel_function.tcc \
${tr1_srcdir}/beta_function.tcc \
+ ${tr1_srcdir}/boost_sp_shared_count.h \
${tr1_srcdir}/ccomplex \
${tr1_srcdir}/cctype \
${tr1_srcdir}/cfenv \
@@ -575,6 +577,7 @@ tr1_impl_builddir = ./tr1_impl
tr1_impl_headers = \
${tr1_impl_srcdir}/array \
${tr1_impl_srcdir}/boost_shared_ptr.h \
+ ${tr1_impl_srcdir}/boost_sp_counted_base.h \
${tr1_impl_srcdir}/cctype \
${tr1_impl_srcdir}/cfenv \
${tr1_impl_srcdir}/cinttypes \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 9b2fb033dbe..3291fca5607 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -326,6 +326,7 @@ bits_headers = \
${bits_srcdir}/basic_string.h \
${bits_srcdir}/basic_string.tcc \
${bits_srcdir}/boost_concept_check.h \
+ ${bits_srcdir}/boost_sp_shared_count.h \
${bits_srcdir}/char_traits.h \
${bits_srcdir}/codecvt.h \
${bits_srcdir}/concept_check.h \
@@ -762,6 +763,7 @@ tr1_headers = \
${tr1_srcdir}/array \
${tr1_srcdir}/bessel_function.tcc \
${tr1_srcdir}/beta_function.tcc \
+ ${tr1_srcdir}/boost_sp_shared_count.h \
${tr1_srcdir}/ccomplex \
${tr1_srcdir}/cctype \
${tr1_srcdir}/cfenv \
@@ -821,6 +823,7 @@ tr1_impl_builddir = ./tr1_impl
tr1_impl_headers = \
${tr1_impl_srcdir}/array \
${tr1_impl_srcdir}/boost_shared_ptr.h \
+ ${tr1_impl_srcdir}/boost_sp_counted_base.h \
${tr1_impl_srcdir}/cctype \
${tr1_impl_srcdir}/cfenv \
${tr1_impl_srcdir}/cinttypes \
diff --git a/libstdc++-v3/include/bits/boost_sp_shared_count.h b/libstdc++-v3/include/bits/boost_sp_shared_count.h
new file mode 100644
index 00000000000..75ee16d8eb2
--- /dev/null
+++ b/libstdc++-v3/include/bits/boost_sp_shared_count.h
@@ -0,0 +1,378 @@
+// <bits/boost_sp_shared_count.h> -*- C++ -*-
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// shared_count.hpp
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+
+// shared_ptr.hpp
+// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
+// Copyright (C) 2001, 2002, 2003 Peter Dimov
+
+// weak_ptr.hpp
+// Copyright (C) 2001, 2002, 2003 Peter Dimov
+
+// enable_shared_from_this.hpp
+// Copyright (C) 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)
+
+// GCC Note: based on version 1.32.0 of the Boost library.
+
+/** @file bits/boost_sp_shared_count.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+# include <c++0x_warning.h>
+#endif
+
+#if defined(_GLIBCXX_INCLUDE_AS_TR1)
+# error C++0x header cannot be included from TR1 header
+#endif
+
+namespace std
+{
+ // counted ptr with no deleter or allocator support
+ template<typename _Ptr, _Lock_policy _Lp>
+ class _Sp_counted_ptr
+ : public _Sp_counted_base<_Lp>
+ {
+ public:
+ _Sp_counted_ptr(_Ptr __p)
+ : _M_ptr(__p) { }
+
+ virtual void
+ _M_dispose() // nothrow
+ { delete _M_ptr; }
+
+ virtual void
+ _M_destroy() // nothrow
+ { delete this; }
+
+ virtual void*
+ _M_get_deleter(const std::type_info& __ti)
+ { return 0; }
+
+ private:
+ _Sp_counted_ptr(const _Sp_counted_ptr&);
+ _Sp_counted_ptr& operator=(const _Sp_counted_ptr&);
+
+ protected:
+ _Ptr _M_ptr; // copy constructor must not throw
+ };
+
+ // support for custom deleter and/or allocator
+ template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
+ class _Sp_counted_deleter
+ : public _Sp_counted_ptr<_Ptr, _Lp>
+ {
+ typedef typename _Alloc::template
+ rebind<_Sp_counted_deleter>::other _My_alloc_type;
+
+ // Helper class that stores the Deleter and also acts as an allocator.
+ // Used to dispose of the owned pointer and the internal refcount
+ // Requires that copies of _Alloc can free each other's memory.
+ struct _My_Deleter
+ : public _My_alloc_type // copy constructor must not throw
+ {
+ _Deleter _M_del; // copy constructor must not throw
+ _My_Deleter(_Deleter __d, const _Alloc& __a)
+ : _My_alloc_type(__a), _M_del(__d) { }
+ };
+
+ protected:
+ typedef _Sp_counted_ptr<_Ptr, _Lp> _Base_type;
+
+ public:
+ /**
+ * @brief
+ * @pre __d(__p) must not throw.
+ */
+ _Sp_counted_deleter(_Ptr __p, _Deleter __d)
+ : _Base_type(__p), _M_del(__d, _Alloc()) { }
+
+ /**
+ * @brief
+ * @pre __d(__p) must not throw.
+ */
+ _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a)
+ : _Base_type(__p), _M_del(__d, __a) { }
+
+ virtual void
+ _M_dispose() // nothrow
+ { _M_del._M_del(_Base_type::_M_ptr); }
+
+ virtual void
+ _M_destroy() // nothrow
+ {
+ _My_alloc_type __a(_M_del);
+ this->~_Sp_counted_deleter();
+ __a.deallocate(this, 1);
+ }
+
+ virtual void*
+ _M_get_deleter(const std::type_info& __ti)
+ { return __ti == typeid(_Deleter) ? &_M_del._M_del : 0; }
+
+ private:
+ _Sp_counted_deleter(const _Sp_counted_deleter&);
+ _Sp_counted_deleter& operator=(const _Sp_counted_deleter&);
+
+ protected:
+ _My_Deleter _M_del; // copy constructor must not throw
+ };
+
+ // helpers for make_shared / allocate_shared
+
+ template<typename _Tp>
+ struct _Sp_destroy_inplace
+ {
+ void operator()(_Tp* __p) const { if (__p) __p->~_Tp(); }
+ };
+
+ struct _Sp_make_shared_tag { };
+
+ template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
+ class _Sp_counted_ptr_inplace
+ : public _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
+ {
+ typedef _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
+ _Base_type;
+
+ public:
+ _Sp_counted_ptr_inplace(_Alloc __a)
+ : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
+ , _M_storage()
+ {
+ void* __p = &_M_storage;
+ ::new (__p) _Tp(); // might throw
+ _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p);
+ }
+
+ template<typename... _Args>
+ _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
+ : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
+ , _M_storage()
+ {
+ void* __p = &_M_storage;
+ ::new (__p) _Tp(std::forward<_Args>(__args)...); // might throw
+ _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p);
+ }
+
+ // override because the allocator needs to know the dynamic type
+ virtual void
+ _M_destroy() // nothrow
+ {
+ typedef typename _Alloc::template
+ rebind<_Sp_counted_ptr_inplace>::other _My_alloc_type;
+ _My_alloc_type __a(_Base_type::_M_del);
+ this->~_Sp_counted_ptr_inplace();
+ __a.deallocate(this, 1);
+ }
+
+ // sneaky trick so __shared_ptr can get the managed pointer
+ virtual void*
+ _M_get_deleter(const std::type_info& __ti)
+ {
+ return __ti == typeid(_Sp_make_shared_tag)
+ ? static_cast<void*>(&_M_storage)
+ : _Base_type::_M_get_deleter(__ti);
+ }
+
+ private:
+ typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
+ _M_storage;
+ };
+
+ template<_Lock_policy _Lp = __default_lock_policy>
+ class __weak_count;
+
+ template<_Lock_policy _Lp = __default_lock_policy>
+ class __shared_count
+ {
+ public:
+ __shared_count()
+ : _M_pi(0) // nothrow
+ { }
+
+ template<typename _Ptr>
+ __shared_count(_Ptr __p) : _M_pi(0)
+ {
+ try
+ {
+ _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
+ }
+ catch(...)
+ {
+ delete __p;
+ __throw_exception_again;
+ }
+ }
+
+ template<typename _Ptr, typename _Deleter>
+ __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
+ {
+ // allocator's value_type doesn't matter, will rebind it anyway
+ typedef std::allocator<int> _Alloc;
+ typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
+ typedef std::allocator<_Sp_cd_type> _Alloc2;
+ _Alloc2 __a2;
+ try
+ {
+ _M_pi = __a2.allocate(1);
+ new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d);
+ }
+ catch(...)
+ {
+ __d(__p); // Call _Deleter on __p.
+ if (_M_pi)
+ __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
+ __throw_exception_again;
+ }
+ }
+
+ template<typename _Ptr, typename _Deleter, typename _Alloc>
+ __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
+ {
+ typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
+ typedef typename _Alloc::template rebind<_Sp_cd_type>::other _Alloc2;
+ _Alloc2 __a2(__a);
+ try
+ {
+ _M_pi = __a2.allocate(1);
+ new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d, __a);
+ }
+ catch(...)
+ {
+ __d(__p); // Call _Deleter on __p.
+ if (_M_pi)
+ __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
+ __throw_exception_again;
+ }
+ }
+
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ __shared_count(_Sp_make_shared_tag, _Tp*, _Alloc __a, _Args&&... __args)
+ : _M_pi(0)
+ {
+ typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
+ typedef typename _Alloc::template rebind<_Sp_cp_type>::other _Alloc2;
+ _Alloc2 __a2(__a);
+ try
+ {
+ _M_pi = __a2.allocate(1);
+ new(static_cast<void*>(_M_pi)) _Sp_cp_type(__a,
+ std::forward<_Args>(__args)...);
+ }
+ catch(...)
+ {
+ if (_M_pi)
+ __a2.deallocate(static_cast<_Sp_cp_type*>(_M_pi), 1);
+ __throw_exception_again;
+ }
+ }
+
+#if _GLIBCXX_DEPRECATED
+ // Special case for auto_ptr<_Tp> to provide the strong guarantee.
+ template<typename _Tp>
+ explicit
+ __shared_count(std::auto_ptr<_Tp>& __r)
+ : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
+ { __r.release(); }
+#endif
+
+ // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
+ explicit
+ __shared_count(const __weak_count<_Lp>& __r);
+
+ ~__shared_count() // nothrow
+ {
+ if (_M_pi != 0)
+ _M_pi->_M_release();
+ }
+
+ __shared_count(const __shared_count& __r)
+ : _M_pi(__r._M_pi) // nothrow
+ {
+ if (_M_pi != 0)
+ _M_pi->_M_add_ref_copy();
+ }
+
+ __shared_count&
+ operator=(const __shared_count& __r) // nothrow
+ {
+ _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
+ if (__tmp != _M_pi)
+ {
+ if (__tmp != 0)
+ __tmp->_M_add_ref_copy();
+ if (_M_pi != 0)
+ _M_pi->_M_release();
+ _M_pi = __tmp;
+ }
+ return *this;
+ }
+
+ void
+ _M_swap(__shared_count& __r) // nothrow
+ {
+ _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
+ __r._M_pi = _M_pi;
+ _M_pi = __tmp;
+ }
+
+ long
+ _M_get_use_count() const // nothrow
+ { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
+
+ bool
+ _M_unique() const // nothrow
+ { return this->_M_get_use_count() == 1; }
+
+ friend inline bool
+ operator==(const __shared_count& __a, const __shared_count& __b)
+ { return __a._M_pi == __b._M_pi; }
+
+ friend inline bool
+ operator<(const __shared_count& __a, const __shared_count& __b)
+ { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
+
+ void*
+ _M_get_deleter(const std::type_info& __ti) const
+ { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
+
+ private:
+ friend class __weak_count<_Lp>;
+
+ _Sp_counted_base<_Lp>* _M_pi;
+ };
+}
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 89f680d7088..2e78e3f7fd0 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -75,12 +75,16 @@
# include <backward/auto_ptr.h>
# endif
# if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
+# include <tr1_impl/boost_sp_counted_base.h>
+# include <bits/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
# else
# define _GLIBCXX_INCLUDE_AS_CXX0X
# define _GLIBCXX_BEGIN_NAMESPACE_TR1
# define _GLIBCXX_END_NAMESPACE_TR1
# define _GLIBCXX_TR1
+# include <tr1_impl/boost_sp_counted_base.h>
+# include <bits/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
# undef _GLIBCXX_TR1
# undef _GLIBCXX_END_NAMESPACE_TR1
diff --git a/libstdc++-v3/include/tr1/boost_sp_shared_count.h b/libstdc++-v3/include/tr1/boost_sp_shared_count.h
new file mode 100644
index 00000000000..a2de21f4439
--- /dev/null
+++ b/libstdc++-v3/include/tr1/boost_sp_shared_count.h
@@ -0,0 +1,214 @@
+// <tr1/boost_sp_shared_count.h> -*- C++ -*-
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// shared_count.hpp
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+
+// shared_ptr.hpp
+// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
+// Copyright (C) 2001, 2002, 2003 Peter Dimov
+
+// weak_ptr.hpp
+// Copyright (C) 2001, 2002, 2003 Peter Dimov
+
+// enable_shared_from_this.hpp
+// Copyright (C) 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)
+
+// GCC Note: based on version 1.32.0 of the Boost library.
+
+/** @file tr1/boost_sp_shared_count.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
+# error TR1 header cannot be included from C++0x header
+#endif
+
+namespace std
+{
+namespace tr1
+{
+
+ template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
+ class _Sp_counted_base_impl
+ : public _Sp_counted_base<_Lp>
+ {
+ public:
+ /**
+ * @brief
+ * @pre __d(__p) must not throw.
+ */
+ _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
+ : _M_ptr(__p), _M_del(__d) { }
+
+ virtual void
+ _M_dispose() // nothrow
+ { _M_del(_M_ptr); }
+
+ virtual void*
+ _M_get_deleter(const std::type_info& __ti)
+ { return __ti == typeid(_Deleter) ? &_M_del : 0; }
+
+ private:
+ _Sp_counted_base_impl(const _Sp_counted_base_impl&);
+ _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
+
+ _Ptr _M_ptr; // copy constructor must not throw
+ _Deleter _M_del; // copy constructor must not throw
+ };
+
+ template<_Lock_policy _Lp = __default_lock_policy>
+ class __weak_count;
+
+ template<typename _Tp>
+ struct _Sp_deleter
+ {
+ typedef void result_type;
+ typedef _Tp* argument_type;
+ void operator()(_Tp* __p) const { delete __p; }
+ };
+
+ template<_Lock_policy _Lp = __default_lock_policy>
+ class __shared_count
+ {
+ public:
+ __shared_count()
+ : _M_pi(0) // nothrow
+ { }
+
+ template<typename _Ptr>
+ __shared_count(_Ptr __p) : _M_pi(0)
+ {
+ try
+ {
+ typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
+ _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
+ __p, _Sp_deleter<_Tp>());
+ }
+ catch(...)
+ {
+ delete __p;
+ __throw_exception_again;
+ }
+ }
+
+ template<typename _Ptr, typename _Deleter>
+ __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
+ {
+ try
+ {
+ _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
+ }
+ catch(...)
+ {
+ __d(__p); // Call _Deleter on __p.
+ __throw_exception_again;
+ }
+ }
+
+ // Special case for auto_ptr<_Tp> to provide the strong guarantee.
+ template<typename _Tp>
+ explicit
+ __shared_count(std::auto_ptr<_Tp>& __r)
+ : _M_pi(new _Sp_counted_base_impl<_Tp*,
+ _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
+ { __r.release(); }
+
+ // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
+ explicit
+ __shared_count(const __weak_count<_Lp>& __r);
+
+ ~__shared_count() // nothrow
+ {
+ if (_M_pi != 0)
+ _M_pi->_M_release();
+ }
+
+ __shared_count(const __shared_count& __r)
+ : _M_pi(__r._M_pi) // nothrow
+ {
+ if (_M_pi != 0)
+ _M_pi->_M_add_ref_copy();
+ }
+
+ __shared_count&
+ operator=(const __shared_count& __r) // nothrow
+ {
+ _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
+ if (__tmp != _M_pi)
+ {
+ if (__tmp != 0)
+ __tmp->_M_add_ref_copy();
+ if (_M_pi != 0)
+ _M_pi->_M_release();
+ _M_pi = __tmp;
+ }
+ return *this;
+ }
+
+ void
+ _M_swap(__shared_count& __r) // nothrow
+ {
+ _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
+ __r._M_pi = _M_pi;
+ _M_pi = __tmp;
+ }
+
+ long
+ _M_get_use_count() const // nothrow
+ { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
+
+ bool
+ _M_unique() const // nothrow
+ { return this->_M_get_use_count() == 1; }
+
+ friend inline bool
+ operator==(const __shared_count& __a, const __shared_count& __b)
+ { return __a._M_pi == __b._M_pi; }
+
+ friend inline bool
+ operator<(const __shared_count& __a, const __shared_count& __b)
+ { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
+
+ void*
+ _M_get_deleter(const std::type_info& __ti) const
+ { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
+
+ private:
+ friend class __weak_count<_Lp>;
+
+ _Sp_counted_base<_Lp>* _M_pi;
+ };
+}
+}
diff --git a/libstdc++-v3/include/tr1/memory b/libstdc++-v3/include/tr1/memory
index 3cf92f46b1d..134b5bd3f25 100644
--- a/libstdc++-v3/include/tr1/memory
+++ b/libstdc++-v3/include/tr1/memory
@@ -54,12 +54,16 @@
#include <tr1/type_traits>
#if defined(_GLIBCXX_INCLUDE_AS_TR1)
+# include <tr1_impl/boost_sp_counted_base.h>
+# include <tr1/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
#else
# define _GLIBCXX_INCLUDE_AS_TR1
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 tr1::
+# include <tr1_impl/boost_sp_counted_base.h>
+# include <tr1/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
# undef _GLIBCXX_TR1
# undef _GLIBCXX_END_NAMESPACE_TR1
diff --git a/libstdc++-v3/include/tr1_impl/boost_shared_ptr.h b/libstdc++-v3/include/tr1_impl/boost_shared_ptr.h
index c2ee1ca5b5d..53f8c0febf5 100644
--- a/libstdc++-v3/include/tr1_impl/boost_shared_ptr.h
+++ b/libstdc++-v3/include/tr1_impl/boost_shared_ptr.h
@@ -51,330 +51,11 @@
* You should not attempt to use it directly.
*/
+
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_TR1
- class bad_weak_ptr : public std::exception
- {
- public:
- virtual char const*
- what() const throw()
- { return "tr1::bad_weak_ptr"; }
- };
-
- // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
- inline void
- __throw_bad_weak_ptr()
- {
-#if __EXCEPTIONS
- throw bad_weak_ptr();
-#else
- __builtin_abort();
-#endif
- }
-
- using __gnu_cxx::_Lock_policy;
- using __gnu_cxx::__default_lock_policy;
- using __gnu_cxx::_S_single;
- using __gnu_cxx::_S_mutex;
- using __gnu_cxx::_S_atomic;
-
- template<typename _Tp>
- struct _Sp_deleter
- {
- typedef void result_type;
- typedef _Tp* argument_type;
-
- void
- operator()(_Tp* __p) const
- { delete __p; }
- };
-
- // Empty helper class except when the template argument is _S_mutex.
- template<_Lock_policy _Lp>
- class _Mutex_base
- {
- protected:
- // The atomic policy uses fully-fenced builtins, single doesn't care.
- enum { _S_need_barriers = 0 };
- };
-
- template<>
- class _Mutex_base<_S_mutex>
- : public __gnu_cxx::__mutex
- {
- protected:
- // This policy is used when atomic builtins are not available.
- // The replacement atomic operations might not have the necessary
- // memory barriers.
- enum { _S_need_barriers = 1 };
- };
-
- template<_Lock_policy _Lp = __default_lock_policy>
- class _Sp_counted_base
- : public _Mutex_base<_Lp>
- {
- public:
- _Sp_counted_base()
- : _M_use_count(1), _M_weak_count(1) { }
-
- virtual
- ~_Sp_counted_base() // nothrow
- { }
-
- // Called when _M_use_count drops to zero, to release the resources
- // managed by *this.
- virtual void
- _M_dispose() = 0; // nothrow
-
- // Called when _M_weak_count drops to zero.
- virtual void
- _M_destroy() // nothrow
- { delete this; }
-
- virtual void*
- _M_get_deleter(const std::type_info&) = 0;
-
- void
- _M_add_ref_copy()
- { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
-
- void
- _M_add_ref_lock();
-
- void
- _M_release() // nothrow
- {
- if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
- {
- _M_dispose();
- // There must be a memory barrier between dispose() and destroy()
- // to ensure that the effects of dispose() are observed in the
- // thread that runs destroy().
- // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
- if (_Mutex_base<_Lp>::_S_need_barriers)
- {
- _GLIBCXX_READ_MEM_BARRIER;
- _GLIBCXX_WRITE_MEM_BARRIER;
- }
-
- if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
- -1) == 1)
- _M_destroy();
- }
- }
-
- void
- _M_weak_add_ref() // nothrow
- { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
-
- void
- _M_weak_release() // nothrow
- {
- if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
- {
- if (_Mutex_base<_Lp>::_S_need_barriers)
- {
- // See _M_release(),
- // destroy() must observe results of dispose()
- _GLIBCXX_READ_MEM_BARRIER;
- _GLIBCXX_WRITE_MEM_BARRIER;
- }
- _M_destroy();
- }
- }
-
- long
- _M_get_use_count() const // nothrow
- {
- // No memory barrier is used here so there is no synchronization
- // with other threads.
- return const_cast<const volatile _Atomic_word&>(_M_use_count);
- }
-
- private:
- _Sp_counted_base(_Sp_counted_base const&);
- _Sp_counted_base& operator=(_Sp_counted_base const&);
-
- _Atomic_word _M_use_count; // #shared
- _Atomic_word _M_weak_count; // #weak + (#shared != 0)
- };
-
- template<>
- inline void
- _Sp_counted_base<_S_single>::
- _M_add_ref_lock()
- {
- if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
- {
- _M_use_count = 0;
- __throw_bad_weak_ptr();
- }
- }
-
- template<>
- inline void
- _Sp_counted_base<_S_mutex>::
- _M_add_ref_lock()
- {
- __gnu_cxx::__scoped_lock sentry(*this);
- if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
- {
- _M_use_count = 0;
- __throw_bad_weak_ptr();
- }
- }
-
- template<>
- inline void
- _Sp_counted_base<_S_atomic>::
- _M_add_ref_lock()
- {
- // Perform lock-free add-if-not-zero operation.
- _Atomic_word __count;
- do
- {
- __count = _M_use_count;
- if (__count == 0)
- __throw_bad_weak_ptr();
-
- // Replace the current counter value with the old value + 1, as
- // long as it's not changed meanwhile.
- }
- while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
- __count + 1));
- }
-
- template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
- class _Sp_counted_base_impl
- : public _Sp_counted_base<_Lp>
- {
- public:
- /**
- * @brief
- * @pre __d(__p) must not throw.
- */
- _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
- : _M_ptr(__p), _M_del(__d) { }
-
- virtual void
- _M_dispose() // nothrow
- { _M_del(_M_ptr); }
-
- virtual void*
- _M_get_deleter(const std::type_info& __ti)
- { return __ti == typeid(_Deleter) ? &_M_del : 0; }
-
- private:
- _Sp_counted_base_impl(const _Sp_counted_base_impl&);
- _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
-
- _Ptr _M_ptr; // copy constructor must not throw
- _Deleter _M_del; // copy constructor must not throw
- };
-
- template<_Lock_policy _Lp = __default_lock_policy>
- class __weak_count;
-
- template<_Lock_policy _Lp = __default_lock_policy>
- class __shared_count
- {
- public:
- __shared_count()
- : _M_pi(0) // nothrow
- { }
-
- template<typename _Ptr, typename _Deleter>
- __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
- {
- try
- {
- _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
- }
- catch(...)
- {
- __d(__p); // Call _Deleter on __p.
- __throw_exception_again;
- }
- }
-
-#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
- // Special case for auto_ptr<_Tp> to provide the strong guarantee.
- template<typename _Tp>
- explicit
- __shared_count(std::auto_ptr<_Tp>& __r)
- : _M_pi(new _Sp_counted_base_impl<_Tp*,
- _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
- { __r.release(); }
-#endif
-
- // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
- explicit
- __shared_count(const __weak_count<_Lp>& __r);
-
- ~__shared_count() // nothrow
- {
- if (_M_pi != 0)
- _M_pi->_M_release();
- }
-
- __shared_count(const __shared_count& __r)
- : _M_pi(__r._M_pi) // nothrow
- {
- if (_M_pi != 0)
- _M_pi->_M_add_ref_copy();
- }
-
- __shared_count&
- operator=(const __shared_count& __r) // nothrow
- {
- _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
- if (__tmp != _M_pi)
- {
- if (__tmp != 0)
- __tmp->_M_add_ref_copy();
- if (_M_pi != 0)
- _M_pi->_M_release();
- _M_pi = __tmp;
- }
- return *this;
- }
-
- void
- _M_swap(__shared_count& __r) // nothrow
- {
- _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
- __r._M_pi = _M_pi;
- _M_pi = __tmp;
- }
-
- long
- _M_get_use_count() const // nothrow
- { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
-
- bool
- _M_unique() const // nothrow
- { return this->_M_get_use_count() == 1; }
-
- friend inline bool
- operator==(const __shared_count& __a, const __shared_count& __b)
- { return __a._M_pi == __b._M_pi; }
-
- friend inline bool
- operator<(const __shared_count& __a, const __shared_count& __b)
- { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
-
- void*
- _M_get_deleter(const std::type_info& __ti) const
- { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
-
- private:
- friend class __weak_count<_Lp>;
-
- _Sp_counted_base<_Lp>* _M_pi;
- };
-
template<_Lock_policy _Lp>
class __weak_count
{
@@ -453,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
_Sp_counted_base<_Lp>* _M_pi;
};
+ // now that __weak_count is defined we can define this constructor:
template<_Lock_policy _Lp>
inline
__shared_count<_Lp>::
@@ -464,7 +146,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
else
__throw_bad_weak_ptr();
}
-
// Forward declarations.
template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
@@ -507,9 +188,11 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
{ }
+#ifdef _GLIBCXX_INCLUDE_AS_TR1
struct __static_cast_tag { };
struct __const_cast_tag { };
struct __dynamic_cast_tag { };
+#endif
/**
* @class shared_ptr <tr1/memory>
@@ -539,7 +222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Tp1>
explicit
__shared_ptr(_Tp1* __p)
- : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
+ : _M_ptr(__p), _M_refcount(__p)
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
@@ -560,13 +243,58 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
*/
template<typename _Tp1, typename _Deleter>
__shared_ptr(_Tp1* __p, _Deleter __d)
- : _M_ptr(__p), _M_refcount(__p, __d)
+ : _M_ptr(__p), _M_refcount(__p, __d)
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// TODO requires _Deleter CopyConstructible and __d(__p) well-formed
__enable_shared_from_this_helper(_M_refcount, __p, __p);
}
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ //
+ // Requirements: _Deleter's copy constructor and destructor must not throw
+ // _Alloc's copy constructor and destructor must not throw.
+ //
+ // __shared_ptr will release __p by calling __d(__p)
+ //
+ /** @brief Construct a %__shared_ptr that owns the pointer @a __p
+ * and the deleter @a __d.
+ * @param __p A pointer.
+ * @param __d A deleter.
+ * @param __a An allocator.
+ * @post use_count() == 1 && get() == __p
+ * @throw std::bad_alloc, in which case @a __d(__p) is called.
+ */
+ template<typename _Tp1, typename _Deleter, typename _Alloc>
+ __shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
+ : _M_ptr(__p), _M_refcount(__p, __d, __a)
+ {
+ __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
+ // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
+ __enable_shared_from_this_helper(_M_refcount, __p, __p);
+ }
+
+ /** @brief Constructs a %__shared_ptr instance that stores @a __p
+ * and shares ownership with @a __r.
+ * @param __r A %__shared_ptr.
+ * @param __p A pointer that will remain valid while @a *__r is valid.
+ * @post get() == __p && use_count() == __r.use_count()
+ *
+ * This can be used to construct a @c shared_ptr to a sub-object
+ * of an object managed by an existing @c shared_ptr.
+ *
+ * @code
+ * shared_ptr< pair<int,int> > pii(new pair<int,int>());
+ * shared_ptr<int> pi(pii, &pii->first);
+ * assert(pii.use_count() == 2);
+ * @endcode
+ */
+ template<typename _Tp1>
+ __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p)
+ : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
+ { }
+#endif
+
// generated copy constructor, assignment, destructor are fine.
/** @brief If @a __r is empty, constructs an empty %__shared_ptr;
@@ -580,6 +308,32 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
{ __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ /** @brief Move-constructs a %__shared_ptr instance from @a __r.
+ * @param __r A %__shared_ptr rvalue.
+ * @post *this contains the old value of @a __r, @a __r is empty.
+ */
+ __shared_ptr(__shared_ptr&& __r)
+ : _M_ptr(__r._M_ptr), _M_refcount() // never throws
+ {
+ _M_refcount._M_swap(__r._M_refcount);
+ __r._M_ptr = 0;
+ }
+
+ /** @brief Move-constructs a %__shared_ptr instance from @a __r.
+ * @param __r A %__shared_ptr rvalue.
+ * @post *this contains the old value of @a __r, @a __r is empty.
+ */
+ template<typename _Tp1>
+ __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
+ : _M_ptr(__r._M_ptr), _M_refcount() // never throws
+ {
+ __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
+ _M_refcount._M_swap(__r._M_refcount);
+ __r._M_ptr = 0;
+ }
+#endif
+
/** @brief Constructs a %__shared_ptr that shares ownership with @a __r
* and stores a copy of the pointer stored in @a __r.
* @param __r A weak_ptr.
@@ -607,14 +361,15 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
__shared_ptr(std::auto_ptr<_Tp1>& __r)
: _M_ptr(__r.get()), _M_refcount()
{
- // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
- // delete __r.release() well-formed
+ __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
+ // TODO requires _Tp1 is complete, delete __r.release() well-formed
_Tp1* __tmp = __r.get();
_M_refcount = __shared_count<_Lp>(__r);
__enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
}
#endif
+#ifdef _GLIBCXX_INCLUDE_AS_TR1
template<typename _Tp1>
__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
@@ -635,6 +390,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
if (_M_ptr == 0) // need to allocate new counter -- the cast failed
_M_refcount = __shared_count<_Lp>();
}
+#endif
template<typename _Tp1>
__shared_ptr&
@@ -655,6 +411,23 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
}
#endif
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ __shared_ptr&
+ operator=(__shared_ptr&& __r)
+ {
+ __shared_ptr(std::move(__r)).swap(*this);
+ return *this;
+ }
+
+ template<class _Tp1>
+ __shared_ptr&
+ operator=(__shared_ptr<_Tp1, _Lp>&& __r)
+ {
+ __shared_ptr(std::move(__r)).swap(*this);
+ return *this;
+ }
+#endif
+
void
reset() // never throws
{ __shared_ptr().swap(*this); }
@@ -673,10 +446,16 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
reset(_Tp1* __p, _Deleter __d)
{ __shared_ptr(__p, __d).swap(*this); }
- // Allow class instantiation when _Tp is [cv-qual] void.
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ template<typename _Tp1, typename _Deleter, typename _Alloc>
+ void
+ reset(_Tp1* __p, _Deleter __d, const _Alloc& __a)
+ { __shared_ptr(__p, __d, __a).swap(*this); }
+
+ // Allow class instantiation when _Tp is [cv-qual] void.
typename std::add_lvalue_reference<_Tp>::type
#else
+ // Allow class instantiation when _Tp is [cv-qual] void.
typename std::tr1::add_reference<_Tp>::type
#endif
operator*() const // never throws
@@ -719,6 +498,26 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
_M_refcount._M_swap(__other._M_refcount);
}
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ protected:
+ // This constructor is non-standard, it is used by allocate_shared.
+ template<typename _Alloc, typename... _Args>
+ __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
+ : _M_ptr()
+ , _M_refcount(__tag, (_Tp*)0, __a, std::forward<_Args>(__args)...)
+ {
+ // _M_ptr needs to point to the newly constructed object.
+ // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
+ void * __p = _M_refcount._M_get_deleter(typeid(__tag));
+ _M_ptr = static_cast<_Tp*>(__p);
+ }
+
+ template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
+ typename... _Args>
+ friend __shared_ptr<_Tp1, _Lp1>
+ __allocate_shared(_Alloc __a, _Args&&... __args);
+#endif
+
private:
void*
_M_get_deleter(const std::type_info& __ti) const
@@ -768,9 +567,15 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
* attempting to delete the same object twice.
*/
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
- __shared_ptr<_Tp, _Lp>
+ inline __shared_ptr<_Tp, _Lp>
static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
- { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
+ {
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get()));
+#else
+ return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag());
+#endif
+ }
/** @warning The seemingly equivalent
* <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
@@ -778,9 +583,15 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
* attempting to delete the same object twice.
*/
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
- __shared_ptr<_Tp, _Lp>
+ inline __shared_ptr<_Tp, _Lp>
const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
- { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
+ {
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get()));
+#else
+ return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag());
+#endif
+ }
/** @warning The seemingly equivalent
* <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
@@ -788,9 +599,17 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
* attempting to delete the same object twice.
*/
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
- __shared_ptr<_Tp, _Lp>
+ inline __shared_ptr<_Tp, _Lp>
dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
- { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
+ {
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
+ return __shared_ptr<_Tp, _Lp>(__r, __p);
+ return __shared_ptr<_Tp, _Lp>();
+#else
+ return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag());
+#endif
+ }
// 2.2.3.7 shared_ptr I/O
template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
@@ -1011,10 +830,30 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
shared_ptr(_Tp1* __p, _Deleter __d)
: __shared_ptr<_Tp>(__p, __d) { }
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ template<typename _Tp1, typename _Deleter, typename _Alloc>
+ shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
+ : __shared_ptr<_Tp>(__p, __d, __a) { }
+
+ // Aliasing constructor
+ template<typename _Tp1>
+ shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p)
+ : __shared_ptr<_Tp>(__r, __p) { }
+#endif
+
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r)
: __shared_ptr<_Tp>(__r) { }
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ shared_ptr(shared_ptr&& __r)
+ : __shared_ptr<_Tp>(std::move(__r)) { }
+
+ template<typename _Tp1>
+ shared_ptr(shared_ptr<_Tp1>&& __r)
+ : __shared_ptr<_Tp>(std::move(__r)) { }
+#endif
+
template<typename _Tp1>
explicit
shared_ptr(const weak_ptr<_Tp1>& __r)
@@ -1027,6 +866,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
: __shared_ptr<_Tp>(__r) { }
#endif
+#ifdef _GLIBCXX_INCLUDE_AS_TR1
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
@@ -1038,6 +878,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
+#endif
template<typename _Tp1>
shared_ptr&
@@ -1056,22 +897,72 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
return *this;
}
#endif
+
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ shared_ptr&
+ operator=(shared_ptr&& __r)
+ {
+ this->__shared_ptr<_Tp>::operator=(std::move(__r));
+ return *this;
+ }
+
+ template<class _Tp1>
+ shared_ptr&
+ operator=(shared_ptr<_Tp1>&& __r)
+ {
+ this->__shared_ptr<_Tp>::operator=(std::move(__r));
+ return *this;
+ }
+#endif
+
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ private:
+ // This constructor is non-standard, it is used by allocate_shared.
+ template<typename _Alloc, typename... _Args>
+ shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
+ : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
+ { }
+
+ template<typename _Tp1, typename _Alloc, typename... _Args>
+ friend shared_ptr<_Tp1>
+ allocate_shared(_Alloc __a, _Args&&... __args);
+#endif
};
template<typename _Tp, typename _Tp1>
- shared_ptr<_Tp>
+ inline shared_ptr<_Tp>
static_pointer_cast(const shared_ptr<_Tp1>& __r)
- { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
+ {
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
+#else
+ return shared_ptr<_Tp>(__r, __static_cast_tag());
+#endif
+ }
template<typename _Tp, typename _Tp1>
- shared_ptr<_Tp>
+ inline shared_ptr<_Tp>
const_pointer_cast(const shared_ptr<_Tp1>& __r)
- { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
+ {
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get()));
+#else
+ return shared_ptr<_Tp>(__r, __const_cast_tag());
+#endif
+ }
template<typename _Tp, typename _Tp1>
- shared_ptr<_Tp>
+ inline shared_ptr<_Tp>
dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
- { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
+ {
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
+ return shared_ptr<_Tp>(__r, __p);
+ return shared_ptr<_Tp>();
+#else
+ return shared_ptr<_Tp>(__r, __dynamic_cast_tag());
+#endif
+ }
// The actual TR1 weak_ptr, with forwarding constructors and
@@ -1173,5 +1064,57 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
mutable weak_ptr<_Tp> _M_weak_this;
};
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
+ inline __shared_ptr<_Tp, _Lp>
+ __allocate_shared(_Alloc __a, _Args&&... __args)
+ {
+ return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(),
+ std::forward<_Alloc>(__a), std::forward<_Args>(__args)...);
+ }
+
+ template<typename _Tp, _Lock_policy _Lp, typename... _Args>
+ inline __shared_ptr<_Tp, _Lp>
+ __make_shared(_Args&&... __args)
+ {
+ typedef typename std::remove_const<_Tp>::type _Tp_nc;
+ return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
+ std::forward<_Args>(__args)...);
+ }
+
+ /** @brief Create an object that is owned by a shared_ptr.
+ * @param __a An allocator.
+ * @param __args Arguments for the @a _Tp object's constructor.
+ * @return A shared_ptr that owns the newly created object.
+ * @throw An exception thrown from @a _Alloc::allocate or from the
+ * constructor of @a _Tp.
+ *
+ * A copy of @a __a will be used to allocate memory for the shared_ptr
+ * and the new object.
+ */
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ inline shared_ptr<_Tp>
+ allocate_shared(_Alloc __a, _Args&&... __args)
+ {
+ return shared_ptr<_Tp>(_Sp_make_shared_tag(), std::forward<_Alloc>(__a),
+ std::forward<_Args>(__args)...);
+ }
+
+ /** @brief Create an object that is owned by a shared_ptr.
+ * @param __args Arguments for the @a _Tp object's constructor.
+ * @return A shared_ptr that owns the newly created object.
+ * @throw std::bad_alloc, or an exception thrown from the
+ * constructor of @a _Tp.
+ */
+ template<typename _Tp, typename... _Args>
+ inline shared_ptr<_Tp>
+ make_shared(_Args&&... __args)
+ {
+ typedef typename std::remove_const<_Tp>::type _Tp_nc;
+ return allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
+ std::forward<_Args>(__args)...);
+ }
+#endif
+
_GLIBCXX_END_NAMESPACE_TR1
}
diff --git a/libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h b/libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h
new file mode 100644
index 00000000000..3cb4175b376
--- /dev/null
+++ b/libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h
@@ -0,0 +1,244 @@
+// <tr1_impl/boost_sp_counted_base.h> -*- C++ -*-
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// shared_count.hpp
+// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+
+// shared_ptr.hpp
+// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
+// Copyright (C) 2001, 2002, 2003 Peter Dimov
+
+// weak_ptr.hpp
+// Copyright (C) 2001, 2002, 2003 Peter Dimov
+
+// enable_shared_from_this.hpp
+// Copyright (C) 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)
+
+// GCC Note: based on version 1.32.0 of the Boost library.
+
+/** @file tr1_impl/boost_sp_counted_base.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+
+namespace std
+{
+_GLIBCXX_BEGIN_NAMESPACE_TR1
+
+ class bad_weak_ptr : public std::exception
+ {
+ public:
+ virtual char const*
+ what() const throw()
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ { return "std::bad_weak_ptr"; }
+#else
+ { return "tr1::bad_weak_ptr"; }
+#endif
+ };
+
+ // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
+ inline void
+ __throw_bad_weak_ptr()
+ {
+#if __EXCEPTIONS
+ throw bad_weak_ptr();
+#else
+ __builtin_abort();
+#endif
+ }
+
+ using __gnu_cxx::_Lock_policy;
+ using __gnu_cxx::__default_lock_policy;
+ using __gnu_cxx::_S_single;
+ using __gnu_cxx::_S_mutex;
+ using __gnu_cxx::_S_atomic;
+
+ // Empty helper class except when the template argument is _S_mutex.
+ template<_Lock_policy _Lp>
+ class _Mutex_base
+ {
+ protected:
+ // The atomic policy uses fully-fenced builtins, single doesn't care.
+ enum { _S_need_barriers = 0 };
+ };
+
+ template<>
+ class _Mutex_base<_S_mutex>
+ : public __gnu_cxx::__mutex
+ {
+ protected:
+ // This policy is used when atomic builtins are not available.
+ // The replacement atomic operations might not have the necessary
+ // memory barriers.
+ enum { _S_need_barriers = 1 };
+ };
+
+ template<_Lock_policy _Lp = __default_lock_policy>
+ class _Sp_counted_base
+ : public _Mutex_base<_Lp>
+ {
+ public:
+ _Sp_counted_base()
+ : _M_use_count(1), _M_weak_count(1) { }
+
+ virtual
+ ~_Sp_counted_base() // nothrow
+ { }
+
+ // Called when _M_use_count drops to zero, to release the resources
+ // managed by *this.
+ virtual void
+ _M_dispose() = 0; // nothrow
+
+ // Called when _M_weak_count drops to zero.
+ virtual void
+ _M_destroy() // nothrow
+ { delete this; }
+
+ virtual void*
+ _M_get_deleter(const std::type_info&) = 0;
+
+ void
+ _M_add_ref_copy()
+ { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
+
+ void
+ _M_add_ref_lock();
+
+ void
+ _M_release() // nothrow
+ {
+ if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
+ {
+ _M_dispose();
+ // There must be a memory barrier between dispose() and destroy()
+ // to ensure that the effects of dispose() are observed in the
+ // thread that runs destroy().
+ // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
+ if (_Mutex_base<_Lp>::_S_need_barriers)
+ {
+ _GLIBCXX_READ_MEM_BARRIER;
+ _GLIBCXX_WRITE_MEM_BARRIER;
+ }
+
+ if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
+ -1) == 1)
+ _M_destroy();
+ }
+ }
+
+ void
+ _M_weak_add_ref() // nothrow
+ { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
+
+ void
+ _M_weak_release() // nothrow
+ {
+ if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
+ {
+ if (_Mutex_base<_Lp>::_S_need_barriers)
+ {
+ // See _M_release(),
+ // destroy() must observe results of dispose()
+ _GLIBCXX_READ_MEM_BARRIER;
+ _GLIBCXX_WRITE_MEM_BARRIER;
+ }
+ _M_destroy();
+ }
+ }
+
+ long
+ _M_get_use_count() const // nothrow
+ {
+ // No memory barrier is used here so there is no synchronization
+ // with other threads.
+ return const_cast<const volatile _Atomic_word&>(_M_use_count);
+ }
+
+ private:
+ _Sp_counted_base(_Sp_counted_base const&);
+ _Sp_counted_base& operator=(_Sp_counted_base const&);
+
+ _Atomic_word _M_use_count; // #shared
+ _Atomic_word _M_weak_count; // #weak + (#shared != 0)
+ };
+
+ template<>
+ inline void
+ _Sp_counted_base<_S_single>::
+ _M_add_ref_lock()
+ {
+ if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
+ {
+ _M_use_count = 0;
+ __throw_bad_weak_ptr();
+ }
+ }
+
+ template<>
+ inline void
+ _Sp_counted_base<_S_mutex>::
+ _M_add_ref_lock()
+ {
+ __gnu_cxx::__scoped_lock sentry(*this);
+ if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
+ {
+ _M_use_count = 0;
+ __throw_bad_weak_ptr();
+ }
+ }
+
+ template<>
+ inline void
+ _Sp_counted_base<_S_atomic>::
+ _M_add_ref_lock()
+ {
+ // Perform lock-free add-if-not-zero operation.
+ _Atomic_word __count;
+ do
+ {
+ __count = _M_use_count;
+ if (__count == 0)
+ __throw_bad_weak_ptr();
+
+ // Replace the current counter value with the old value + 1, as
+ // long as it's not changed meanwhile.
+ }
+ while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
+ __count + 1));
+ }
+
+_GLIBCXX_END_NAMESPACE_TR1
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/assign.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/assign.cc
new file mode 100644
index 00000000000..6f428ca0d34
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/assign.cc
@@ -0,0 +1,73 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() { ++ctor_count; }
+ virtual ~A() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long A::ctor_count = 0;
+long A::dtor_count = 0;
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ }
+};
+
+
+// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.assign]
+
+// Assignment from shared_ptr<Y>
+void
+test01()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+
+ a = std::shared_ptr<A>(new A);
+ VERIFY( a.get() != 0 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+
+ a = std::shared_ptr<A>();
+ VERIFY( a.get() == 0 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 1 );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc
new file mode 100644
index 00000000000..2a18b486236
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc
@@ -0,0 +1,86 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() { ++ctor_count; }
+ virtual ~A() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long A::ctor_count = 0;
+long A::dtor_count = 0;
+
+struct B : A
+{
+ B() { ++ctor_count; }
+ virtual ~B() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long B::ctor_count = 0;
+long B::dtor_count = 0;
+
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ B::ctor_count = 0;
+ B::dtor_count = 0;
+ }
+};
+
+
+// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.assign]
+
+// Assignment from auto_ptr<Y>
+int
+test01()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a(new A);
+ std::auto_ptr<B> b(new B);
+ a = b;
+ VERIFY( a.get() != 0 );
+ VERIFY( b.get() == 0 );
+ VERIFY( A::ctor_count == 2 );
+ VERIFY( A::dtor_count == 1 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc
new file mode 100644
index 00000000000..79bb73f1a79
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc
@@ -0,0 +1,51 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+struct B { };
+
+// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.assign]
+
+// Assignment from incompatible auto_ptr<Y>
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+ std::auto_ptr<B> b;
+ a = b; // { dg-error "here" }
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
+// { dg-excess-errors "In constructor" }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_rvalue_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_rvalue_neg.cc
new file mode 100644
index 00000000000..afa284931b5
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_rvalue_neg.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+std::auto_ptr<A> source() { return std::auto_ptr<A>(); }
+
+// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.assign]
+
+// Assignment from rvalue auto_ptr
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+ a = source(); // { dg-error "no match" }
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
+// { dg-excess-errors "candidates are" }
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/dr541.cc
index 1bbfe882811..86f648d263a 100644
--- a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/dr541.cc
@@ -1,7 +1,7 @@
// { dg-options "-std=gnu++0x" }
// { dg-do compile }
-// Copyright (C) 2007 Free Software Foundation
+// Copyright (C) 2006, 2007 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -14,11 +14,18 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02110-1301, USA.
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
#include <memory>
-template class std::weak_ptr<int>;
+// DR 541. shared_ptr template assignment and void
+void test01()
+{
+ std::shared_ptr<void> p;
+ p.operator=<void>(p);
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/move.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/move.cc
new file mode 100644
index 00000000000..34c9f8dc935
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/move.cc
@@ -0,0 +1,119 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <utility>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() { ++ctor_count; }
+ virtual ~A() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long A::ctor_count = 0;
+long A::dtor_count = 0;
+
+struct B : A
+{
+ B() { ++ctor_count; }
+ virtual ~B() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long B::ctor_count = 0;
+long B::dtor_count = 0;
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ B::ctor_count = 0;
+ B::dtor_count = 0;
+ }
+};
+
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Rvalue assignment from shared_ptr
+void
+test01()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a1;
+ std::shared_ptr<A> a2(new A);
+
+ a1 = std::move(a2);
+ VERIFY( a1.get() != 0 );
+ VERIFY( a2.get() == 0 );
+ VERIFY( a1.use_count() == 1 );
+ VERIFY( a2.use_count() == 0 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+
+ a1 = std::move(std::shared_ptr<A>());
+ VERIFY( a1.get() == 0 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 1 );
+}
+
+// Rvalue assignment from shared_ptr<Y>
+void
+test02()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+ std::shared_ptr<B> b(new B);
+
+ a = std::move(b);
+ VERIFY( a.get() != 0 );
+ VERIFY( b.get() == 0 );
+ VERIFY( a.use_count() == 1 );
+ VERIFY( b.use_count() == 0 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+
+ a = std::move(std::shared_ptr<A>());
+ VERIFY( a.get() == 0 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 1 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 1 );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr.cc
new file mode 100644
index 00000000000..983c70e4bfc
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr.cc
@@ -0,0 +1,97 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() { ++ctor_count; }
+ virtual ~A() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long A::ctor_count = 0;
+long A::dtor_count = 0;
+
+struct B : A
+{
+ B() { ++ctor_count; }
+ virtual ~B() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long B::ctor_count = 0;
+long B::dtor_count = 0;
+
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ B::ctor_count = 0;
+ B::dtor_count = 0;
+ }
+};
+
+
+// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.assign]
+
+// Assignment from shared_ptr<Y>
+void
+test01()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+
+ a = std::shared_ptr<A>();
+ VERIFY( a.get() == 0 );
+ VERIFY( A::ctor_count == 0 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 0 );
+ VERIFY( B::dtor_count == 0 );
+
+ a = std::shared_ptr<A>(new A);
+ VERIFY( a.get() != 0 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 0 );
+ VERIFY( B::dtor_count == 0 );
+
+ a = std::shared_ptr<B>(new B);
+ VERIFY( a.get() != 0 );
+ VERIFY( A::ctor_count == 2 );
+ VERIFY( A::dtor_count == 1 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc
new file mode 100644
index 00000000000..ab272d8c62f
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+struct B { };
+
+// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.assign]
+
+// Assignment from incompatible shared_ptr<Y>
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+ std::shared_ptr<B> b;
+ a = b; // { dg-error "here" }
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
+// { dg-error "In member function" "" { target *-*-* } 0 }
+// { dg-error "cannot convert" "" { target *-*-* } 0 }
+// { dg-error "instantiated from" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc
new file mode 100644
index 00000000000..58ebded5ca7
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc
@@ -0,0 +1,46 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2.10 shared_ptr casts [util.smartptr.shared.cast]
+
+#include <memory>
+#include <testsuite_tr1.h>
+
+// { dg-do compile }
+
+struct MyP { virtual ~MyP() { }; };
+struct MyDP : MyP { };
+
+int main()
+{
+ using __gnu_test::check_ret_type;
+ using std::shared_ptr;
+ using std::static_pointer_cast;
+ using std::const_pointer_cast;
+ using std::dynamic_pointer_cast;
+
+ shared_ptr<double> spd;
+ shared_ptr<const int> spci;
+ shared_ptr<MyP> spa;
+
+ check_ret_type<shared_ptr<void> >(static_pointer_cast<void>(spd));
+ check_ret_type<shared_ptr<int> >(const_pointer_cast<int>(spci));
+ check_ret_type<shared_ptr<MyDP> >(static_pointer_cast<MyDP>(spa));
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/comparison/cmp.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/comparison/cmp.cc
new file mode 100644
index 00000000000..55041f8ee81
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/comparison/cmp.cc
@@ -0,0 +1,85 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ virtual ~A() { }
+};
+
+struct B : A
+{
+};
+
+// 20.6.6.2.6 shared_ptr comparison [util.smartptr.shared.cmp]
+
+int
+test01()
+{
+ // test empty shared_ptrs compare equivalent
+ std::shared_ptr<A> p1;
+ std::shared_ptr<B> p2;
+ VERIFY( p1 == p2 );
+ VERIFY( !(p1 != p2) );
+ VERIFY( !(p1 < p2) && !(p2 < p1) );
+ return 0;
+}
+
+
+// Construction from pointer
+int
+test02()
+{
+ std::shared_ptr<A> A_default;
+
+ std::shared_ptr<A> A_from_A(new A);
+ VERIFY( A_default != A_from_A );
+ VERIFY( !(A_default == A_from_A) );
+ VERIFY( (A_default < A_from_A) || (A_from_A < A_default) );
+
+ std::shared_ptr<B> B_from_B(new B);
+ VERIFY( B_from_B != A_from_A );
+ VERIFY( !(B_from_B == A_from_A) );
+ VERIFY( (B_from_B < A_from_A) || (A_from_A < B_from_B) );
+
+ A_from_A.reset();
+ VERIFY( A_default == A_from_A );
+ VERIFY( !(A_default != A_from_A) );
+ VERIFY( !(A_default < A_from_A) && !(A_from_A < A_default) );
+
+ B_from_B.reset();
+ VERIFY( B_from_B == A_from_A );
+ VERIFY( !(B_from_B != A_from_A) );
+ VERIFY( !(B_from_B < A_from_A) && !(A_from_A < B_from_B) );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc
new file mode 100644
index 00000000000..a707740c9ec
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc
@@ -0,0 +1,108 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() : i() { }
+ virtual ~A() { }
+ int i;
+};
+
+struct B : A
+{
+ B() : A(), a() { }
+ virtual ~B() { }
+ A a;
+};
+
+void deletefunc(A* p) { delete p; }
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Aliasing constructors
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+ std::shared_ptr<bool> b1(a, &test);
+ VERIFY( b1.use_count() == 0 );
+ VERIFY( a.get() == 0 );
+ VERIFY( b1.get() == &test );
+
+ std::shared_ptr<bool> b2(b1);
+ VERIFY( b2.use_count() == 0 );
+ VERIFY( b1.get() == b2.get() );
+
+ return 0;
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a(new A);
+ std::shared_ptr<int> i1(a, &a->i);
+ VERIFY( i1.use_count() == 2 );
+
+ std::shared_ptr<int> i2(i1);
+ VERIFY( i2.use_count() == 3 );
+ VERIFY( i2.get() == &a->i );
+
+ return 0;
+}
+
+int
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<B> b(new B);
+ std::shared_ptr<A> a1(b, b.get());
+ std::shared_ptr<A> a2(b, &b->a);
+ VERIFY( a2.use_count() == 3 );
+ VERIFY( a1 == b );
+ VERIFY( a2 != b );
+ VERIFY( a1.get() != a2.get() );
+
+ std::shared_ptr<A> a3(a1);
+ VERIFY( a3 == b );
+
+ a3 = a2;
+ VERIFY( a3.get() == &b->a );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc.cc
new file mode 100644
index 00000000000..10ee34b5a6b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc.cc
@@ -0,0 +1,104 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::tracker_allocator_counter;
+using __gnu_test::tracker_allocator;
+
+struct A { };
+void deletefunc(A* p) { delete p; }
+struct D
+{
+ void operator()(A* p) { delete p; ++delete_count; }
+ static long delete_count;
+};
+long D::delete_count = 0;
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Construction with allocator
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ tracker_allocator_counter::reset();
+
+ std::shared_ptr<A> p1(new A, deletefunc, tracker_allocator<A>());
+ std::size_t const sz = tracker_allocator_counter::get_allocation_count();
+ VERIFY( sz > 0 );
+ {
+ std::shared_ptr<A> p2(p1);
+ VERIFY( p2.use_count() == 2 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == sz );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() == 0 );
+ }
+ VERIFY( p1.use_count() == 1 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == sz );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() == 0 );
+ p1.reset();
+ VERIFY( p1.use_count() == 0 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == sz );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() == sz );
+
+ return 0;
+}
+
+// Construction with allocator
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+ tracker_allocator_counter::reset();
+
+ std::shared_ptr<A> p1(new A, deletefunc, tracker_allocator<A>());
+ std::size_t const sz1 = tracker_allocator_counter::get_allocation_count();
+ VERIFY( sz1 > 0 );
+ std::shared_ptr<A> p2(new A, D(), tracker_allocator<A>());
+ std::size_t const sz2 = tracker_allocator_counter::get_allocation_count();
+ VERIFY( sz2 > sz1 );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() == 0 );
+ p1 = p2;
+ VERIFY( p2.use_count() == 2 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == sz2 );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() == sz1 );
+ p1.reset();
+ VERIFY( p2.use_count() == 1 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == sz2 );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() == sz1 );
+ p2.reset();
+ VERIFY( tracker_allocator_counter::get_allocation_count() == sz2 );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() == sz2 );
+ VERIFY( D::delete_count == 1 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc
new file mode 100644
index 00000000000..b82bcfb82f6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Construction from auto_ptr
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::auto_ptr<A> a(new A);
+ std::shared_ptr<A> a2(a);
+ VERIFY( a.get() == 0 );
+ VERIFY( a2.get() != 0 );
+ VERIFY( a2.use_count() == 1 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc
new file mode 100644
index 00000000000..3f9275ac114
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc
@@ -0,0 +1,49 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.const]
+
+// Construction from const auto_ptr
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::auto_ptr<A> a;
+ std::shared_ptr<A> p(a); // { dg-error "no match" }
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
+// { dg-excess-errors "candidates are" }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/copy.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/copy.cc
new file mode 100644
index 00000000000..b802e4366a3
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/copy.cc
@@ -0,0 +1,137 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() { ++ctor_count; }
+ virtual ~A() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long A::ctor_count = 0;
+long A::dtor_count = 0;
+
+struct B : A
+{
+ B() { ++ctor_count; }
+ virtual ~B() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long B::ctor_count = 0;
+long B::dtor_count = 0;
+
+void deleter(A* p) { delete p; }
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ B::ctor_count = 0;
+ B::dtor_count = 0;
+ }
+};
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Copy construction
+int test01()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a1;
+ std::shared_ptr<A> a2(a1);
+ VERIFY( a2.use_count() == 0 );
+ VERIFY( A::ctor_count == 0 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 0 );
+ VERIFY( B::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+test02()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a1(new A);
+ std::shared_ptr<A> a2(a1);
+ VERIFY( a2.use_count() == 2 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 0 );
+ VERIFY( B::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+test03()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<B> b(new B);
+ std::shared_ptr<A> a(b);
+ VERIFY( a.use_count() == 2 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+test04()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<B> b(new B, &deleter);
+ std::shared_ptr<A> a(b);
+ VERIFY( a.use_count() == 2 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/default.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/default.cc
new file mode 100644
index 00000000000..b6c326b4035
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/default.cc
@@ -0,0 +1,47 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Default construction
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+ VERIFY( a.get() == 0 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/move.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/move.cc
new file mode 100644
index 00000000000..065c2555ef6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/move.cc
@@ -0,0 +1,165 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// TR1 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <utility>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() { ++ctor_count; }
+ virtual ~A() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long A::ctor_count = 0;
+long A::dtor_count = 0;
+
+struct B : A
+{
+ B() { ++ctor_count; }
+ virtual ~B() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long B::ctor_count = 0;
+long B::dtor_count = 0;
+
+struct D
+{
+ void operator()(B* p) const { delete p; ++delete_count; }
+ static long delete_count;
+};
+long D::delete_count = 0;
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ B::ctor_count = 0;
+ B::dtor_count = 0;
+ D::delete_count = 0;
+ }
+};
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Rvalue construction
+int test01()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a1;
+ std::shared_ptr<A> a2(std::move(a1));
+ VERIFY( a1.use_count() == 0 );
+ VERIFY( a2.use_count() == 0 );
+ VERIFY( A::ctor_count == 0 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 0 );
+ VERIFY( B::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+test02()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a1(new A);
+ std::shared_ptr<A> a2(std::move(a1));
+ VERIFY( a1.use_count() == 0 );
+ VERIFY( a2.use_count() == 1 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+test03()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<B> b(new B);
+ std::shared_ptr<A> a(std::move(b));
+ VERIFY( b.use_count() == 0 );
+ VERIFY( a.use_count() == 1 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+test04()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<B> b(new B, D());
+ std::shared_ptr<A> a(std::move(b));
+ VERIFY( b.use_count() == 0 );
+ VERIFY( a.use_count() == 1 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+
+ a = std::move(std::shared_ptr<A>());
+ VERIFY( D::delete_count == 1 );
+ VERIFY( B::dtor_count == 1 );
+
+ return 0;
+}
+
+int
+test05()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a(std::move(std::shared_ptr<A>(new A)));
+ VERIFY( a.use_count() == 1 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ test05();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/pointer.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/pointer.cc
new file mode 100644
index 00000000000..98d17fb287a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/pointer.cc
@@ -0,0 +1,81 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+struct B : A { };
+
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Construction from pointer
+
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = 0;
+ std::shared_ptr<A> p(a);
+ VERIFY( p.get() == 0 );
+ VERIFY( p.use_count() == 1 );
+
+ return 0;
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = new A;
+ std::shared_ptr<A> p(a);
+ VERIFY( p.get() == a );
+ VERIFY( p.use_count() == 1 );
+
+ return 0;
+}
+
+
+int
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ B * const b = new B;
+ std::shared_ptr<A> p(b);
+ VERIFY( p.get() == b );
+ VERIFY( p.use_count() == 1 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr.cc
new file mode 100644
index 00000000000..b56fad236f1
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Construction from weak_ptr
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = new A;
+ std::shared_ptr<A> a1(a);
+ std::weak_ptr<A> wa(a1);
+ std::shared_ptr<A> a2(wa);
+ VERIFY( a2.get() == a );
+ VERIFY( a2.use_count() == wa.use_count() );
+
+ return 0;
+}
+
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr_expired.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr_expired.cc
new file mode 100644
index 00000000000..7facf9252bd
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr_expired.cc
@@ -0,0 +1,63 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do run { xfail *-*-* } }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.1 shared_ptr constructors [util.smartptr.shared.const]
+
+// Construction from expired weak_ptr
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a1(new A);
+ std::weak_ptr<A> wa(a1);
+ a1.reset();
+ VERIFY( wa.expired() );
+ try
+ {
+ std::shared_ptr<A> a2(wa);
+ }
+ catch (const std::bad_weak_ptr&)
+ {
+ // Expected.
+ __throw_exception_again;
+ }
+ catch (...)
+ {
+ // Failed.
+ }
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc
new file mode 100644
index 00000000000..cb789e0713d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc
@@ -0,0 +1,110 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::tracker_allocator_counter;
+using __gnu_test::tracker_allocator;
+
+struct A
+{
+ A(int i, double d, char c = '\0') : i(i), d(d), c(c) { ++ctor_count; }
+ explicit A(int i) : i(i), d(), c() { ++ctor_count; }
+ A() : i(), d(), c() { ++ctor_count; }
+ ~A() { ++dtor_count; }
+ int i;
+ double d;
+ char c;
+ static int ctor_count;
+ static int dtor_count;
+};
+int A::ctor_count = 0;
+int A::dtor_count = 0;
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ tracker_allocator_counter::reset();
+ }
+};
+
+// 20.6.6.2.6 shared_ptr creation [util.smartptr.shared.create]
+
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ reset_count_struct __attribute__((unused)) reset;
+
+ {
+ std::shared_ptr<A> p1 = std::allocate_shared<A>(tracker_allocator<A>());
+ VERIFY( p1.get() != 0 );
+ VERIFY( p1.use_count() == 1 );
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() > 0 );
+ }
+ VERIFY( A::ctor_count == A::dtor_count );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count() );
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+ reset_count_struct __attribute__((unused)) reset;
+
+ std::shared_ptr<A> p1;
+
+ p1 = std::allocate_shared<A>(tracker_allocator<A>(), 1);
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() > 0 );
+
+ p1 = std::allocate_shared<A>(tracker_allocator<A>(), 1, 2.0);
+ VERIFY( A::ctor_count == 2 );
+ VERIFY( A::dtor_count == 1 );
+ VERIFY( tracker_allocator_counter::get_deallocation_count() > 0 );
+
+ p1 = std::allocate_shared<A>(tracker_allocator<A>(), 1, 2.0, '3');
+ VERIFY( A::ctor_count == 3 );
+ VERIFY( A::dtor_count == 2 );
+ VERIFY( p1->i == 1 );
+ VERIFY( p1->d == 2.0 );
+ VERIFY( p1->c == '3' );
+
+ p1 = std::shared_ptr<A>();
+ VERIFY( A::ctor_count == A::dtor_count );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count() );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/dr402.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/dr402.cc
new file mode 100644
index 00000000000..b9e6fde0eac
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/dr402.cc
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <new>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ void* operator new(size_t n) { return new char[sizeof(A)]; }
+ void operator delete(void* p, size_t) { delete (char*)p; }
+};
+
+// 20.6.6.2.6 shared_ptr creation [util.smartptr.shared.create]
+
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p = std::make_shared<A>();
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/make.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/make.cc
new file mode 100644
index 00000000000..2d763c109e1
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/make.cc
@@ -0,0 +1,100 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A(int i, double d, char c = '\0') : i(i), d(d), c(c) { ++ctor_count; }
+ explicit A(int i) : i(i), d(), c() { ++ctor_count; }
+ A() : i(), d(), c() { ++ctor_count; }
+ ~A() { ++dtor_count; }
+ int i;
+ double d;
+ char c;
+ static int ctor_count;
+ static int dtor_count;
+};
+int A::ctor_count = 0;
+int A::dtor_count = 0;
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ }
+};
+
+// 20.6.6.2.6 shared_ptr creation [util.smartptr.shared.create]
+
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ reset_count_struct __attribute__((unused)) reset;
+
+ {
+ std::shared_ptr<A> p1 = std::make_shared<A>();
+ VERIFY( p1.get() != 0 );
+ VERIFY( p1.use_count() == 1 );
+ VERIFY( A::ctor_count == 1 );
+ }
+ VERIFY( A::ctor_count == A::dtor_count );
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+ reset_count_struct __attribute__((unused)) reset;
+
+ std::shared_ptr<A> p1;
+
+ p1 = std::make_shared<A>(1);
+ VERIFY( A::ctor_count == 1 );
+
+ p1 = std::make_shared<A>(1, 2.0);
+ VERIFY( A::ctor_count == 2 );
+ VERIFY( A::dtor_count == 1 );
+
+ p1 = std::make_shared<A>(1, 2.0, '3');
+ VERIFY( A::ctor_count == 3 );
+ VERIFY( A::dtor_count == 2 );
+ VERIFY( p1->i == 1 );
+ VERIFY( p1->d == 2.0 );
+ VERIFY( p1->c == '3' );
+
+ p1 = std::shared_ptr<A>();
+ VERIFY( A::ctor_count == A::dtor_count );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/dest/dest.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/dest/dest.cc
new file mode 100644
index 00000000000..f3e6b813016
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/dest/dest.cc
@@ -0,0 +1,135 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() { ++ctor_count; }
+ ~A() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long A::ctor_count = 0;
+long A::dtor_count = 0;
+
+struct B : A
+{
+ B() { ++ctor_count; }
+ ~B() { ++dtor_count; }
+ static long ctor_count;
+ static long dtor_count;
+};
+long B::ctor_count = 0;
+long B::dtor_count = 0;
+
+struct D
+{
+ void operator()(const B* p) { delete p; ++delete_count; }
+ static long delete_count;
+};
+long D::delete_count = 0;
+
+struct reset_count_struct
+{
+ ~reset_count_struct()
+ {
+ A::ctor_count = 0;
+ A::dtor_count = 0;
+ B::ctor_count = 0;
+ B::dtor_count = 0;
+ D::delete_count = 0;
+ }
+};
+
+
+// 20.6.6.2.2 shared_ptr destructor [util.smartptr.shared.dest]
+
+// empty shared_ptr
+int
+test01()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ {
+ std::shared_ptr<A> a;
+ }
+ VERIFY( A::ctor_count == 0 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 0 );
+ VERIFY( B::dtor_count == 0 );
+ VERIFY( D::delete_count == 0 );
+
+ return 0;
+}
+
+// shared ownership
+int
+test02()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> a;
+ {
+ a = std::shared_ptr<A>(new B, D());
+ }
+ VERIFY( A::ctor_count == 1 );
+ VERIFY( A::dtor_count == 0 );
+ VERIFY( B::ctor_count == 1 );
+ VERIFY( B::dtor_count == 0 );
+ VERIFY( D::delete_count == 0 );
+
+ return 0;
+}
+
+// exclusive ownership
+int
+test03()
+{
+ reset_count_struct __attribute__((unused)) reset;
+ bool test __attribute__((unused)) = true;
+
+ {
+ std::shared_ptr<A> a1(new B);
+ std::shared_ptr<A> a2(new B, D());
+ }
+ VERIFY( A::ctor_count == 2 );
+ VERIFY( A::dtor_count == 2 );
+ VERIFY( B::ctor_count == 2 );
+ VERIFY( B::dtor_count == 2 );
+ VERIFY( D::delete_count == 1 );
+
+ return 0;
+}
+
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/misc/24595.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/24595.cc
new file mode 100644
index 00000000000..e35765638af
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/24595.cc
@@ -0,0 +1,41 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+using std::get_deleter;
+
+// libstdc++/24595
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<int> sp;
+ VERIFY( !get_deleter<void(*)(int*)>(sp) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/misc/io.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/io.cc
new file mode 100644
index 00000000000..45d9ad808ac
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/io.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.8 shared_ptr I/O [util.smartptr.shared.io]
+
+// operator<<
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p(new A);
+ std::ostringstream buf;
+ buf << p;
+ const std::string s = buf.str();
+ buf.str("");
+ buf << p.get();
+ VERIFY( s == buf.str() );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/misc/swap.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/swap.cc
new file mode 100644
index 00000000000..f2e0468dad5
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/misc/swap.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.9 shared_ptr specialized algorithms [util.smartptr.shared.spec]
+
+// std::swap
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a1 = new A;
+ A * const a2 = new A;
+ std::shared_ptr<A> p1(a1);
+ std::shared_ptr<A> p2(a2);
+ std::swap(p1, p2);
+ VERIFY( p1.get() == a2 );
+ VERIFY( p2.get() == a1 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/24805.cc
index 7e54a738fe4..b555bf58f1d 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/24805.cc
@@ -1,7 +1,7 @@
// { dg-options "-std=gnu++0x" }
// { dg-do compile }
-// Copyright (C) 2007 Free Software Foundation
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -14,11 +14,18 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02110-1301, USA.
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
#include <memory>
-template class std::shared_ptr<int>;
+// 20.6.6.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
+
+// swap
+
+// libstdc++/24805
+using std::swap;
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset.cc
new file mode 100644
index 00000000000..c7349469bfa
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset.cc
@@ -0,0 +1,90 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+struct B : A { };
+struct D
+{
+ void operator()(B* p) { delete p; ++delete_count; }
+ static long delete_count;
+};
+long D::delete_count = 0;
+
+// 20.6.6.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
+
+// reset
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = new A;
+ std::shared_ptr<A> p1(a);
+ std::shared_ptr<A> p2(p1);
+ p1.reset();
+ VERIFY( p1.get() == 0 );
+ VERIFY( p2.get() == a );
+
+ return 0;
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = new A;
+ B * const b = new B;
+ std::shared_ptr<A> p1(a);
+ std::shared_ptr<A> p2(p1);
+ p1.reset(b);
+ VERIFY( p1.get() == b );
+ VERIFY( p2.get() == a );
+
+ return 0;
+}
+
+int
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ {
+ std::shared_ptr<A> p1;
+ p1.reset(new B, D());
+ }
+ VERIFY( D::delete_count == 1 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_alloc.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_alloc.cc
new file mode 100644
index 00000000000..04d90519383
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_alloc.cc
@@ -0,0 +1,64 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using __gnu_test::tracker_allocator_counter;
+using __gnu_test::tracker_allocator;
+
+struct A { };
+struct B : A { };
+struct D
+{
+ void operator()(B* p) { delete p; ++delete_count; }
+ static long delete_count;
+};
+long D::delete_count = 0;
+
+// 20.6.6.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
+
+// Reset with allocator
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ tracker_allocator_counter::reset();
+
+ {
+ std::shared_ptr<A> p1;
+ p1.reset(new B, D(), tracker_allocator<B>());
+ VERIFY( tracker_allocator_counter::get_allocation_count() > 0 );
+ }
+ VERIFY( D::delete_count == 1 );
+ VERIFY( tracker_allocator_counter::get_allocation_count() == tracker_allocator_counter::get_deallocation_count() );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_neg.cc
new file mode 100644
index 00000000000..16773539879
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_neg.cc
@@ -0,0 +1,48 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
+
+// reset
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::shared_ptr<A> p1(new A);
+ p1.reset(); // { dg-error "discards qualifiers" }
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap.cc
new file mode 100644
index 00000000000..5c18e65a55e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
+
+// swap
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a1 = new A;
+ A * const a2 = new A;
+ std::shared_ptr<A> p1(a1);
+ std::shared_ptr<A> p2(a2);
+ p1.swap(p2);
+ VERIFY( p1.get() == a2 );
+ VERIFY( p2.get() == a1 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_neg.cc
new file mode 100644
index 00000000000..995cfc0b40c
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_neg.cc
@@ -0,0 +1,49 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
+
+// swap
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::shared_ptr<A> p1(new A);
+ std::shared_ptr<A> p2(new A);
+ p1.swap(p2); // { dg-error "discards qualifiers" }
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc
new file mode 100644
index 00000000000..9efe26fc28c
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc
@@ -0,0 +1,82 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.5 shared_ptr observers [util.smartptr.shared.obs]
+
+// conversion to bool
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::shared_ptr<A> p1;
+ VERIFY( p1 == false );
+ const std::shared_ptr<A> p2(p1);
+ VERIFY( p2 == false );
+
+ return 0;
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p1(new A);
+ VERIFY( p1 );
+ std::shared_ptr<A> p2(p1);
+ VERIFY( p2 );
+ p1.reset();
+ VERIFY( !p1 );
+ VERIFY( p2 );
+
+ return 0;
+}
+
+int
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p1(new A);
+ std::shared_ptr<A> p2(p1);
+ p2.reset(new A);
+ VERIFY( p1 );
+ VERIFY( p2 );
+
+ return 0;
+}
+
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/get.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/get.cc
new file mode 100644
index 00000000000..c64ed38fc70
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/get.cc
@@ -0,0 +1,82 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A
+{
+ A() : i() {}
+ int i;
+};
+
+// 20.6.6.2.5 shared_ptr observers [util.smartptr.shared.obs]
+
+// get
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = new A;
+ const std::shared_ptr<A> p(a);
+ VERIFY( p.get() == a );
+
+ return 0;
+}
+
+// operator*
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = new A;
+ const std::shared_ptr<A> p(a);
+ VERIFY( &*p == a );
+
+ return 0;
+}
+
+
+// operator->
+int
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ A * const a = new A;
+ const std::shared_ptr<A> p(a);
+ VERIFY( &p->i == &a->i );
+
+ return 0;
+}
+
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/unique.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/unique.cc
new file mode 100644
index 00000000000..de7ab15a7b0
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/unique.cc
@@ -0,0 +1,82 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+
+// 20.6.6.2.5 shared_ptr observers [util.smartptr.shared.obs]
+
+// unique
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::shared_ptr<A> p1;
+ VERIFY( !p1.unique() );
+ const std::shared_ptr<A> p2(p1);
+ VERIFY( !p1.unique() );
+
+ return 0;
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p1(new A);
+ VERIFY( p1.unique() );
+ std::shared_ptr<A> p2(p1);
+ VERIFY( !p1.unique() );
+ p1.reset();
+ VERIFY( !p1.unique() );
+ VERIFY( p2.unique() );
+
+ return 0;
+}
+
+int
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p1(new A);
+ std::shared_ptr<A> p2(p1);
+ p2.reset(new A);
+ VERIFY( p1.unique() );
+ VERIFY( p2.unique() );
+
+ return 0;
+}
+
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/use_count.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/use_count.cc
new file mode 100644
index 00000000000..8e074a8b888
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/use_count.cc
@@ -0,0 +1,81 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+struct A { };
+struct B : A { };
+
+// 20.6.6.2.5 shared_ptr observers [util.smartptr.shared.obs]
+
+// use_count
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::shared_ptr<A> p1;
+ VERIFY( p1.use_count() == 0 );
+ const std::shared_ptr<A> p2(p1);
+ VERIFY( p1.use_count() == 0 );
+
+ return 0;
+}
+
+int
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p1(new A);
+ std::shared_ptr<A> p2(p1);
+ p1.reset();
+ VERIFY( p1.use_count() == 0 );
+ VERIFY( p2.use_count() == 1 );
+
+ return 0;
+}
+
+int
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::shared_ptr<A> p1(new A);
+ std::shared_ptr<A> p2(p1);
+ p2.reset(new B);
+ VERIFY( p1.use_count() == 1 );
+ VERIFY( p2.use_count() == 1 );
+
+ return 0;
+}
+
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc
new file mode 100644
index 00000000000..880c38ab893
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+using std::shared_ptr;
+template class shared_ptr<int>;
+template class shared_ptr<void>;
+template class shared_ptr<ClassType>;
+template class shared_ptr<IncompleteClass>;
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc
new file mode 100644
index 00000000000..293f54881c4
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc
@@ -0,0 +1,35 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_tr1.h>
+
+// Check the _S_single lock policy can be instantiated. For a thread-enabled
+// library this checks the templates can be instantiated for non-default
+// lock policy, for a single-threaded lib this is redundant but harmless.
+using namespace __gnu_test;
+using std::__shared_ptr;
+using std::_S_single;
+template class __shared_ptr<int, _S_single>;
+template class __shared_ptr<ClassType, _S_single>;
+template class __shared_ptr<IncompleteClass, _S_single>;
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc
new file mode 100644
index 00000000000..c806a0e1293
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc
@@ -0,0 +1,194 @@
+// Copyright (C) 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options "-pthread -std=gnu++0x" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options "-pthreads -std=gnu++0x" { target *-*-solaris* } }
+
+#include <memory>
+#include <random>
+#include <vector>
+#include <testsuite_hooks.h>
+#include <iostream>
+#include <cstdlib>
+
+#include <pthread.h>
+
+#ifdef _GLIBCXX_HAVE_UNISTD_H
+#include <unistd.h> // To test for _POSIX_THREAD_PRIORITY_SCHEDULING
+#endif
+
+/* This (brute-force) tests the atomicity and thus thread safety of the
+ * shared_ptr <- weak_ptr
+ * assignment operation by allocating a test object, retrieving a weak
+ * reference to it, and letting a number of threads repeatedly create strong
+ * references from the weak reference.
+ * Specifically, this tests the function _Sp_counted_base<true>::add_ref_lock()
+ */
+
+
+const unsigned int HAMMER_MAX_THREADS = 10;
+const unsigned int POOL_SIZE = 1000;
+const unsigned long HAMMER_REPEAT = 100000;
+const unsigned long KILL_ONE_IN = 1000;
+
+struct A
+ {
+ static _Atomic_word counter;
+ A()
+ {
+ __gnu_cxx::__atomic_add(&counter, 1);
+ }
+ ~A()
+ {
+ __gnu_cxx::__atomic_add(&counter, -1);
+ }
+ };
+
+_Atomic_word A::counter = 0;
+
+typedef std::shared_ptr<A> sp_A_t;
+typedef std::weak_ptr<A> wp_A_t;
+
+typedef std::vector<sp_A_t> sp_vector_t;
+typedef std::vector<wp_A_t> wp_vector_t;
+
+struct shared_and_weak_pools
+{
+ sp_vector_t& shared_pool;
+ wp_vector_t& weak_pool;
+
+ shared_and_weak_pools(sp_vector_t& _shared_pool, wp_vector_t& _weak_pool)
+ : shared_pool(_shared_pool), weak_pool(_weak_pool)
+ { }
+};
+
+void* thread_hammer_and_kill(void* opaque_pools)
+{
+ shared_and_weak_pools& pools = *static_cast<shared_and_weak_pools*>(opaque_pools);
+ // Using the same parameters as in the RNG test cases.
+ std::mersenne_twister<
+ unsigned long, 32, 624, 397, 31,
+ 0x9908b0dful, 11, 7,
+ 0x9d2c5680ul, 15,
+ 0xefc60000ul, 18> rng;
+
+ sp_vector_t::iterator cur_shared = pools.shared_pool.begin();
+ wp_vector_t::iterator cur_weak = pools.weak_pool.begin();
+
+ for (unsigned int i = 0; i < HAMMER_REPEAT; ++i)
+ {
+ try
+ {
+ sp_A_t strong(*cur_weak);
+ }
+ catch (std::bad_weak_ptr& exception)
+ {
+ ++cur_weak;
+ if (cur_weak == pools.weak_pool.end())
+ break;
+ }
+
+ if (rng() % KILL_ONE_IN == 0)
+ {
+ cur_shared->reset();
+ ++cur_shared;
+ }
+ }
+ return 0;
+}
+
+void* thread_hammer(void* opaque_weak)
+{
+ wp_vector_t& weak_pool = *static_cast<wp_vector_t*>(opaque_weak);
+ // Using the same parameters as in the RNG test cases.
+ std::mersenne_twister<
+ unsigned long, 32, 624, 397, 31,
+ 0x9908b0dful, 11, 7,
+ 0x9d2c5680ul, 15,
+ 0xefc60000ul, 18> rng;
+ wp_vector_t::iterator cur_weak = weak_pool.begin();
+
+ for (unsigned int i = 0; i < HAMMER_REPEAT; ++i)
+ {
+ try
+ {
+ sp_A_t strong(*cur_weak);
+ }
+ catch (std::bad_weak_ptr& exception)
+ {
+ ++cur_weak;
+ if (cur_weak == weak_pool.end())
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ sp_vector_t obj_pool(POOL_SIZE);
+
+ for(sp_vector_t::iterator cur = obj_pool.begin(); cur != obj_pool.end(); ++cur)
+ {
+ cur->reset(new A);
+ }
+ // Obtain weak references.
+ std::vector<wp_vector_t> weak_pool(HAMMER_MAX_THREADS, wp_vector_t(obj_pool.begin(), obj_pool.end()));
+
+ // Launch threads with pointer to weak reference.
+ pthread_t threads[HAMMER_MAX_THREADS];
+#if defined(__sun) && defined(__svr4__) && _XOPEN_VERSION >= 500
+ pthread_setconcurrency (HAMMER_MAX_THREADS);
+#endif
+
+ pthread_attr_t tattr;
+ int ret = pthread_attr_init(&tattr);
+
+ shared_and_weak_pools pools(obj_pool, weak_pool[0]);
+ pthread_create(threads, &tattr, thread_hammer_and_kill, static_cast<void*>(&pools));
+ for (unsigned int worker = 1; worker < HAMMER_MAX_THREADS; worker++)
+ {
+ if (pthread_create(&threads[worker], &tattr,
+ thread_hammer, static_cast<void*>(&weak_pool[worker])))
+ std::abort();
+ }
+ // Wait for threads to complete, then check integrity of reference.
+ void* status;
+ for (unsigned int worker = 0; worker < HAMMER_MAX_THREADS; worker++)
+ {
+ if (pthread_join(threads[worker], &status))
+ std::abort();
+ }
+ obj_pool.clear();
+
+ VERIFY( A::counter == 0 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc
new file mode 100644
index 00000000000..1515f65b443
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc
@@ -0,0 +1,196 @@
+// Copyright (C) 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
+
+#include <memory>
+#include <random>
+#include <vector>
+#include <testsuite_hooks.h>
+#include <iostream>
+#include <cstdlib>
+
+#include <pthread.h>
+
+#ifdef _GLIBCXX_HAVE_UNISTD_H
+#include <unistd.h> // To test for _POSIX_THREAD_PRIORITY_SCHEDULING
+#endif
+
+/* This (brute-force) tests the atomicity and thus thread safety of the
+ * shared_ptr <- weak_ptr
+ * assignment operation by allocating a test object, retrieving a weak
+ * reference to it, and letting a number of threads repeatedly create strong
+ * references from the weak reference.
+ * Specifically, this tests the function _Sp_counted_base<true>::add_ref_lock()
+ */
+
+
+const unsigned int HAMMER_MAX_THREADS = 10;
+const unsigned int POOL_SIZE = 1000;
+const unsigned long HAMMER_REPEAT = 100000;
+const unsigned long KILL_ONE_IN = 1000;
+
+struct A
+ {
+ static _Atomic_word counter;
+ A()
+ {
+ __gnu_cxx::__atomic_add(&counter, 1);
+ }
+ ~A()
+ {
+ __gnu_cxx::__atomic_add(&counter, -1);
+ }
+ };
+
+_Atomic_word A::counter = 0;
+
+using std::_S_mutex;
+
+typedef std::__shared_ptr<A, _S_mutex> sp_A_t;
+typedef std::__weak_ptr<A, _S_mutex> wp_A_t;
+
+typedef std::vector<sp_A_t> sp_vector_t;
+typedef std::vector<wp_A_t> wp_vector_t;
+
+struct shared_and_weak_pools
+{
+ sp_vector_t& shared_pool;
+ wp_vector_t& weak_pool;
+
+ shared_and_weak_pools(sp_vector_t& _shared_pool, wp_vector_t& _weak_pool)
+ : shared_pool(_shared_pool), weak_pool(_weak_pool)
+ { }
+};
+
+void* thread_hammer_and_kill(void* opaque_pools)
+{
+ shared_and_weak_pools& pools = *static_cast<shared_and_weak_pools*>(opaque_pools);
+ // Using the same parameters as in the RNG test cases.
+ std::mersenne_twister<
+ unsigned long, 32, 624, 397, 31,
+ 0x9908b0dful, 11, 7,
+ 0x9d2c5680ul, 15,
+ 0xefc60000ul, 18> rng;
+
+ sp_vector_t::iterator cur_shared = pools.shared_pool.begin();
+ wp_vector_t::iterator cur_weak = pools.weak_pool.begin();
+
+ for (unsigned int i = 0; i < HAMMER_REPEAT; ++i)
+ {
+ try
+ {
+ sp_A_t strong(*cur_weak);
+ }
+ catch (std::bad_weak_ptr& exception)
+ {
+ ++cur_weak;
+ if (cur_weak == pools.weak_pool.end())
+ break;
+ }
+
+ if (rng() % KILL_ONE_IN == 0)
+ {
+ cur_shared->reset();
+ ++cur_shared;
+ }
+ }
+ return 0;
+}
+
+void* thread_hammer(void* opaque_weak)
+{
+ wp_vector_t& weak_pool = *static_cast<wp_vector_t*>(opaque_weak);
+ // Using the same parameters as in the RNG test cases.
+ std::mersenne_twister<
+ unsigned long, 32, 624, 397, 31,
+ 0x9908b0dful, 11, 7,
+ 0x9d2c5680ul, 15,
+ 0xefc60000ul, 18> rng;
+ wp_vector_t::iterator cur_weak = weak_pool.begin();
+
+ for (unsigned int i = 0; i < HAMMER_REPEAT; ++i)
+ {
+ try
+ {
+ sp_A_t strong(*cur_weak);
+ }
+ catch (std::bad_weak_ptr& exception)
+ {
+ ++cur_weak;
+ if (cur_weak == weak_pool.end())
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ sp_vector_t obj_pool(POOL_SIZE);
+
+ for(sp_vector_t::iterator cur = obj_pool.begin(); cur != obj_pool.end(); ++cur)
+ {
+ cur->reset(new A);
+ }
+ // Obtain weak references.
+ std::vector<wp_vector_t> weak_pool(HAMMER_MAX_THREADS, wp_vector_t(obj_pool.begin(), obj_pool.end()));
+
+ // Launch threads with pointer to weak reference.
+ pthread_t threads[HAMMER_MAX_THREADS];
+#if defined(__sun) && defined(__svr4__) && _XOPEN_VERSION >= 500
+ pthread_setconcurrency (HAMMER_MAX_THREADS);
+#endif
+
+ pthread_attr_t tattr;
+ int ret = pthread_attr_init(&tattr);
+
+ shared_and_weak_pools pools(obj_pool, weak_pool[0]);
+ pthread_create(threads, &tattr, thread_hammer_and_kill, static_cast<void*>(&pools));
+ for (unsigned int worker = 1; worker < HAMMER_MAX_THREADS; worker++)
+ {
+ if (pthread_create(&threads[worker], &tattr,
+ thread_hammer, static_cast<void*>(&weak_pool[worker])))
+ std::abort();
+ }
+ // Wait for threads to complete, then check integrity of reference.
+ void* status;
+ for (unsigned int worker = 0; worker < HAMMER_MAX_THREADS; worker++)
+ {
+ if (pthread_join(threads[worker], &status))
+ std::abort();
+ }
+ obj_pool.clear();
+
+ VERIFY( A::counter == 0 );
+
+ return 0;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/lock/1.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/lock/1.cc
new file mode 100644
index 00000000000..a6506e379ef
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/weak_ptr/lock/1.cc
@@ -0,0 +1,37 @@
+// 2006-09-24 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.3 Template class weak_ptr [util.smartptr.weak]
+
+#include <memory>
+#include <testsuite_tr1.h>
+
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+int main()
+{
+ using __gnu_test::check_ret_type;
+ using std::weak_ptr;
+ using std::shared_ptr;
+
+ weak_ptr<int> wp;
+ check_ret_type<shared_ptr<int> >(wp.lock());
+}
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc
new file mode 100644
index 00000000000..ede053bb717
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2006, 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+using std::weak_ptr;
+template class weak_ptr<int>;
+template class weak_ptr<void>;
+template class weak_ptr<ClassType>;
+template class weak_ptr<IncompleteClass>;
diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc
new file mode 100644
index 00000000000..272ef4fe444
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
+
+#include <memory>
+#include <testsuite_tr1.h>
+
+// Check the _S_single lock policy can be instantiated. For a thread-enabled
+// library this checks the templates can be instantiated for non-default
+// lock policy, for a single-threaded lib this is redundant but harmless.
+using namespace __gnu_test;
+using std::__weak_ptr;
+using std::_S_single;
+template class __weak_ptr<int, _S_single>;
+template class __weak_ptr<void, _S_single>;
+template class __weak_ptr<ClassType, _S_single>;
+template class __weak_ptr<IncompleteClass, _S_single>;