OSDN Git Service

2007-12-15 Jonathan Wakely <jwakely-gcc@gmail.com>
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Dec 2007 22:28:29 +0000 (22:28 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Dec 2007 22:28:29 +0000 (22:28 +0000)
* 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

55 files changed:
libstdc++-v3/docs/html/17_intro/c++0x_status.html
libstdc++-v3/docs/html/20_util/shared_ptr.html [new file with mode: 0644]
libstdc++-v3/docs/html/documentation.html
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/boost_sp_shared_count.h [new file with mode: 0644]
libstdc++-v3/include/std/memory
libstdc++-v3/include/tr1/boost_sp_shared_count.h [new file with mode: 0644]
libstdc++-v3/include/tr1/memory
libstdc++-v3/include/tr1_impl/boost_shared_ptr.h
libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_rvalue_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/dr541.cc [moved from libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation.cc with 62% similarity]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/comparison/cmp.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/copy.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/default.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/pointer.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr_expired.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/creation/dr402.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/creation/make.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/dest/dest.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/misc/24595.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/misc/io.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/misc/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/24805.cc [moved from libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation.cc with 62% similarity]
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_alloc.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/observers/get.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/observers/unique.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/observers/use_count.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/weak_ptr/lock/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc [new file with mode: 0644]

index e4e07e0..cfc28ed 100644 (file)
@@ -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 (file)
index 0000000..6df2e6d
--- /dev/null
@@ -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>
+
index 0c7dda3..c5413de 100644 (file)
@@ -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 />
index 9eee090..a4a4d3e 100644 (file)
@@ -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 \
index 9b2fb03..3291fca 100644 (file)
@@ -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 (file)
index 0000000..75ee16d
--- /dev/null
@@ -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;
+    };
+}
index 89f680d..2e78e3f 100644 (file)
 #    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 (file)
index 0000000..a2de21f
--- /dev/null
@@ -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;
+    };
+}
+}
index 3cf92f4..134b5bd 100644 (file)
 #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
index c2ee1ca..53f8c0f 100644 (file)
  *  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 (file)
index 0000000..3cb4175
--- /dev/null
@@ -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 (file)
index 0000000..6f428ca
--- /dev/null
@@ -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 (file)
index 0000000..2a18b48
--- /dev/null
@@ -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 (file)
index 0000000..79bb73f
--- /dev/null
@@ -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 (file)
index 0000000..afa2849
--- /dev/null
@@ -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" }
@@ -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
 // 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 (file)
index 0000000..34c9f8d
--- /dev/null
@@ -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 (file)
index 0000000..983c70e
--- /dev/null
@@ -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 (file)
index 0000000..ab272d8
--- /dev/null
@@ -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 (file)
index 0000000..58ebded
--- /dev/null
@@ -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 (file)
index 0000000..55041f8
--- /dev/null
@@ -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 (file)
index 0000000..a707740
--- /dev/null
@@ -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 (file)
index 0000000..10ee34b
--- /dev/null
@@ -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 (file)
index 0000000..b82bcfb
--- /dev/null
@@ -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 (file)
index 0000000..3f9275a
--- /dev/null
@@ -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 (file)
index 0000000..b802e43
--- /dev/null
@@ -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 (file)
index 0000000..b6c326b
--- /dev/null
@@ -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 (file)
index 0000000..065c255
--- /dev/null
@@ -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 (file)
index 0000000..98d17fb
--- /dev/null
@@ -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 (file)
index 0000000..b56fad2
--- /dev/null
@@ -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 (file)
index 0000000..7facf92
--- /dev/null
@@ -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 (file)
index 0000000..cb789e0
--- /dev/null
@@ -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 (file)
index 0000000..b9e6fde
--- /dev/null
@@ -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 (file)
index 0000000..2d763c1
--- /dev/null
@@ -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 (file)
index 0000000..f3e6b81
--- /dev/null
@@ -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 (file)
index 0000000..e357656
--- /dev/null
@@ -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 (file)
index 0000000..45d9ad8
--- /dev/null
@@ -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 (file)
index 0000000..f2e0468
--- /dev/null
@@ -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;
+}
@@ -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
 // 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 (file)
index 0000000..c734946
--- /dev/null
@@ -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 (file)
index 0000000..04d9051
--- /dev/null
@@ -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 (file)
index 0000000..1677353
--- /dev/null
@@ -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 (file)
index 0000000..5c18e65
--- /dev/null
@@ -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 (file)
index 0000000..995cfc0
--- /dev/null
@@ -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 (file)
index 0000000..9efe26f
--- /dev/null
@@ -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 (file)
index 0000000..c64ed38
--- /dev/null
@@ -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 (file)
index 0000000..de7ab15
--- /dev/null
@@ -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 (file)
index 0000000..8e074a8
--- /dev/null
@@ -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 (file)
index 0000000..880c38a
--- /dev/null
@@ -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 (file)
index 0000000..293f548
--- /dev/null
@@ -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 (file)
index 0000000..c806a0e
--- /dev/null
@@ -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 (file)
index 0000000..1515f65
--- /dev/null
@@ -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 (file)
index 0000000..a6506e3
--- /dev/null
@@ -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 (file)
index 0000000..ede053b
--- /dev/null
@@ -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 (file)
index 0000000..272ef4f
--- /dev/null
@@ -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>;