mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-30 15:24:07 +08:00
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:
parent
5f0686bc40
commit
aaf0ca6f27
@ -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>
|
||||
|
419
libstdc++-v3/docs/html/20_util/shared_ptr.html
Normal file
419
libstdc++-v3/docs/html/20_util/shared_ptr.html
Normal 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 & 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<A> a(new A);
|
||||
shared_ptr<A> 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><ext/atomicity.h></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<T></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<Lp></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<Ptr, Deleter, Lp></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<Ptr></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<Ptr, Lp></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<Ptr, Deleter, Alloc></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<Tp, Alloc, Lp></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<Tp, Lp></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<A></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<_Sp_make_shared_tag>()</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<_S_single>.
|
||||
</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<_Sp_make_shared_tag>() 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>
|
||||
|
@ -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 />
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
378
libstdc++-v3/include/bits/boost_sp_shared_count.h
Normal file
378
libstdc++-v3/include/bits/boost_sp_shared_count.h
Normal 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;
|
||||
};
|
||||
}
|
@ -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
|
||||
|
214
libstdc++-v3/include/tr1/boost_sp_shared_count.h
Normal file
214
libstdc++-v3/include/tr1/boost_sp_shared_count.h
Normal 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;
|
||||
};
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
244
libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h
Normal file
244
libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h
Normal 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
|
||||
}
|
73
libstdc++-v3/testsuite/20_util/shared_ptr/assign/assign.cc
Normal file
73
libstdc++-v3/testsuite/20_util/shared_ptr/assign/assign.cc
Normal 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;
|
||||
}
|
86
libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc
Normal file
86
libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr.cc
Normal 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;
|
||||
}
|
@ -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" }
|
@ -0,0 +1,50 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2005, 2006, 2007 Free Software Foundation
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
// USA.
|
||||
|
||||
// 20.6.6.2 Template class shared_ptr [util.smartptr.shared]
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
struct A { };
|
||||
std::auto_ptr<A> source() { return std::auto_ptr<A>(); }
|
||||
|
||||
// 20.6.6.2.3 shared_ptr assignment [util.smartptr.shared.assign]
|
||||
|
||||
// Assignment from rvalue auto_ptr
|
||||
int
|
||||
test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
std::shared_ptr<A> a;
|
||||
a = source(); // { dg-error "no match" }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
// { dg-excess-errors "candidates are" }
|
@ -1,7 +1,7 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2007 Free Software Foundation
|
||||
// Copyright (C) 2006, 2007 Free Software Foundation
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@ -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);
|
||||
}
|
119
libstdc++-v3/testsuite/20_util/shared_ptr/assign/move.cc
Normal file
119
libstdc++-v3/testsuite/20_util/shared_ptr/assign/move.cc
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 }
|
46
libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc
Normal file
46
libstdc++-v3/testsuite/20_util/shared_ptr/casts/1.cc
Normal 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));
|
||||
}
|
85
libstdc++-v3/testsuite/20_util/shared_ptr/comparison/cmp.cc
Normal file
85
libstdc++-v3/testsuite/20_util/shared_ptr/comparison/cmp.cc
Normal 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;
|
||||
}
|
108
libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc
Normal file
108
libstdc++-v3/testsuite/20_util/shared_ptr/cons/alias.cc
Normal 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;
|
||||
}
|
104
libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc.cc
Normal file
104
libstdc++-v3/testsuite/20_util/shared_ptr/cons/alloc.cc
Normal 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;
|
||||
}
|
50
libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc
Normal file
50
libstdc++-v3/testsuite/20_util/shared_ptr/cons/auto_ptr.cc
Normal 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;
|
||||
}
|
@ -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" }
|
137
libstdc++-v3/testsuite/20_util/shared_ptr/cons/copy.cc
Normal file
137
libstdc++-v3/testsuite/20_util/shared_ptr/cons/copy.cc
Normal 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;
|
||||
}
|
47
libstdc++-v3/testsuite/20_util/shared_ptr/cons/default.cc
Normal file
47
libstdc++-v3/testsuite/20_util/shared_ptr/cons/default.cc
Normal 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;
|
||||
}
|
165
libstdc++-v3/testsuite/20_util/shared_ptr/cons/move.cc
Normal file
165
libstdc++-v3/testsuite/20_util/shared_ptr/cons/move.cc
Normal 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;
|
||||
}
|
81
libstdc++-v3/testsuite/20_util/shared_ptr/cons/pointer.cc
Normal file
81
libstdc++-v3/testsuite/20_util/shared_ptr/cons/pointer.cc
Normal 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;
|
||||
}
|
52
libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr.cc
Normal file
52
libstdc++-v3/testsuite/20_util/shared_ptr/cons/weak_ptr.cc
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
110
libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc
Normal file
110
libstdc++-v3/testsuite/20_util/shared_ptr/creation/alloc.cc
Normal 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();
|
||||
}
|
48
libstdc++-v3/testsuite/20_util/shared_ptr/creation/dr402.cc
Normal file
48
libstdc++-v3/testsuite/20_util/shared_ptr/creation/dr402.cc
Normal 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();
|
||||
}
|
100
libstdc++-v3/testsuite/20_util/shared_ptr/creation/make.cc
Normal file
100
libstdc++-v3/testsuite/20_util/shared_ptr/creation/make.cc
Normal 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();
|
||||
}
|
135
libstdc++-v3/testsuite/20_util/shared_ptr/dest/dest.cc
Normal file
135
libstdc++-v3/testsuite/20_util/shared_ptr/dest/dest.cc
Normal 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;
|
||||
}
|
41
libstdc++-v3/testsuite/20_util/shared_ptr/misc/24595.cc
Normal file
41
libstdc++-v3/testsuite/20_util/shared_ptr/misc/24595.cc
Normal 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;
|
||||
}
|
53
libstdc++-v3/testsuite/20_util/shared_ptr/misc/io.cc
Normal file
53
libstdc++-v3/testsuite/20_util/shared_ptr/misc/io.cc
Normal 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;
|
||||
}
|
52
libstdc++-v3/testsuite/20_util/shared_ptr/misc/swap.cc
Normal file
52
libstdc++-v3/testsuite/20_util/shared_ptr/misc/swap.cc
Normal 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;
|
||||
}
|
@ -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;
|
90
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset.cc
Normal file
90
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/reset.cc
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
52
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap.cc
Normal file
52
libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap.cc
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
82
libstdc++-v3/testsuite/20_util/shared_ptr/observers/get.cc
Normal file
82
libstdc++-v3/testsuite/20_util/shared_ptr/observers/get.cc
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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>;
|
@ -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>;
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
37
libstdc++-v3/testsuite/20_util/weak_ptr/lock/1.cc
Normal file
37
libstdc++-v3/testsuite/20_util/weak_ptr/lock/1.cc
Normal 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());
|
||||
}
|
@ -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>;
|
@ -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>;
|
Loading…
Reference in New Issue
Block a user