boost_shared_ptr.h: Add support for allocators, aliasing, make_shared and rvalue-references.

2007-12-15  Jonathan Wakely  <jwakely-gcc@gmail.com>

	* include/tr1_impl/boost_shared_ptr.h: Add support for allocators,
	aliasing, make_shared and rvalue-references. Move __shared_count
	and _Sp_counted_* classes to new headers.
	* include/tr1_impl/boost_sp_counted_base.h: New.
	* include/bits/boost_sp_shared_count.h: New.
	* include/tr1/boost_sp_shared_count.h: New.
	* include/std/memory, include/tr1/memory: Include new headers.
	* include/Makefile.am: Adjust.
	* include/Makefile.in: Regenerate.
	* docs/html/documentation.html: Link to shared_ptr notes.
	* docs/html/20_util/shared_ptr.html: New.
	* docs/html/17_intro/c++0x_status.html: Update shared_ptr status.
	* testsuite/20_util/shared_ptr/cons/alias.cc: New.
	* testsuite/20_util/shared_ptr/cons/alloc.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/move.cc: Likewise.
	* testsuite/20_util/shared_ptr/assign/move.cc: Likewise.
	* testsuite/20_util/shared_ptr/creation/alloc.cc: Likewise.
	* testsuite/20_util/shared_ptr/creation/make.cc: Likewise.
	* testsuite/20_util/shared_ptr/creation/dr402.cc: Likewise.
	* testsuite/20_util/shared_ptr/modifiers/reset_alloc.cc: Likewise.
	* testsuite/20_util/shared_ptr/assign/assign.cc: Duplicate tr1 test.
	* testsuite/20_util/shared_ptr/assign/auto_ptr.cc: Likewise.
	* testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc: Likewise.
	* testsuite/20_util/shared_ptr/assign/auto_ptr_rvalue_neg.cc: Likewise.
	* testsuite/20_util/shared_ptr/assign/dr541.cc: Likewise.
	* testsuite/20_util/shared_ptr/assign/shared_ptr.cc: Likewise.
	* testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc: Likewise.
	* testsuite/20_util/shared_ptr/casts/1.cc: Likewise.
	* testsuite/20_util/shared_ptr/comparison/cmp.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/auto_ptr.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/auto_ptr_neg.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/copy.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/default.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/pointer.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/weak_ptr.cc: Likewise.
	* testsuite/20_util/shared_ptr/cons/weak_ptr_expired.cc: Likewise.
	* testsuite/20_util/shared_ptr/dest/dest.cc: Likewise.
	* testsuite/20_util/shared_ptr/misc/24595.cc: Likewise.
	* testsuite/20_util/shared_ptr/misc/io.cc: Likewise.
	* testsuite/20_util/shared_ptr/misc/swap.cc: Likewise.
	* testsuite/20_util/shared_ptr/modifiers/24805.cc: Likewise.
	* testsuite/20_util/shared_ptr/modifiers/reset.cc: Likewise.
	* testsuite/20_util/shared_ptr/modifiers/reset_neg.cc: Likewise.
	* testsuite/20_util/shared_ptr/modifiers/swap.cc: Likewise.
	* testsuite/20_util/shared_ptr/modifiers/swap_neg.cc: Likewise.
	* testsuite/20_util/shared_ptr/observers/bool_conv.cc: Likewise.
	* testsuite/20_util/shared_ptr/observers/get.cc: Likewise.
	* testsuite/20_util/shared_ptr/observers/unique.cc: Likewise.
	* testsuite/20_util/shared_ptr/observers/use_count.cc: Likewise.
	* testsuite/20_util/shared_ptr/thread/default_weaktoshared.cc:
	Likewise.
	* testsuite/20_util/shared_ptr/thread/mutex_weaktoshared.cc: Likewise.
	* testsuite/20_util/shared_ptr/requirements/explicit_instantiation/
	1.cc: Likewise.
	* testsuite/20_util/shared_ptr/requirements/explicit_instantiation/
	2.cc: Likewise.
	* testsuite/20_util/shared_ptr/requirements/explicit_instantiation.cc:
	Remove.
	* testsuite/20_util/weak_ptr/lock/1.cc: Duplicate tr1 test.
	* testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc:
	Likewise.
	* testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc:
	Likewise.
	* testsuite/20_util/weak_ptr/requirements/explicit_instantiation.cc:
	Remove.

From-SVN: r130977
This commit is contained in:
Jonathan Wakely 2007-12-15 22:28:29 +00:00 committed by Jonathan Wakely
parent 5f0686bc40
commit aaf0ca6f27
55 changed files with 4845 additions and 356 deletions

View 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>

View File

@ -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>

View 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 />

View 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 \

View 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 \

View File

@ -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;
};
}

View File

@ -75,12 +75,16 @@
# include <backward/auto_ptr.h>
# endif
# if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
# include <tr1_impl/boost_sp_counted_base.h>
# include <bits/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
# else
# define _GLIBCXX_INCLUDE_AS_CXX0X
# define _GLIBCXX_BEGIN_NAMESPACE_TR1
# define _GLIBCXX_END_NAMESPACE_TR1
# define _GLIBCXX_TR1
# include <tr1_impl/boost_sp_counted_base.h>
# include <bits/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
# undef _GLIBCXX_TR1
# undef _GLIBCXX_END_NAMESPACE_TR1

View File

@ -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;
};
}
}

View File

@ -54,12 +54,16 @@
#include <tr1/type_traits>
#if defined(_GLIBCXX_INCLUDE_AS_TR1)
# include <tr1_impl/boost_sp_counted_base.h>
# include <tr1/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
#else
# define _GLIBCXX_INCLUDE_AS_TR1
# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
# define _GLIBCXX_END_NAMESPACE_TR1 }
# define _GLIBCXX_TR1 tr1::
# include <tr1_impl/boost_sp_counted_base.h>
# include <tr1/boost_sp_shared_count.h>
# include <tr1_impl/boost_shared_ptr.h>
# undef _GLIBCXX_TR1
# undef _GLIBCXX_END_NAMESPACE_TR1

View File

@ -51,330 +51,11 @@
* You should not attempt to use it directly.
*/
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_TR1
class bad_weak_ptr : public std::exception
{
public:
virtual char const*
what() const throw()
{ return "tr1::bad_weak_ptr"; }
};
// Substitute for bad_weak_ptr object in the case of -fno-exceptions.
inline void
__throw_bad_weak_ptr()
{
#if __EXCEPTIONS
throw bad_weak_ptr();
#else
__builtin_abort();
#endif
}
using __gnu_cxx::_Lock_policy;
using __gnu_cxx::__default_lock_policy;
using __gnu_cxx::_S_single;
using __gnu_cxx::_S_mutex;
using __gnu_cxx::_S_atomic;
template<typename _Tp>
struct _Sp_deleter
{
typedef void result_type;
typedef _Tp* argument_type;
void
operator()(_Tp* __p) const
{ delete __p; }
};
// Empty helper class except when the template argument is _S_mutex.
template<_Lock_policy _Lp>
class _Mutex_base
{
protected:
// The atomic policy uses fully-fenced builtins, single doesn't care.
enum { _S_need_barriers = 0 };
};
template<>
class _Mutex_base<_S_mutex>
: public __gnu_cxx::__mutex
{
protected:
// This policy is used when atomic builtins are not available.
// The replacement atomic operations might not have the necessary
// memory barriers.
enum { _S_need_barriers = 1 };
};
template<_Lock_policy _Lp = __default_lock_policy>
class _Sp_counted_base
: public _Mutex_base<_Lp>
{
public:
_Sp_counted_base()
: _M_use_count(1), _M_weak_count(1) { }
virtual
~_Sp_counted_base() // nothrow
{ }
// Called when _M_use_count drops to zero, to release the resources
// managed by *this.
virtual void
_M_dispose() = 0; // nothrow
// Called when _M_weak_count drops to zero.
virtual void
_M_destroy() // nothrow
{ delete this; }
virtual void*
_M_get_deleter(const std::type_info&) = 0;
void
_M_add_ref_copy()
{ __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
void
_M_add_ref_lock();
void
_M_release() // nothrow
{
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
{
_M_dispose();
// There must be a memory barrier between dispose() and destroy()
// to ensure that the effects of dispose() are observed in the
// thread that runs destroy().
// See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
if (_Mutex_base<_Lp>::_S_need_barriers)
{
_GLIBCXX_READ_MEM_BARRIER;
_GLIBCXX_WRITE_MEM_BARRIER;
}
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
-1) == 1)
_M_destroy();
}
}
void
_M_weak_add_ref() // nothrow
{ __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
void
_M_weak_release() // nothrow
{
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
{
if (_Mutex_base<_Lp>::_S_need_barriers)
{
// See _M_release(),
// destroy() must observe results of dispose()
_GLIBCXX_READ_MEM_BARRIER;
_GLIBCXX_WRITE_MEM_BARRIER;
}
_M_destroy();
}
}
long
_M_get_use_count() const // nothrow
{
// No memory barrier is used here so there is no synchronization
// with other threads.
return const_cast<const volatile _Atomic_word&>(_M_use_count);
}
private:
_Sp_counted_base(_Sp_counted_base const&);
_Sp_counted_base& operator=(_Sp_counted_base const&);
_Atomic_word _M_use_count; // #shared
_Atomic_word _M_weak_count; // #weak + (#shared != 0)
};
template<>
inline void
_Sp_counted_base<_S_single>::
_M_add_ref_lock()
{
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
{
_M_use_count = 0;
__throw_bad_weak_ptr();
}
}
template<>
inline void
_Sp_counted_base<_S_mutex>::
_M_add_ref_lock()
{
__gnu_cxx::__scoped_lock sentry(*this);
if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
{
_M_use_count = 0;
__throw_bad_weak_ptr();
}
}
template<>
inline void
_Sp_counted_base<_S_atomic>::
_M_add_ref_lock()
{
// Perform lock-free add-if-not-zero operation.
_Atomic_word __count;
do
{
__count = _M_use_count;
if (__count == 0)
__throw_bad_weak_ptr();
// Replace the current counter value with the old value + 1, as
// long as it's not changed meanwhile.
}
while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
__count + 1));
}
template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
class _Sp_counted_base_impl
: public _Sp_counted_base<_Lp>
{
public:
/**
* @brief
* @pre __d(__p) must not throw.
*/
_Sp_counted_base_impl(_Ptr __p, _Deleter __d)
: _M_ptr(__p), _M_del(__d) { }
virtual void
_M_dispose() // nothrow
{ _M_del(_M_ptr); }
virtual void*
_M_get_deleter(const std::type_info& __ti)
{ return __ti == typeid(_Deleter) ? &_M_del : 0; }
private:
_Sp_counted_base_impl(const _Sp_counted_base_impl&);
_Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
_Ptr _M_ptr; // copy constructor must not throw
_Deleter _M_del; // copy constructor must not throw
};
template<_Lock_policy _Lp = __default_lock_policy>
class __weak_count;
template<_Lock_policy _Lp = __default_lock_policy>
class __shared_count
{
public:
__shared_count()
: _M_pi(0) // nothrow
{ }
template<typename _Ptr, typename _Deleter>
__shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
{
try
{
_M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
}
catch(...)
{
__d(__p); // Call _Deleter on __p.
__throw_exception_again;
}
}
#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
// Special case for auto_ptr<_Tp> to provide the strong guarantee.
template<typename _Tp>
explicit
__shared_count(std::auto_ptr<_Tp>& __r)
: _M_pi(new _Sp_counted_base_impl<_Tp*,
_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
{ __r.release(); }
#endif
// Throw bad_weak_ptr when __r._M_get_use_count() == 0.
explicit
__shared_count(const __weak_count<_Lp>& __r);
~__shared_count() // nothrow
{
if (_M_pi != 0)
_M_pi->_M_release();
}
__shared_count(const __shared_count& __r)
: _M_pi(__r._M_pi) // nothrow
{
if (_M_pi != 0)
_M_pi->_M_add_ref_copy();
}
__shared_count&
operator=(const __shared_count& __r) // nothrow
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != _M_pi)
{
if (__tmp != 0)
__tmp->_M_add_ref_copy();
if (_M_pi != 0)
_M_pi->_M_release();
_M_pi = __tmp;
}
return *this;
}
void
_M_swap(__shared_count& __r) // nothrow
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
__r._M_pi = _M_pi;
_M_pi = __tmp;
}
long
_M_get_use_count() const // nothrow
{ return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
bool
_M_unique() const // nothrow
{ return this->_M_get_use_count() == 1; }
friend inline bool
operator==(const __shared_count& __a, const __shared_count& __b)
{ return __a._M_pi == __b._M_pi; }
friend inline bool
operator<(const __shared_count& __a, const __shared_count& __b)
{ return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
void*
_M_get_deleter(const std::type_info& __ti) const
{ return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
private:
friend class __weak_count<_Lp>;
_Sp_counted_base<_Lp>* _M_pi;
};
template<_Lock_policy _Lp>
class __weak_count
{
@ -453,6 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
_Sp_counted_base<_Lp>* _M_pi;
};
// now that __weak_count is defined we can define this constructor:
template<_Lock_policy _Lp>
inline
__shared_count<_Lp>::
@ -464,7 +146,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
else
__throw_bad_weak_ptr();
}
// Forward declarations.
template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
@ -507,9 +188,11 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
{ }
#ifdef _GLIBCXX_INCLUDE_AS_TR1
struct __static_cast_tag { };
struct __const_cast_tag { };
struct __dynamic_cast_tag { };
#endif
/**
* @class shared_ptr <tr1/memory>
@ -539,7 +222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Tp1>
explicit
__shared_ptr(_Tp1* __p)
: _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
: _M_ptr(__p), _M_refcount(__p)
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
@ -560,13 +243,58 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
*/
template<typename _Tp1, typename _Deleter>
__shared_ptr(_Tp1* __p, _Deleter __d)
: _M_ptr(__p), _M_refcount(__p, __d)
: _M_ptr(__p), _M_refcount(__p, __d)
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// TODO requires _Deleter CopyConstructible and __d(__p) well-formed
__enable_shared_from_this_helper(_M_refcount, __p, __p);
}
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
//
// Requirements: _Deleter's copy constructor and destructor must not throw
// _Alloc's copy constructor and destructor must not throw.
//
// __shared_ptr will release __p by calling __d(__p)
//
/** @brief Construct a %__shared_ptr that owns the pointer @a __p
* and the deleter @a __d.
* @param __p A pointer.
* @param __d A deleter.
* @param __a An allocator.
* @post use_count() == 1 && get() == __p
* @throw std::bad_alloc, in which case @a __d(__p) is called.
*/
template<typename _Tp1, typename _Deleter, typename _Alloc>
__shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
: _M_ptr(__p), _M_refcount(__p, __d, __a)
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// TODO requires _Deleter CopyConstructible and __d(__p) well-formed
__enable_shared_from_this_helper(_M_refcount, __p, __p);
}
/** @brief Constructs a %__shared_ptr instance that stores @a __p
* and shares ownership with @a __r.
* @param __r A %__shared_ptr.
* @param __p A pointer that will remain valid while @a *__r is valid.
* @post get() == __p && use_count() == __r.use_count()
*
* This can be used to construct a @c shared_ptr to a sub-object
* of an object managed by an existing @c shared_ptr.
*
* @code
* shared_ptr< pair<int,int> > pii(new pair<int,int>());
* shared_ptr<int> pi(pii, &pii->first);
* assert(pii.use_count() == 2);
* @endcode
*/
template<typename _Tp1>
__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p)
: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
{ }
#endif
// generated copy constructor, assignment, destructor are fine.
/** @brief If @a __r is empty, constructs an empty %__shared_ptr;
@ -580,6 +308,32 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
{ __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
/** @brief Move-constructs a %__shared_ptr instance from @a __r.
* @param __r A %__shared_ptr rvalue.
* @post *this contains the old value of @a __r, @a __r is empty.
*/
__shared_ptr(__shared_ptr&& __r)
: _M_ptr(__r._M_ptr), _M_refcount() // never throws
{
_M_refcount._M_swap(__r._M_refcount);
__r._M_ptr = 0;
}
/** @brief Move-constructs a %__shared_ptr instance from @a __r.
* @param __r A %__shared_ptr rvalue.
* @post *this contains the old value of @a __r, @a __r is empty.
*/
template<typename _Tp1>
__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
: _M_ptr(__r._M_ptr), _M_refcount() // never throws
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
_M_refcount._M_swap(__r._M_refcount);
__r._M_ptr = 0;
}
#endif
/** @brief Constructs a %__shared_ptr that shares ownership with @a __r
* and stores a copy of the pointer stored in @a __r.
* @param __r A weak_ptr.
@ -607,14 +361,15 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
__shared_ptr(std::auto_ptr<_Tp1>& __r)
: _M_ptr(__r.get()), _M_refcount()
{
// TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
// delete __r.release() well-formed
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// TODO requires _Tp1 is complete, delete __r.release() well-formed
_Tp1* __tmp = __r.get();
_M_refcount = __shared_count<_Lp>(__r);
__enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
}
#endif
#ifdef _GLIBCXX_INCLUDE_AS_TR1
template<typename _Tp1>
__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
@ -635,6 +390,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
if (_M_ptr == 0) // need to allocate new counter -- the cast failed
_M_refcount = __shared_count<_Lp>();
}
#endif
template<typename _Tp1>
__shared_ptr&
@ -655,6 +411,23 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
}
#endif
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
__shared_ptr&
operator=(__shared_ptr&& __r)
{
__shared_ptr(std::move(__r)).swap(*this);
return *this;
}
template<class _Tp1>
__shared_ptr&
operator=(__shared_ptr<_Tp1, _Lp>&& __r)
{
__shared_ptr(std::move(__r)).swap(*this);
return *this;
}
#endif
void
reset() // never throws
{ __shared_ptr().swap(*this); }
@ -673,10 +446,16 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
reset(_Tp1* __p, _Deleter __d)
{ __shared_ptr(__p, __d).swap(*this); }
// Allow class instantiation when _Tp is [cv-qual] void.
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
template<typename _Tp1, typename _Deleter, typename _Alloc>
void
reset(_Tp1* __p, _Deleter __d, const _Alloc& __a)
{ __shared_ptr(__p, __d, __a).swap(*this); }
// Allow class instantiation when _Tp is [cv-qual] void.
typename std::add_lvalue_reference<_Tp>::type
#else
// Allow class instantiation when _Tp is [cv-qual] void.
typename std::tr1::add_reference<_Tp>::type
#endif
operator*() const // never throws
@ -719,6 +498,26 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
_M_refcount._M_swap(__other._M_refcount);
}
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
protected:
// This constructor is non-standard, it is used by allocate_shared.
template<typename _Alloc, typename... _Args>
__shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
: _M_ptr()
, _M_refcount(__tag, (_Tp*)0, __a, std::forward<_Args>(__args)...)
{
// _M_ptr needs to point to the newly constructed object.
// This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
void * __p = _M_refcount._M_get_deleter(typeid(__tag));
_M_ptr = static_cast<_Tp*>(__p);
}
template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
typename... _Args>
friend __shared_ptr<_Tp1, _Lp1>
__allocate_shared(_Alloc __a, _Args&&... __args);
#endif
private:
void*
_M_get_deleter(const std::type_info& __ti) const
@ -768,9 +567,15 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
* attempting to delete the same object twice.
*/
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
__shared_ptr<_Tp, _Lp>
inline __shared_ptr<_Tp, _Lp>
static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
{ return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
{
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get()));
#else
return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag());
#endif
}
/** @warning The seemingly equivalent
* <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
@ -778,9 +583,15 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
* attempting to delete the same object twice.
*/
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
__shared_ptr<_Tp, _Lp>
inline __shared_ptr<_Tp, _Lp>
const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
{ return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
{
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get()));
#else
return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag());
#endif
}
/** @warning The seemingly equivalent
* <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
@ -788,9 +599,17 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
* attempting to delete the same object twice.
*/
template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
__shared_ptr<_Tp, _Lp>
inline __shared_ptr<_Tp, _Lp>
dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
{ return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
{
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
return __shared_ptr<_Tp, _Lp>(__r, __p);
return __shared_ptr<_Tp, _Lp>();
#else
return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag());
#endif
}
// 2.2.3.7 shared_ptr I/O
template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
@ -1011,10 +830,30 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
shared_ptr(_Tp1* __p, _Deleter __d)
: __shared_ptr<_Tp>(__p, __d) { }
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
template<typename _Tp1, typename _Deleter, typename _Alloc>
shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
: __shared_ptr<_Tp>(__p, __d, __a) { }
// Aliasing constructor
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p)
: __shared_ptr<_Tp>(__r, __p) { }
#endif
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r)
: __shared_ptr<_Tp>(__r) { }
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
shared_ptr(shared_ptr&& __r)
: __shared_ptr<_Tp>(std::move(__r)) { }
template<typename _Tp1>
shared_ptr(shared_ptr<_Tp1>&& __r)
: __shared_ptr<_Tp>(std::move(__r)) { }
#endif
template<typename _Tp1>
explicit
shared_ptr(const weak_ptr<_Tp1>& __r)
@ -1027,6 +866,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
: __shared_ptr<_Tp>(__r) { }
#endif
#ifdef _GLIBCXX_INCLUDE_AS_TR1
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
@ -1038,6 +878,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
#endif
template<typename _Tp1>
shared_ptr&
@ -1056,22 +897,72 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
return *this;
}
#endif
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
shared_ptr&
operator=(shared_ptr&& __r)
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
template<class _Tp1>
shared_ptr&
operator=(shared_ptr<_Tp1>&& __r)
{
this->__shared_ptr<_Tp>::operator=(std::move(__r));
return *this;
}
#endif
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
private:
// This constructor is non-standard, it is used by allocate_shared.
template<typename _Alloc, typename... _Args>
shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
: __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
{ }
template<typename _Tp1, typename _Alloc, typename... _Args>
friend shared_ptr<_Tp1>
allocate_shared(_Alloc __a, _Args&&... __args);
#endif
};
template<typename _Tp, typename _Tp1>
shared_ptr<_Tp>
inline shared_ptr<_Tp>
static_pointer_cast(const shared_ptr<_Tp1>& __r)
{ return shared_ptr<_Tp>(__r, __static_cast_tag()); }
{
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
#else
return shared_ptr<_Tp>(__r, __static_cast_tag());
#endif
}
template<typename _Tp, typename _Tp1>
shared_ptr<_Tp>
inline shared_ptr<_Tp>
const_pointer_cast(const shared_ptr<_Tp1>& __r)
{ return shared_ptr<_Tp>(__r, __const_cast_tag()); }
{
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get()));
#else
return shared_ptr<_Tp>(__r, __const_cast_tag());
#endif
}
template<typename _Tp, typename _Tp1>
shared_ptr<_Tp>
inline shared_ptr<_Tp>
dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
{ return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
{
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
return shared_ptr<_Tp>(__r, __p);
return shared_ptr<_Tp>();
#else
return shared_ptr<_Tp>(__r, __dynamic_cast_tag());
#endif
}
// The actual TR1 weak_ptr, with forwarding constructors and
@ -1173,5 +1064,57 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
mutable weak_ptr<_Tp> _M_weak_this;
};
#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
inline __shared_ptr<_Tp, _Lp>
__allocate_shared(_Alloc __a, _Args&&... __args)
{
return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(),
std::forward<_Alloc>(__a), std::forward<_Args>(__args)...);
}
template<typename _Tp, _Lock_policy _Lp, typename... _Args>
inline __shared_ptr<_Tp, _Lp>
__make_shared(_Args&&... __args)
{
typedef typename std::remove_const<_Tp>::type _Tp_nc;
return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
std::forward<_Args>(__args)...);
}
/** @brief Create an object that is owned by a shared_ptr.
* @param __a An allocator.
* @param __args Arguments for the @a _Tp object's constructor.
* @return A shared_ptr that owns the newly created object.
* @throw An exception thrown from @a _Alloc::allocate or from the
* constructor of @a _Tp.
*
* A copy of @a __a will be used to allocate memory for the shared_ptr
* and the new object.
*/
template<typename _Tp, typename _Alloc, typename... _Args>
inline shared_ptr<_Tp>
allocate_shared(_Alloc __a, _Args&&... __args)
{
return shared_ptr<_Tp>(_Sp_make_shared_tag(), std::forward<_Alloc>(__a),
std::forward<_Args>(__args)...);
}
/** @brief Create an object that is owned by a shared_ptr.
* @param __args Arguments for the @a _Tp object's constructor.
* @return A shared_ptr that owns the newly created object.
* @throw std::bad_alloc, or an exception thrown from the
* constructor of @a _Tp.
*/
template<typename _Tp, typename... _Args>
inline shared_ptr<_Tp>
make_shared(_Args&&... __args)
{
typedef typename std::remove_const<_Tp>::type _Tp_nc;
return allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
std::forward<_Args>(__args)...);
}
#endif
_GLIBCXX_END_NAMESPACE_TR1
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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" }

View File

@ -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" }

View File

@ -1,7 +1,7 @@
// { dg-options "-std=gnu++0x" }
// { dg-do compile }
// Copyright (C) 2007 Free Software Foundation
// Copyright (C) 2006, 2007 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -14,11 +14,18 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this library; see the file COPYING. If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02110-1301, USA.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
#include <memory>
template class std::weak_ptr<int>;
// DR 541. shared_ptr template assignment and void
void test01()
{
std::shared_ptr<void> p;
p.operator=<void>(p);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 }

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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" }

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,7 +1,7 @@
// { dg-options "-std=gnu++0x" }
// { dg-do compile }
// Copyright (C) 2007 Free Software Foundation
// Copyright (C) 2005, 2006, 2007 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -14,11 +14,18 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this library; see the file COPYING. If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02110-1301, USA.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
#include <memory>
template class std::shared_ptr<int>;
// 20.6.6.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
// swap
// libstdc++/24805
using std::swap;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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>;

View File

@ -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>;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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());
}

View File

@ -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>;

View File

@ -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>;