mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-10-05 20:21:04 +02:00
Compare commits
45 Commits
boost-1.33
...
boost-1.35
Author | SHA1 | Date | |
---|---|---|---|
|
e56e474e64 | ||
|
4ba016d29e | ||
|
60ae24f4ae | ||
|
dba6ebbb01 | ||
|
d2194e3b24 | ||
|
5ab6b24856 | ||
|
87c6b6b403 | ||
|
c66f0aeecc | ||
|
94db735438 | ||
|
d889751bc0 | ||
|
2f70e81b73 | ||
|
c464a07ab1 | ||
|
4a98c2931c | ||
|
ebc0af9147 | ||
|
db0969d97b | ||
|
7c477960d3 | ||
|
7e5d7011e6 | ||
|
75cd88112c | ||
|
6e120f4bf1 | ||
|
7ce5b55f5c | ||
|
f3e94d8ca0 | ||
|
c36e023162 | ||
|
00f744bf1e | ||
|
24d1e6f8dd | ||
|
ae0a48d544 | ||
|
e427716dc2 | ||
|
8c256502cc | ||
|
a86b2f7fbf | ||
|
a196f39cd0 | ||
|
90b5a3736a | ||
|
2d25f8f036 | ||
|
3771707bb7 | ||
|
239bb6d966 | ||
|
25ca855127 | ||
|
0127c06692 | ||
|
9edd3beebc | ||
|
92a027fbeb | ||
|
7880720bc1 | ||
|
235994873f | ||
|
7bfddbccf6 | ||
|
c6a4e93a05 | ||
|
ff7e027648 | ||
|
08f517b5b0 | ||
|
6b3f961542 | ||
|
0db2a88403 |
@@ -1,105 +1,88 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
<head>
|
<title>Smart Pointer Changes</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
<title>Smart Pointer Changes</title>
|
</head>
|
||||||
</head>
|
<body bgcolor="#ffffff" text="#000000">
|
||||||
|
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||||
<body bgcolor="#FFFFFF" text="#000000">
|
border="0"></A>Smart Pointer Changes</h1>
|
||||||
|
<p>The February 2002 change to the Boost smart pointers introduced a number of
|
||||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86">Smart
|
changes. Since the previous version of the smart pointers was in use for a long
|
||||||
Pointer Changes</h1>
|
time, it's useful to have a detailed list of what changed from a library user's
|
||||||
|
point of view.</p>
|
||||||
<p>The February 2002 change to the Boost smart pointers introduced a number
|
<p>Note that for compilers that don't support member templates well enough, a
|
||||||
of changes. Since the previous version of the smart pointers was in use for
|
separate implementation is used that lacks many of the new features and is more
|
||||||
a long time, it's useful to have a detailed list of what changed from a library
|
like the old version.</p>
|
||||||
user's point of view.</p>
|
<h2>Features Requiring Code Changes to Take Advantage</h2>
|
||||||
|
<ul>
|
||||||
<p>Note that for compilers that don't support member templates well enough,
|
<li>
|
||||||
a separate implementation is used that lacks many of the new features and is
|
The smart pointer class templates now each have their own header file. For
|
||||||
more like the old version.</p>
|
compatibility, the <a href="../../boost/smart_ptr.hpp"><boost/smart_ptr.hpp></a>
|
||||||
|
header now includes the headers for the four classic smart pointer class
|
||||||
<h2>Features Requiring Code Changes to Take Advantage</h2>
|
templates.
|
||||||
|
<li>
|
||||||
<ul>
|
The <b>weak_ptr</b>
|
||||||
|
template was added.
|
||||||
<li>The smart pointer class templates now each have their own header file.
|
<li>
|
||||||
For compatibility, the
|
The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that
|
||||||
<a href="../../boost/smart_ptr.hpp"><boost/smart_ptr.hpp></a>
|
the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
|
||||||
header now includes the headers for the four classic smart pointer class templates.</li>
|
destructor. This makes it easier to have shared_ptr members in classes without
|
||||||
|
explicit destructors.
|
||||||
<li>The <b>weak_ptr</b> template was added.</li>
|
<li>
|
||||||
|
A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
|
||||||
<li>The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that the pointed-to object's
|
<li>
|
||||||
destructor must be visible when instantiating the <b>shared_ptr</b> destructor.
|
<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
|
||||||
This makes it easier to have shared_ptr members in classes without explicit destructors.</li>
|
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
|
||||||
|
and <b>dynamic_cast</b>
|
||||||
<li>A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.</li>
|
do for pointers.
|
||||||
|
<li>
|
||||||
<li><b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
|
The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
|
||||||
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b> and
|
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
|
||||||
<b>dynamic_cast</b> do for pointers.</li>
|
Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
|
||||||
|
results in undefined behavior (an assertion, or eventually a double-delete if
|
||||||
<li>The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
|
assertions are off).
|
||||||
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
|
<li>
|
||||||
Calling <b>reset</b> with a pointer to the object that's already owned by the
|
The <b>BOOST_SMART_PTR_CONVERSION</b>
|
||||||
<b>shared_ptr</b> results in undefined behavior
|
feature has been removed.
|
||||||
(an assertion, or eventually a double-delete if assertions are off).</li>
|
<li>
|
||||||
|
<b>shared_ptr<void></b> is now allowed.</li>
|
||||||
<li>The <b>BOOST_SMART_PTR_CONVERSION</b> feature has been removed.</li>
|
</ul>
|
||||||
|
<h2>Features That Improve Robustness</h2>
|
||||||
<li><b>shared_ptr<void></b> is now allowed.</li>
|
<ul>
|
||||||
|
<li>
|
||||||
</ul>
|
The manipulation of use counts is now <a name="threadsafe">thread safe</a> on
|
||||||
|
Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
|
||||||
<h2>Features That Improve Robustness</h2>
|
<boost/detail/atomic_count.hpp></a>
|
||||||
|
file for details
|
||||||
<ul>
|
<li>
|
||||||
|
The new shared_ptr will always delete the object using the pointer it was
|
||||||
<li>The manipulation of use counts is now <a name="threadsafe">thread safe</a> on Windows, Linux, and platforms
|
originally constructed with. This prevents subtle problems that could happen if
|
||||||
that support pthreads. See the
|
the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did
|
||||||
<a href="../../boost/detail/atomic_count.hpp"><boost/detail/atomic_count.hpp></a>
|
not have a virtual destructor.</li>
|
||||||
file for details</li>
|
</ul>
|
||||||
|
<h2>Implementation Details</h2>
|
||||||
<li>The new shared_ptr will always delete the object using the pointer it was originally constructed with.
|
<ul>
|
||||||
This prevents subtle problems that could happen if the last <b>shared_ptr</b> was a pointer to a sub-object
|
<li>
|
||||||
of a class that did not have a virtual destructor.</li>
|
Some bugs in the assignment operator implementations and in <b>reset</b>
|
||||||
|
have been fixed by using the "copy and swap" idiom.
|
||||||
</ul>
|
<li>
|
||||||
|
Assertions have been added to check preconditions of various functions;
|
||||||
<h2>Implementation Details</h2>
|
however, since these use the new <a href="../../boost/assert.hpp"><boost/assert.hpp></a>
|
||||||
|
header, the assertions are disabled by default.
|
||||||
<ul>
|
<li>
|
||||||
|
The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
|
||||||
<li>Some bugs in the assignment operator implementations and in <b>reset</b>
|
overloads which accomplish the same thing without relying on undefined
|
||||||
have been fixed by using the "copy and swap" idiom.</li>
|
behavior.
|
||||||
|
<li>
|
||||||
<li>Assertions have been added to check preconditions of various functions;
|
The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>,
|
||||||
however, since these use the new
|
which has many of the same advantages for generic programming but does not
|
||||||
<a href="../../boost/assert.hpp"><boost/assert.hpp></a>
|
violate the C++ standard.</li>
|
||||||
header, the assertions are disabled by default.</li>
|
</ul>
|
||||||
|
<hr>
|
||||||
<li>The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
|
<p>Revised 1 February 2002</p>
|
||||||
overloads which accomplish the same thing without relying on undefined behavior.</li>
|
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
|
||||||
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
<li>The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, which
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
has many of the same advantages for generic programming but does not violate the C++ standard.</li>
|
</body>
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>Revised 1 February 2002</p>
|
|
||||||
|
|
||||||
<p>Copyright 2002 Darin Adler.
|
|
||||||
Permission to copy, use,
|
|
||||||
modify, sell and distribute this document is granted provided this copyright
|
|
||||||
notice appears in all copies. This document is provided "as is"
|
|
||||||
without express or implied warranty, and with no claim as to its suitability for
|
|
||||||
any purpose.</p>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@@ -7,10 +7,9 @@
|
|||||||
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
|
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
|
||||||
<table border="0" width="100%">
|
<table border="0" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td width="277">
|
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
|
||||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
|
|
||||||
</td>
|
</td>
|
||||||
<td align="middle">
|
<td align="center">
|
||||||
<h1>enable_shared_from_this.hpp</h1>
|
<h1>enable_shared_from_this.hpp</h1>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -85,9 +84,8 @@ public:
|
|||||||
</blockquote>
|
</blockquote>
|
||||||
<p>
|
<p>
|
||||||
<br>
|
<br>
|
||||||
<small>Copyright <20> 2002, 2003 by Peter Dimov. Permission to copy, use, modify, sell
|
<small>Copyright <20> 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
and distribute this document is granted provided this copyright notice appears
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
in all copies. This document is provided "as is" without express or implied
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -90,14 +90,30 @@ typedef long atomic_count;
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(BOOST_AC_USE_PTHREADS)
|
#elif defined(BOOST_AC_USE_PTHREADS)
|
||||||
|
|
||||||
# include <boost/detail/atomic_count_pthreads.hpp>
|
# include <boost/detail/atomic_count_pthreads.hpp>
|
||||||
|
|
||||||
|
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||||
|
|
||||||
|
# include <boost/detail/atomic_count_gcc_x86.hpp>
|
||||||
|
|
||||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||||
|
|
||||||
# include <boost/detail/atomic_count_win32.hpp>
|
# include <boost/detail/atomic_count_win32.hpp>
|
||||||
|
|
||||||
|
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||||
|
|
||||||
|
# include <boost/detail/atomic_count_sync.hpp>
|
||||||
|
|
||||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||||
|
|
||||||
# include <boost/detail/atomic_count_gcc.hpp>
|
# include <boost/detail/atomic_count_gcc.hpp>
|
||||||
|
|
||||||
#elif defined(BOOST_HAS_PTHREADS)
|
#elif defined(BOOST_HAS_PTHREADS)
|
||||||
|
|
||||||
# define BOOST_AC_USE_PTHREADS
|
# define BOOST_AC_USE_PTHREADS
|
||||||
# include <boost/detail/atomic_count_pthreads.hpp>
|
# include <boost/detail/atomic_count_pthreads.hpp>
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||||
|
84
include/boost/detail/atomic_count_gcc_x86.hpp
Normal file
84
include/boost/detail/atomic_count_gcc_x86.hpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// boost/detail/atomic_count_gcc_x86.hpp
|
||||||
|
//
|
||||||
|
// atomic_count for g++ on 486+/AMD64
|
||||||
|
//
|
||||||
|
// Copyright 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class atomic_count
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
|
||||||
|
|
||||||
|
void operator++()
|
||||||
|
{
|
||||||
|
__asm__
|
||||||
|
(
|
||||||
|
"lock\n\t"
|
||||||
|
"incl %0":
|
||||||
|
"+m"( value_ ): // output (%0)
|
||||||
|
: // inputs
|
||||||
|
"cc" // clobbers
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
long operator--()
|
||||||
|
{
|
||||||
|
return atomic_exchange_and_add( &value_, -1 ) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator long() const
|
||||||
|
{
|
||||||
|
return atomic_exchange_and_add( &value_, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
atomic_count(atomic_count const &);
|
||||||
|
atomic_count & operator=(atomic_count const &);
|
||||||
|
|
||||||
|
mutable int value_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static int atomic_exchange_and_add( int * pw, int dv )
|
||||||
|
{
|
||||||
|
// int r = *pw;
|
||||||
|
// *pw += dv;
|
||||||
|
// return r;
|
||||||
|
|
||||||
|
int r;
|
||||||
|
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
"lock\n\t"
|
||||||
|
"xadd %1, %0":
|
||||||
|
"+m"( *pw ), "=r"( r ): // outputs (%0, %1)
|
||||||
|
"1"( dv ): // inputs (%2 == %1)
|
||||||
|
"memory", "cc" // clobbers
|
||||||
|
);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
59
include/boost/detail/atomic_count_solaris.hpp
Normal file
59
include/boost/detail/atomic_count_solaris.hpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// boost/detail/atomic_count_solaris.hpp
|
||||||
|
// based on: boost/detail/atomic_count_win32.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2001-2005 Peter Dimov
|
||||||
|
// Copyright (c) 2006 Michael van der Westhuizen
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <atomic.h>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class atomic_count
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit atomic_count( uint32_t v ): value_( v )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
long operator++()
|
||||||
|
{
|
||||||
|
return atomic_inc_32_nv( &value_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
long operator--()
|
||||||
|
{
|
||||||
|
return atomic_dec_32_nv( &value_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
operator uint32_t() const
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t const volatile &>( value_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
atomic_count( atomic_count const & );
|
||||||
|
atomic_count & operator=( atomic_count const & );
|
||||||
|
|
||||||
|
uint32_t value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
57
include/boost/detail/atomic_count_sync.hpp
Normal file
57
include/boost/detail/atomic_count_sync.hpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// boost/detail/atomic_count_sync.hpp
|
||||||
|
//
|
||||||
|
// atomic_count for g++ 4.1+
|
||||||
|
//
|
||||||
|
// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html
|
||||||
|
//
|
||||||
|
// Copyright 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class atomic_count
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit atomic_count( long v ) : value_( v ) {}
|
||||||
|
|
||||||
|
void operator++()
|
||||||
|
{
|
||||||
|
__sync_add_and_fetch( &value_, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
long operator--()
|
||||||
|
{
|
||||||
|
return __sync_add_and_fetch( &value_, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
operator long() const
|
||||||
|
{
|
||||||
|
return __sync_fetch_and_add( &value_, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
atomic_count(atomic_count const &);
|
||||||
|
atomic_count & operator=(atomic_count const &);
|
||||||
|
|
||||||
|
mutable long value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
@@ -42,7 +42,7 @@ public:
|
|||||||
|
|
||||||
virtual char const * what() const throw()
|
virtual char const * what() const throw()
|
||||||
{
|
{
|
||||||
return "boost::bad_weak_ptr";
|
return "tr1::bad_weak_ptr";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -30,10 +30,10 @@
|
|||||||
|
|
||||||
#if !defined(BOOST_HAS_THREADS)
|
#if !defined(BOOST_HAS_THREADS)
|
||||||
# include <boost/detail/lwm_nop.hpp>
|
# include <boost/detail/lwm_nop.hpp>
|
||||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
|
||||||
# include <boost/detail/lwm_win32_cs.hpp>
|
|
||||||
#elif defined(BOOST_HAS_PTHREADS)
|
#elif defined(BOOST_HAS_PTHREADS)
|
||||||
# include <boost/detail/lwm_pthreads.hpp>
|
# include <boost/detail/lwm_pthreads.hpp>
|
||||||
|
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||||
|
# include <boost/detail/lwm_win32_cs.hpp>
|
||||||
#else
|
#else
|
||||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||||
# error Unrecognized threading platform
|
# error Unrecognized threading platform
|
||||||
|
@@ -29,10 +29,9 @@
|
|||||||
#include <boost/detail/sp_counted_base.hpp>
|
#include <boost/detail/sp_counted_base.hpp>
|
||||||
#include <boost/detail/sp_counted_impl.hpp>
|
#include <boost/detail/sp_counted_impl.hpp>
|
||||||
|
|
||||||
#include <memory> // std::auto_ptr, std::allocator
|
#include <memory> // std::auto_ptr
|
||||||
#include <functional> // std::less
|
#include <functional> // std::less
|
||||||
#include <new> // std::bad_alloc
|
#include <new> // std::bad_alloc
|
||||||
#include <typeinfo> // std::type_info in get_deleter
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -127,6 +126,52 @@ public:
|
|||||||
boost::throw_exception(std::bad_alloc());
|
boost::throw_exception(std::bad_alloc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
|
||||||
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
|
, id_(shared_count_id)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
typedef sp_counted_impl_pda<P, D, A> impl_type;
|
||||||
|
typedef typename A::template rebind< impl_type >::other A2;
|
||||||
|
|
||||||
|
A2 a2( a );
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||||
|
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
d( p );
|
||||||
|
|
||||||
|
if( pi_ != 0 )
|
||||||
|
{
|
||||||
|
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||||
|
|
||||||
|
if( pi_ != 0 )
|
||||||
|
{
|
||||||
|
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d( p );
|
||||||
|
boost::throw_exception( std::bad_alloc() );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +258,7 @@ public:
|
|||||||
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
|
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
void * get_deleter(std::type_info const & ti) const
|
void * get_deleter( sp_typeinfo const & ti ) const
|
||||||
{
|
{
|
||||||
return pi_? pi_->get_deleter( ti ): 0;
|
return pi_? pi_->get_deleter( ti ): 0;
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
//
|
//
|
||||||
// detail/sp_counted_base.hpp
|
// detail/sp_counted_base.hpp
|
||||||
//
|
//
|
||||||
// Copyright 2005 Peter Dimov
|
// Copyright 2005, 2006 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -39,14 +39,26 @@
|
|||||||
|
|
||||||
# include <boost/detail/sp_counted_base_gcc_ia64.hpp>
|
# include <boost/detail/sp_counted_base_gcc_ia64.hpp>
|
||||||
|
|
||||||
|
#elif defined(__HP_aCC) && defined(__ia64)
|
||||||
|
|
||||||
|
# include <boost/detail/sp_counted_base_acc_ia64.hpp>
|
||||||
|
|
||||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
||||||
|
|
||||||
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
|
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) )
|
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
|
||||||
|
|
||||||
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
|
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
|
||||||
|
|
||||||
|
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||||
|
|
||||||
|
# include <boost/detail/sp_counted_base_sync.hpp>
|
||||||
|
|
||||||
|
#elif defined(__GNUC__) && ( defined( __sparcv8 ) || defined( __sparcv9 ) )
|
||||||
|
|
||||||
|
# include <boost/detail/sp_counted_base_gcc_sparc.hpp>
|
||||||
|
|
||||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
||||||
|
|
||||||
# include <boost/detail/sp_counted_base_w32.hpp>
|
# include <boost/detail/sp_counted_base_w32.hpp>
|
||||||
|
150
include/boost/detail/sp_counted_base_acc_ia64.hpp
Normal file
150
include/boost/detail/sp_counted_base_acc_ia64.hpp
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
|
||||||
|
//
|
||||||
|
// Copyright 2007 Baruch Zilber
|
||||||
|
// Copyright 2007 Boris Gubenko
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Lock-free algorithm by Alexander Terekhov
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "sp_typeinfo.hpp"
|
||||||
|
#include <machine/sys/inline.h>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void atomic_increment( int * pw )
|
||||||
|
{
|
||||||
|
// ++*pw;
|
||||||
|
|
||||||
|
_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int atomic_decrement( int * pw )
|
||||||
|
{
|
||||||
|
// return --*pw;
|
||||||
|
|
||||||
|
int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
|
||||||
|
if (1 == r)
|
||||||
|
{
|
||||||
|
_Asm_mf();
|
||||||
|
}
|
||||||
|
|
||||||
|
return r - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int atomic_conditional_increment( int * pw )
|
||||||
|
{
|
||||||
|
// if( *pw != 0 ) ++*pw;
|
||||||
|
// return *pw;
|
||||||
|
|
||||||
|
int v = *pw;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (0 == v)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Asm_mov_to_ar(_AREG_CCV,
|
||||||
|
v,
|
||||||
|
(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
|
||||||
|
int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
|
||||||
|
if (r == v)
|
||||||
|
{
|
||||||
|
return r + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_counted_base( sp_counted_base const & );
|
||||||
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
|
int use_count_; // #shared
|
||||||
|
int weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~sp_counted_base() // nothrow
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispose() is called when use_count_ drops to zero, to release
|
||||||
|
// the resources managed by *this.
|
||||||
|
|
||||||
|
virtual void dispose() = 0; // nothrow
|
||||||
|
|
||||||
|
// destroy() is called when weak_count_ drops to zero.
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_increment( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &use_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_increment( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
@@ -24,7 +24,7 @@
|
|||||||
// formulation
|
// formulation
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <typeinfo>
|
#include "sp_typeinfo.hpp"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -34,55 +34,61 @@ namespace detail
|
|||||||
|
|
||||||
inline void atomic_increment( register long * pw )
|
inline void atomic_increment( register long * pw )
|
||||||
{
|
{
|
||||||
|
register int a;
|
||||||
|
|
||||||
asm
|
asm
|
||||||
{
|
{
|
||||||
loop:
|
loop:
|
||||||
|
|
||||||
lwarx r4, 0, r3
|
lwarx a, 0, pw
|
||||||
addi r4, r4, 1
|
addi a, a, 1
|
||||||
stwcx. r4, 0, r3
|
stwcx. a, 0, pw
|
||||||
bne- loop
|
bne- loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long atomic_decrement( register long * pw )
|
inline long atomic_decrement( register long * pw )
|
||||||
{
|
{
|
||||||
|
register int a;
|
||||||
|
|
||||||
asm
|
asm
|
||||||
{
|
{
|
||||||
sync
|
sync
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
|
|
||||||
lwarx r4, 0, r3
|
lwarx a, 0, pw
|
||||||
addi r4, r4, -1
|
addi a, a, -1
|
||||||
stwcx. r4, 0, r3
|
stwcx. a, 0, pw
|
||||||
bne- loop
|
bne- loop
|
||||||
|
|
||||||
mr r3, r4
|
|
||||||
|
|
||||||
isync
|
isync
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long atomic_conditional_increment( register long * pw )
|
inline long atomic_conditional_increment( register long * pw )
|
||||||
{
|
{
|
||||||
|
register int a;
|
||||||
|
|
||||||
asm
|
asm
|
||||||
{
|
{
|
||||||
loop:
|
loop:
|
||||||
|
|
||||||
lwarx r4, 0, r3
|
lwarx a, 0, pw
|
||||||
cmpwi r4, 0
|
cmpwi a, 0
|
||||||
beq store
|
beq store
|
||||||
|
|
||||||
addi r4, r4, 1
|
addi a, a, 1
|
||||||
|
|
||||||
store:
|
store:
|
||||||
|
|
||||||
stwcx. r4, 0, r3
|
stwcx. a, 0, pw
|
||||||
bne- loop
|
bne- loop
|
||||||
|
|
||||||
mr r3, r4
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
class sp_counted_base
|
class sp_counted_base
|
||||||
@@ -117,7 +123,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
// formulation
|
// formulation
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <typeinfo>
|
#include "sp_typeinfo.hpp"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -111,7 +111,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
|
// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
|
||||||
//
|
//
|
||||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||||
// Copyright 2004-2005 Peter Dimov
|
// Copyright 2004-2006 Peter Dimov
|
||||||
// Copyright 2005 Ben Hutchings
|
// Copyright 2005 Ben Hutchings
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
// Lock-free algorithm by Alexander Terekhov
|
// Lock-free algorithm by Alexander Terekhov
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <typeinfo>
|
#include "sp_typeinfo.hpp"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -24,55 +24,55 @@ namespace boost
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
inline void atomic_increment( long * pw )
|
inline void atomic_increment( int * pw )
|
||||||
{
|
{
|
||||||
// ++*pw;
|
// ++*pw;
|
||||||
|
|
||||||
long tmp;
|
int tmp;
|
||||||
|
|
||||||
// No barrier is required here but fetchadd always has an acquire or
|
// No barrier is required here but fetchadd always has an acquire or
|
||||||
// release barrier associated with it. We choose release as it should be
|
// release barrier associated with it. We choose release as it should be
|
||||||
// cheaper.
|
// cheaper.
|
||||||
__asm__ ("fetchadd8.rel %0=[%2],1" :
|
__asm__ ("fetchadd4.rel %0=%1,1" :
|
||||||
"=r"(tmp), "=m"(*pw) :
|
"=r"(tmp), "=m"(*pw) :
|
||||||
"r"(pw));
|
"m"( *pw ));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long atomic_decrement( long * pw )
|
inline int atomic_decrement( int * pw )
|
||||||
{
|
{
|
||||||
// return --*pw;
|
// return --*pw;
|
||||||
|
|
||||||
long rv;
|
int rv;
|
||||||
|
|
||||||
__asm__ (" fetchadd8.rel %0=[%2],-1 ;; \n"
|
__asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
|
||||||
" cmp.eq p7,p0=1,%0 ;; \n"
|
" cmp.eq p7,p0=1,%0 ;; \n"
|
||||||
"(p7) ld8.acq %0=[%2] " :
|
"(p7) ld4.acq %0=%1 " :
|
||||||
"=&r"(rv), "=m"(*pw) :
|
"=&r"(rv), "=m"(*pw) :
|
||||||
"r"(pw) :
|
"m"( *pw ) :
|
||||||
"p7");
|
"p7");
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long atomic_conditional_increment( long * pw )
|
inline int atomic_conditional_increment( int * pw )
|
||||||
{
|
{
|
||||||
// if( *pw != 0 ) ++*pw;
|
// if( *pw != 0 ) ++*pw;
|
||||||
// return *pw;
|
// return *pw;
|
||||||
|
|
||||||
long rv, tmp, tmp2;
|
int rv, tmp, tmp2;
|
||||||
|
|
||||||
__asm__ ("0: ld8 %0=[%4] ;; \n"
|
__asm__ ("0: ld4 %0=%3 ;; \n"
|
||||||
" cmp.eq p7,p0=0,%0 ;; \n"
|
" cmp.eq p7,p0=0,%0 ;; \n"
|
||||||
"(p7) br.cond.spnt 1f \n"
|
"(p7) br.cond.spnt 1f \n"
|
||||||
" mov ar.ccv=%0 \n"
|
" mov ar.ccv=%0 \n"
|
||||||
" add %1=1,%0 ;; \n"
|
" add %1=1,%0 ;; \n"
|
||||||
" cmpxchg8.acq %2=[%4],%1,ar.ccv ;; \n"
|
" cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
|
||||||
" cmp.ne p7,p0=%0,%2 ;; \n"
|
" cmp.ne p7,p0=%0,%2 ;; \n"
|
||||||
"(p7) br.cond.spnt 0b \n"
|
"(p7) br.cond.spnt 0b \n"
|
||||||
" mov %0=%1 ;; \n"
|
" mov %0=%1 ;; \n"
|
||||||
"1:" :
|
"1:" :
|
||||||
"=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
|
"=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
|
||||||
"r"(pw) :
|
"m"( *pw ) :
|
||||||
"ar.ccv", "p7");
|
"ar.ccv", "p7");
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@@ -85,8 +85,8 @@ private:
|
|||||||
sp_counted_base( sp_counted_base const & );
|
sp_counted_base( sp_counted_base const & );
|
||||||
sp_counted_base & operator= ( sp_counted_base const & );
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
long use_count_; // #shared
|
int use_count_; // #shared
|
||||||
long weak_count_; // #weak + (#shared != 0)
|
int weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
@@ -146,7 +146,7 @@ public:
|
|||||||
|
|
||||||
long use_count() const // nothrow
|
long use_count() const // nothrow
|
||||||
{
|
{
|
||||||
return static_cast<long const volatile &>( use_count_ );
|
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
// formulation
|
// formulation
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <typeinfo>
|
#include "sp_typeinfo.hpp"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -32,11 +32,11 @@ namespace boost
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
inline void atomic_increment( long * pw )
|
inline void atomic_increment( int * pw )
|
||||||
{
|
{
|
||||||
// ++*pw;
|
// ++*pw;
|
||||||
|
|
||||||
long tmp;
|
int tmp;
|
||||||
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
@@ -47,16 +47,16 @@ inline void atomic_increment( long * pw )
|
|||||||
"bne- 0b":
|
"bne- 0b":
|
||||||
|
|
||||||
"=m"( *pw ), "=&b"( tmp ):
|
"=m"( *pw ), "=&b"( tmp ):
|
||||||
"r"( pw ):
|
"r"( pw ), "m"( *pw ):
|
||||||
"cc"
|
"cc"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long atomic_decrement( long * pw )
|
inline int atomic_decrement( int * pw )
|
||||||
{
|
{
|
||||||
// return --*pw;
|
// return --*pw;
|
||||||
|
|
||||||
long rv;
|
int rv;
|
||||||
|
|
||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
@@ -69,19 +69,19 @@ inline long atomic_decrement( long * pw )
|
|||||||
"isync":
|
"isync":
|
||||||
|
|
||||||
"=m"( *pw ), "=&b"( rv ):
|
"=m"( *pw ), "=&b"( rv ):
|
||||||
"r"( pw ):
|
"r"( pw ), "m"( *pw ):
|
||||||
"memory", "cc"
|
"memory", "cc"
|
||||||
);
|
);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long atomic_conditional_increment( long * pw )
|
inline int atomic_conditional_increment( int * pw )
|
||||||
{
|
{
|
||||||
// if( *pw != 0 ) ++*pw;
|
// if( *pw != 0 ) ++*pw;
|
||||||
// return *pw;
|
// return *pw;
|
||||||
|
|
||||||
long rv;
|
int rv;
|
||||||
|
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
@@ -95,7 +95,7 @@ inline long atomic_conditional_increment( long * pw )
|
|||||||
"bne- 0b":
|
"bne- 0b":
|
||||||
|
|
||||||
"=m"( *pw ), "=&b"( rv ):
|
"=m"( *pw ), "=&b"( rv ):
|
||||||
"r"( pw ):
|
"r"( pw ), "m"( *pw ):
|
||||||
"cc"
|
"cc"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -109,8 +109,8 @@ private:
|
|||||||
sp_counted_base( sp_counted_base const & );
|
sp_counted_base( sp_counted_base const & );
|
||||||
sp_counted_base & operator= ( sp_counted_base const & );
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
long use_count_; // #shared
|
int use_count_; // #shared
|
||||||
long weak_count_; // #weak + (#shared != 0)
|
int weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
@@ -170,7 +170,7 @@ public:
|
|||||||
|
|
||||||
long use_count() const // nothrow
|
long use_count() const // nothrow
|
||||||
{
|
{
|
||||||
return static_cast<long const volatile &>( use_count_ );
|
return static_cast<int const volatile &>( use_count_ );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
166
include/boost/detail/sp_counted_base_gcc_sparc.hpp
Normal file
166
include/boost/detail/sp_counted_base_gcc_sparc.hpp
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006 Piotr Wyderski
|
||||||
|
// Copyright (c) 2006 Tomas Puverle
|
||||||
|
// Copyright (c) 2006 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
// Thanks to Michael van der Westhuizen
|
||||||
|
|
||||||
|
#include "sp_typeinfo.hpp"
|
||||||
|
#include <inttypes.h> // int32_t
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
|
||||||
|
{
|
||||||
|
__asm__ __volatile__( "cas %0, %2, %1"
|
||||||
|
: "+m" (*dest_), "+r" (swap_)
|
||||||
|
: "r" (compare_)
|
||||||
|
: "memory" );
|
||||||
|
|
||||||
|
return swap_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
|
||||||
|
{
|
||||||
|
// long r = *pw;
|
||||||
|
// *pw += dv;
|
||||||
|
// return r;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
int32_t r = *pw;
|
||||||
|
|
||||||
|
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void atomic_increment( int32_t * pw )
|
||||||
|
{
|
||||||
|
atomic_fetch_and_add( pw, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t atomic_decrement( int32_t * pw )
|
||||||
|
{
|
||||||
|
return atomic_fetch_and_add( pw, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t atomic_conditional_increment( int32_t * pw )
|
||||||
|
{
|
||||||
|
// long r = *pw;
|
||||||
|
// if( r != 0 ) ++*pw;
|
||||||
|
// return r;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
int32_t r = *pw;
|
||||||
|
|
||||||
|
if( r == 0 )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_counted_base( sp_counted_base const & );
|
||||||
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
|
int32_t use_count_; // #shared
|
||||||
|
int32_t weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~sp_counted_base() // nothrow
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispose() is called when use_count_ drops to zero, to release
|
||||||
|
// the resources managed by *this.
|
||||||
|
|
||||||
|
virtual void dispose() = 0; // nothrow
|
||||||
|
|
||||||
|
// destroy() is called when weak_count_ drops to zero.
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_increment( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &use_count_ ) == 1 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_increment( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
return const_cast< int32_t const volatile & >( use_count_ );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
@@ -24,7 +24,7 @@
|
|||||||
// formulation
|
// formulation
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <typeinfo>
|
#include "sp_typeinfo.hpp"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -126,7 +126,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <typeinfo>
|
#include "sp_typeinfo.hpp"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <typeinfo>
|
#include "sp_typeinfo.hpp"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
113
include/boost/detail/sp_counted_base_solaris.hpp
Normal file
113
include/boost/detail/sp_counted_base_solaris.hpp
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// detail/sp_counted_base_solaris.hpp
|
||||||
|
// based on: detail/sp_counted_base_w32.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||||
|
// Copyright 2004-2005 Peter Dimov
|
||||||
|
// Copyright 2006 Michael van der Westhuizen
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Lock-free algorithm by Alexander Terekhov
|
||||||
|
//
|
||||||
|
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||||
|
// formulation
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "sp_typeinfo.hpp"
|
||||||
|
#include <atomic.h>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_counted_base( sp_counted_base const & );
|
||||||
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
|
uint32_t use_count_; // #shared
|
||||||
|
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~sp_counted_base() // nothrow
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispose() is called when use_count_ drops to zero, to release
|
||||||
|
// the resources managed by *this.
|
||||||
|
|
||||||
|
virtual void dispose() = 0; // nothrow
|
||||||
|
|
||||||
|
// destroy() is called when weak_count_ drops to zero.
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_inc_32( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
|
||||||
|
if( tmp == 0 ) return false;
|
||||||
|
if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_dec_32_nv( &use_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_inc_32( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_dec_32_nv( &weak_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
return static_cast<long const volatile &>( use_count_ );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
151
include/boost/detail/sp_counted_base_sync.hpp
Normal file
151
include/boost/detail/sp_counted_base_sync.hpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include "sp_typeinfo.hpp"
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#if INT_MAX >= 2147483647
|
||||||
|
|
||||||
|
typedef int sp_int32_t;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef long sp_int32_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline void atomic_increment( sp_int32_t * pw )
|
||||||
|
{
|
||||||
|
__sync_fetch_and_add( pw, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
|
||||||
|
{
|
||||||
|
return __sync_fetch_and_add( pw, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
|
||||||
|
{
|
||||||
|
// long r = *pw;
|
||||||
|
// if( r != 0 ) ++*pw;
|
||||||
|
// return r;
|
||||||
|
|
||||||
|
sp_int32_t r = *pw;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( r == 0 )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
|
||||||
|
|
||||||
|
if( r2 == r )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = r2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_counted_base( sp_counted_base const & );
|
||||||
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
|
sp_int32_t use_count_; // #shared
|
||||||
|
sp_int32_t weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~sp_counted_base() // nothrow
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispose() is called when use_count_ drops to zero, to release
|
||||||
|
// the resources managed by *this.
|
||||||
|
|
||||||
|
virtual void dispose() = 0; // nothrow
|
||||||
|
|
||||||
|
// destroy() is called when weak_count_ drops to zero.
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_increment( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &use_count_ ) == 1 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_increment( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
return const_cast< sp_int32_t const volatile & >( use_count_ );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
@@ -25,7 +25,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/interlocked.hpp>
|
#include <boost/detail/interlocked.hpp>
|
||||||
#include <typeinfo>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include "sp_typeinfo.hpp"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -65,7 +66,7 @@ public:
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
@@ -78,7 +79,19 @@ public:
|
|||||||
{
|
{
|
||||||
long tmp = static_cast< long const volatile& >( use_count_ );
|
long tmp = static_cast< long const volatile& >( use_count_ );
|
||||||
if( tmp == 0 ) return false;
|
if( tmp == 0 ) return false;
|
||||||
|
|
||||||
|
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
|
||||||
|
|
||||||
|
// work around a code generation bug
|
||||||
|
|
||||||
|
long tmp2 = tmp + 1;
|
||||||
|
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
|
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,8 +31,10 @@
|
|||||||
#include <boost/detail/quick_allocator.hpp>
|
#include <boost/detail/quick_allocator.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||||
#include <memory> // std::allocator
|
#include <memory> // std::allocator
|
||||||
#include <typeinfo> // std::type_info in get_deleter
|
#endif
|
||||||
|
|
||||||
#include <cstddef> // std::size_t
|
#include <cstddef> // std::size_t
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
@@ -76,7 +78,7 @@ public:
|
|||||||
boost::checked_delete( px_ );
|
boost::checked_delete( px_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & )
|
virtual void * get_deleter( detail::sp_typeinfo const & )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -142,9 +144,9 @@ public:
|
|||||||
del( ptr );
|
del( ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( std::type_info const & ti )
|
virtual void * get_deleter( detail::sp_typeinfo const & ti )
|
||||||
{
|
{
|
||||||
return ti == typeid(D)? &del: 0;
|
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||||
@@ -176,6 +178,48 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
P p_; // copy constructor must not throw
|
||||||
|
D d_; // copy constructor must not throw
|
||||||
|
A a_; // copy constructor must not throw
|
||||||
|
|
||||||
|
sp_counted_impl_pda( sp_counted_impl_pda const & );
|
||||||
|
sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
|
||||||
|
|
||||||
|
typedef sp_counted_impl_pda<P, D, A> this_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// pre: d( p ) must not throw
|
||||||
|
|
||||||
|
sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void dispose() // nothrow
|
||||||
|
{
|
||||||
|
d_( p_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
typedef typename A::template rebind< this_type >::other A2;
|
||||||
|
|
||||||
|
A2 a2( a_ );
|
||||||
|
|
||||||
|
this->~this_type();
|
||||||
|
a2.deallocate( this, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( detail::sp_typeinfo const & ti )
|
||||||
|
{
|
||||||
|
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __CODEGUARD__
|
#ifdef __CODEGUARD__
|
||||||
# pragma option pop
|
# pragma option pop
|
||||||
#endif
|
#endif
|
||||||
|
83
include/boost/detail/sp_typeinfo.hpp
Normal file
83
include/boost/detail/sp_typeinfo.hpp
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detail/sp_typeinfo.hpp
|
||||||
|
//
|
||||||
|
// Copyright 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if defined( BOOST_NO_TYPEID )
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef void* sp_typeinfo;
|
||||||
|
|
||||||
|
template<class T> struct sp_typeid_
|
||||||
|
{
|
||||||
|
static char v_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> char sp_typeid_< T >::v_;
|
||||||
|
|
||||||
|
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_SP_TYPEID(T) (&boost::detail::sp_typeid_<T>::v_)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined( BOOST_NO_STD_TYPEINFO )
|
||||||
|
|
||||||
|
typedef ::type_info sp_typeinfo;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef std::type_info sp_typeinfo;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_SP_TYPEID(T) typeid(T)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
@@ -58,6 +58,12 @@ public:
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: No, you don't need to initialize _internal_weak_this
|
||||||
|
//
|
||||||
|
// Please read the documentation, not the code
|
||||||
|
//
|
||||||
|
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||||
|
|
||||||
typedef T _internal_element_type; // for bcc 5.5.1
|
typedef T _internal_element_type; // for bcc 5.5.1
|
||||||
mutable weak_ptr<_internal_element_type> _internal_weak_this;
|
mutable weak_ptr<_internal_element_type> _internal_weak_this;
|
||||||
};
|
};
|
||||||
|
@@ -105,6 +105,11 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset( T * rhs )
|
||||||
|
{
|
||||||
|
this_type( rhs ).swap( *this );
|
||||||
|
}
|
||||||
|
|
||||||
T * get() const
|
T * get() const
|
||||||
{
|
{
|
||||||
return p_;
|
return p_;
|
||||||
@@ -112,11 +117,13 @@ public:
|
|||||||
|
|
||||||
T & operator*() const
|
T & operator*() const
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT( p_ != 0 );
|
||||||
return *p_;
|
return *p_;
|
||||||
}
|
}
|
||||||
|
|
||||||
T * operator->() const
|
T * operator->() const
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT( p_ != 0 );
|
||||||
return p_;
|
return p_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,22 +181,22 @@ template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, in
|
|||||||
return a.get() != b.get();
|
return a.get() != b.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
|
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
|
||||||
{
|
{
|
||||||
return a.get() == b;
|
return a.get() == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
|
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
|
||||||
{
|
{
|
||||||
return a.get() != b;
|
return a.get() != b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
|
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
|
||||||
{
|
{
|
||||||
return a == b.get();
|
return a == b.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
|
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
|
||||||
{
|
{
|
||||||
return a != b.get();
|
return a != b.get();
|
||||||
}
|
}
|
||||||
@@ -249,7 +256,10 @@ template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y>
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
|
// in STLport's no-iostreams mode no iostream symbols can be used
|
||||||
|
#ifndef _STLP_NO_IOSTREAMS
|
||||||
|
|
||||||
|
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
|
||||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
||||||
using std::basic_ostream;
|
using std::basic_ostream;
|
||||||
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
|
||||||
@@ -261,7 +271,9 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // _STLP_NO_IOSTREAMS
|
||||||
|
|
||||||
|
#endif // __GNUC__ < 3
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
45
include/boost/pointer_cast.hpp
Normal file
45
include/boost/pointer_cast.hpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gazta<74>aga 2005.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef BOOST_POINTER_CAST_HPP
|
||||||
|
#define BOOST_POINTER_CAST_HPP
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
//static_pointer_cast overload for raw pointers
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* static_pointer_cast(U *ptr)
|
||||||
|
{
|
||||||
|
return static_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//dynamic_pointer_cast overload for raw pointers
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* dynamic_pointer_cast(U *ptr)
|
||||||
|
{
|
||||||
|
return dynamic_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//const_pointer_cast overload for raw pointers
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* const_pointer_cast(U *ptr)
|
||||||
|
{
|
||||||
|
return const_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//reinterpret_pointer_cast overload for raw pointers
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* reinterpret_pointer_cast(U *ptr)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif //BOOST_POINTER_CAST_HPP
|
55
include/boost/pointer_to_other.hpp
Normal file
55
include/boost/pointer_to_other.hpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
|
||||||
|
#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// pointer_to_other.hpp
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gazta<74>aga 2005.
|
||||||
|
// Copyright (c) 2005 Peter Dimov.
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
//
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/smart_ptr/pointer_to_other.html
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
// Defines the same pointer type (raw or smart) to another pointee type
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
struct pointer_to_other;
|
||||||
|
|
||||||
|
template<class T, class U,
|
||||||
|
template<class> class Sp>
|
||||||
|
struct pointer_to_other< Sp<T>, U >
|
||||||
|
{
|
||||||
|
typedef Sp<U> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class T2, class U,
|
||||||
|
template<class, class> class Sp>
|
||||||
|
struct pointer_to_other< Sp<T, T2>, U >
|
||||||
|
{
|
||||||
|
typedef Sp<U, T2> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class T2, class T3, class U,
|
||||||
|
template<class, class, class> class Sp>
|
||||||
|
struct pointer_to_other< Sp<T, T2, T3>, U >
|
||||||
|
{
|
||||||
|
typedef Sp<U, T2, T3> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
struct pointer_to_other< T*, U >
|
||||||
|
{
|
||||||
|
typedef U* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
|
@@ -20,6 +20,8 @@
|
|||||||
#include <boost/detail/shared_array_nmt.hpp>
|
#include <boost/detail/shared_array_nmt.hpp>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <memory> // TR1 cyclic inclusion fix
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
|
|
||||||
@@ -101,7 +103,23 @@ public:
|
|||||||
return px != 0;
|
return px != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
#elif defined( _MANAGED )
|
||||||
|
|
||||||
|
static void unspecified_bool( this_type*** )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*unspecified_bool_type)( this_type*** );
|
||||||
|
|
||||||
|
operator unspecified_bool_type() const // never throws
|
||||||
|
{
|
||||||
|
return px == 0? 0: unspecified_bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif \
|
||||||
|
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
|
||||||
|
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) )
|
||||||
|
|
||||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||||
|
|
||||||
operator unspecified_bool_type() const // never throws
|
operator unspecified_bool_type() const // never throws
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// shared_ptr.hpp
|
// shared_ptr.hpp
|
||||||
//
|
//
|
||||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov
|
// Copyright (c) 2001-2007 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -20,13 +20,14 @@
|
|||||||
#include <boost/detail/shared_ptr_nmt.hpp>
|
#include <boost/detail/shared_ptr_nmt.hpp>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <memory> // for std::auto_ptr
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <boost/detail/shared_count.hpp>
|
#include <boost/detail/shared_count.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
#include <memory> // for std::auto_ptr
|
|
||||||
#include <algorithm> // for std::swap
|
#include <algorithm> // for std::swap
|
||||||
#include <functional> // for std::less
|
#include <functional> // for std::less
|
||||||
#include <typeinfo> // for std::bad_cast
|
#include <typeinfo> // for std::bad_cast
|
||||||
@@ -87,10 +88,51 @@ template<class T, class Y> void sp_enable_shared_from_this( shared_count const &
|
|||||||
if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
|
if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MANAGED
|
||||||
|
|
||||||
|
// Avoid C4793, ... causes native code generation
|
||||||
|
|
||||||
|
struct sp_any_pointer
|
||||||
|
{
|
||||||
|
template<class T> sp_any_pointer( T* ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, sp_any_pointer, sp_any_pointer )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // _MANAGED
|
||||||
|
|
||||||
|
#ifdef sgi
|
||||||
|
// Turn off: the last argument of the varargs function "sp_enable_shared_from_this" is unnamed
|
||||||
|
# pragma set woff 3506
|
||||||
|
#endif
|
||||||
|
|
||||||
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
|
inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef sgi
|
||||||
|
# pragma reset woff 3506
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _MANAGED
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
|
||||||
|
|
||||||
|
// rvalue auto_ptr support based on a technique by Dave Abrahams
|
||||||
|
|
||||||
|
template< class T, class R > struct sp_enable_if_auto_ptr
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
@@ -114,7 +156,7 @@ public:
|
|||||||
typedef T element_type;
|
typedef T element_type;
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef T * pointer;
|
typedef T * pointer;
|
||||||
typedef typename detail::shared_ptr_traits<T>::reference reference;
|
typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
|
||||||
|
|
||||||
shared_ptr(): px(0), pn() // never throws in 1.30+
|
shared_ptr(): px(0), pn() // never throws in 1.30+
|
||||||
{
|
{
|
||||||
@@ -123,7 +165,7 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
|
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
|
||||||
{
|
{
|
||||||
detail::sp_enable_shared_from_this( pn, p, p );
|
boost::detail::sp_enable_shared_from_this( pn, p, p );
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -134,7 +176,14 @@ public:
|
|||||||
|
|
||||||
template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
|
template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
|
||||||
{
|
{
|
||||||
detail::sp_enable_shared_from_this( pn, p, p );
|
boost::detail::sp_enable_shared_from_this( pn, p, p );
|
||||||
|
}
|
||||||
|
|
||||||
|
// As above, but with allocator. A's copy constructor shall not throw.
|
||||||
|
|
||||||
|
template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
|
||||||
|
{
|
||||||
|
boost::detail::sp_enable_shared_from_this( pn, p, p );
|
||||||
}
|
}
|
||||||
|
|
||||||
// generated copy constructor, assignment, destructor are fine...
|
// generated copy constructor, assignment, destructor are fine...
|
||||||
@@ -163,27 +212,33 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
// aliasing
|
||||||
shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
|
template< class Y >
|
||||||
|
shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr(shared_ptr<Y> const & r, detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
|
shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
||||||
{
|
{
|
||||||
if(px == 0) // need to allocate new counter -- the cast failed
|
if(px == 0) // need to allocate new counter -- the cast failed
|
||||||
{
|
{
|
||||||
pn = detail::shared_count();
|
pn = boost::detail::shared_count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
||||||
{
|
{
|
||||||
if(px == 0)
|
if(px == 0)
|
||||||
{
|
{
|
||||||
@@ -197,13 +252,26 @@ public:
|
|||||||
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
|
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
|
||||||
{
|
{
|
||||||
Y * tmp = r.get();
|
Y * tmp = r.get();
|
||||||
pn = detail::shared_count(r);
|
pn = boost::detail::shared_count(r);
|
||||||
detail::sp_enable_shared_from_this( pn, tmp, tmp );
|
boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||||
|
|
||||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
|
template<class Ap>
|
||||||
|
shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
|
||||||
|
{
|
||||||
|
typename Ap::element_type * tmp = r.get();
|
||||||
|
pn = boost::detail::shared_count( r );
|
||||||
|
boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
|
#endif // BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
|
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
||||||
@@ -218,12 +286,56 @@ public:
|
|||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr & operator=(std::auto_ptr<Y> & r)
|
shared_ptr & operator=( std::auto_ptr<Y> & r )
|
||||||
{
|
{
|
||||||
this_type(r).swap(*this);
|
this_type(r).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||||
|
|
||||||
|
template<class Ap>
|
||||||
|
typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
|
||||||
|
{
|
||||||
|
this_type( r ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
|
#endif // BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
|
// Move support
|
||||||
|
|
||||||
|
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||||
|
|
||||||
|
shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
|
||||||
|
{
|
||||||
|
pn.swap( r.pn );
|
||||||
|
r.px = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_ptr( shared_ptr<Y> && r ): px( r.px ), pn() // never throws
|
||||||
|
{
|
||||||
|
pn.swap( r.pn );
|
||||||
|
r.px = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr & operator=( shared_ptr && r ) // never throws
|
||||||
|
{
|
||||||
|
this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
|
||||||
|
{
|
||||||
|
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void reset() // never throws in 1.30+
|
void reset() // never throws in 1.30+
|
||||||
@@ -237,9 +349,19 @@ public:
|
|||||||
this_type(p).swap(*this);
|
this_type(p).swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y, class D> void reset(Y * p, D d)
|
template<class Y, class D> void reset( Y * p, D d )
|
||||||
{
|
{
|
||||||
this_type(p, d).swap(*this);
|
this_type( p, d ).swap( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y, class D, class A> void reset( Y * p, D d, A a )
|
||||||
|
{
|
||||||
|
this_type( p, d, a ).swap( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y> void reset( shared_ptr<Y> const & r, T * p )
|
||||||
|
{
|
||||||
|
this_type( r, p ).swap( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
reference operator* () const // never throws
|
reference operator* () const // never throws
|
||||||
@@ -261,16 +383,30 @@ public:
|
|||||||
|
|
||||||
// implicit conversion to "bool"
|
// implicit conversion to "bool"
|
||||||
|
|
||||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
|
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
||||||
|
|
||||||
operator bool () const
|
operator bool () const
|
||||||
{
|
{
|
||||||
return px != 0;
|
return px != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined( _MANAGED )
|
||||||
|
|
||||||
|
static void unspecified_bool( this_type*** )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*unspecified_bool_type)( this_type*** );
|
||||||
|
|
||||||
|
operator unspecified_bool_type() const // never throws
|
||||||
|
{
|
||||||
|
return px == 0? 0: unspecified_bool;
|
||||||
|
}
|
||||||
|
|
||||||
#elif \
|
#elif \
|
||||||
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
|
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
|
||||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) )
|
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
|
||||||
|
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
|
||||||
|
|
||||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||||
|
|
||||||
@@ -318,9 +454,9 @@ public:
|
|||||||
return pn < rhs.pn;
|
return pn < rhs.pn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * _internal_get_deleter(std::type_info const & ti) const
|
void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
|
||||||
{
|
{
|
||||||
return pn.get_deleter(ti);
|
return pn.get_deleter( ti );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tasteless as this may seem, making all members public allows member templates
|
// Tasteless as this may seem, making all members public allows member templates
|
||||||
@@ -337,7 +473,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
T * px; // contained pointer
|
T * px; // contained pointer
|
||||||
detail::shared_count pn; // reference counter
|
boost::detail::shared_count pn; // reference counter
|
||||||
|
|
||||||
}; // shared_ptr
|
}; // shared_ptr
|
||||||
|
|
||||||
@@ -374,34 +510,34 @@ template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
|||||||
|
|
||||||
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, detail::static_cast_tag());
|
return shared_ptr<T>(r, boost::detail::static_cast_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, detail::const_cast_tag());
|
return shared_ptr<T>(r, boost::detail::const_cast_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, detail::dynamic_cast_tag());
|
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
|
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, detail::static_cast_tag());
|
return shared_ptr<T>(r, boost::detail::static_cast_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, detail::dynamic_cast_tag());
|
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, detail::polymorphic_cast_tag());
|
return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
|
||||||
@@ -429,7 +565,10 @@ template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> co
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
|
// in STLport's no-iostreams mode no iostream symbols can be used
|
||||||
|
#ifndef _STLP_NO_IOSTREAMS
|
||||||
|
|
||||||
|
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
|
||||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
|
||||||
using std::basic_ostream;
|
using std::basic_ostream;
|
||||||
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
|
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
|
||||||
@@ -441,9 +580,11 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // _STLP_NO_IOSTREAMS
|
||||||
|
|
||||||
// get_deleter (experimental)
|
#endif // __GNUC__ < 3
|
||||||
|
|
||||||
|
// get_deleter
|
||||||
|
|
||||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
||||||
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
|
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
|
||||||
@@ -454,7 +595,7 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
|
|
||||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||||
{
|
{
|
||||||
void const * q = p._internal_get_deleter(typeid(D));
|
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
|
||||||
return const_cast<D *>(static_cast<D const *>(q));
|
return const_cast<D *>(static_cast<D const *>(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +603,7 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
|||||||
|
|
||||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||||
{
|
{
|
||||||
return static_cast<D *>(p._internal_get_deleter(typeid(D)));
|
return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
|
// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <memory> // boost.TR1 include order fix
|
||||||
|
#include <boost/detail/shared_count.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
||||||
@@ -69,7 +71,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
|
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
||||||
@@ -139,7 +141,7 @@ public:
|
|||||||
pn.swap(other.pn);
|
pn.swap(other.pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _internal_assign(T * px2, detail::shared_count const & pn2)
|
void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
|
||||||
{
|
{
|
||||||
px = px2;
|
px = px2;
|
||||||
pn = pn2;
|
pn = pn2;
|
||||||
@@ -163,7 +165,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
T * px; // contained pointer
|
T * px; // contained pointer
|
||||||
detail::weak_count pn; // reference counter
|
boost::detail::weak_count pn; // reference counter
|
||||||
|
|
||||||
}; // weak_ptr
|
}; // weak_ptr
|
||||||
|
|
||||||
@@ -177,12 +179,6 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
|
|||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecated, provided for backward compatibility
|
|
||||||
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
|
|
||||||
{
|
|
||||||
return r.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
#ifdef BOOST_MSVC
|
||||||
|
@@ -7,3 +7,9 @@ Automatic redirection failed, please go to
|
|||||||
<a href="smart_ptr.htm">smart_ptr.htm</a>.
|
<a href="smart_ptr.htm">smart_ptr.htm</a>.
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
<!--
|
||||||
|
<09> Copyright Beman Dawes, 2001
|
||||||
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
|
See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
-->
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body text="#000000" bgColor="#ffffff">
|
<body text="#000000" bgColor="#ffffff">
|
||||||
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">intrusive_ptr
|
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||||
class template</h1>
|
border="0"></A>intrusive_ptr class template</h1>
|
||||||
<p>
|
<p>
|
||||||
<A href="#Introduction">Introduction</A><br>
|
<A href="#Introduction">Introduction</A><br>
|
||||||
<A href="#Synopsis">Synopsis</A><br>
|
<A href="#Synopsis">Synopsis</A><br>
|
||||||
@@ -32,10 +32,10 @@
|
|||||||
<UL>
|
<UL>
|
||||||
<LI>
|
<LI>
|
||||||
Some existing frameworks or OSes provide objects with embedded reference
|
Some existing frameworks or OSes provide objects with embedded reference
|
||||||
counts;</LI>
|
counts;
|
||||||
<LI>
|
<LI>
|
||||||
The memory footprint of <STRONG>intrusive_ptr</STRONG> is the same as the
|
The memory footprint of <STRONG>intrusive_ptr</STRONG>
|
||||||
corresponding raw pointer;</LI>
|
is the same as the corresponding raw pointer;
|
||||||
<LI>
|
<LI>
|
||||||
<STRONG>intrusive_ptr<T></STRONG> can be constructed from an arbitrary
|
<STRONG>intrusive_ptr<T></STRONG> can be constructed from an arbitrary
|
||||||
raw pointer of type <STRONG>T *</STRONG>.</LI></UL>
|
raw pointer of type <STRONG>T *</STRONG>.</LI></UL>
|
||||||
@@ -61,7 +61,8 @@
|
|||||||
|
|
||||||
intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr const & r);
|
intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr const & r);
|
||||||
template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr<Y> const & r);
|
template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr<Y> const & r);
|
||||||
template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
|
intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
|
||||||
|
void <a href="#reset" >reset</a>(T * r);
|
||||||
|
|
||||||
T & <A href="#indirection" >operator*</A>() const; // never throws
|
T & <A href="#indirection" >operator*</A>() const; // never throws
|
||||||
T * <A href="#indirection" >operator-></A>() const; // never throws
|
T * <A href="#indirection" >operator-></A>() const; // never throws
|
||||||
@@ -127,8 +128,8 @@
|
|||||||
<p><b>Effects:</b> <code>if(p != 0 && add_ref) intrusive_ptr_add_ref(p);</code>.</p>
|
<p><b>Effects:</b> <code>if(p != 0 && add_ref) intrusive_ptr_add_ref(p);</code>.</p>
|
||||||
<p><b>Postconditions:</b> <code>get() == p</code>.</p>
|
<p><b>Postconditions:</b> <code>get() == p</code>.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<pre>intrusive_ptr(intrusive_ptr const & r); // never throws
|
<pre>intrusive_ptr(intrusive_ptr const & r);
|
||||||
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r); // never throws</pre>
|
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Effects:</b> <code>if(r.get() != 0) intrusive_ptr_add_ref(r.get());</code>.</p>
|
<p><b>Effects:</b> <code>if(r.get() != 0) intrusive_ptr_add_ref(r.get());</code>.</p>
|
||||||
<p><b>Postconditions:</b> <code>get() == r.get()</code>.</p>
|
<p><b>Postconditions:</b> <code>get() == r.get()</code>.</p>
|
||||||
@@ -139,13 +140,18 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r); //
|
|||||||
<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P>
|
<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<H3><a name="assignment">assignment</a></H3>
|
<H3><a name="assignment">assignment</a></H3>
|
||||||
<pre>intrusive_ptr & operator=(intrusive_ptr const & r); // never throws
|
<pre>intrusive_ptr & operator=(intrusive_ptr const & r);
|
||||||
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r); // never throws
|
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
|
||||||
intrusive_ptr & operator=(T * r);</pre>
|
intrusive_ptr & operator=(T * r);</pre>
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
|
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
|
||||||
<P><B>Returns:</B> <code>*this</code>.</P>
|
<P><B>Returns:</B> <code>*this</code>.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
<H3><a name="reset">reset</a></H3>
|
||||||
|
<pre>void reset(T * r);</pre>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
<h3><a name="indirection">indirection</a></h3>
|
<h3><a name="indirection">indirection</a></h3>
|
||||||
<pre>T & operator*() const; // never throws</pre>
|
<pre>T & operator*() const; // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
@@ -196,26 +202,26 @@ intrusive_ptr & operator=(T * r);</pre>
|
|||||||
<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
|
<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
|
||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<pre>template<class T>
|
<pre>template<class T, class U>
|
||||||
bool operator==(intrusive_ptr<T> const & a, T * b); // never throws</pre>
|
bool operator==(intrusive_ptr<T> const & a, U * b); // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Returns:</b> <code>a.get() == b</code>.</p>
|
<p><b>Returns:</b> <code>a.get() == b</code>.</p>
|
||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<pre>template<class T>
|
<pre>template<class T, class U>
|
||||||
bool operator!=(intrusive_ptr<T> const & a, T * b); // never throws</pre>
|
bool operator!=(intrusive_ptr<T> const & a, U * b); // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Returns:</b> <code>a.get() != b</code>.</p>
|
<p><b>Returns:</b> <code>a.get() != b</code>.</p>
|
||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<pre>template<class T>
|
<pre>template<class T, class U>
|
||||||
bool operator==(T * a, intrusive_ptr<T> const & b); // never throws</pre>
|
bool operator==(T * a, intrusive_ptr<U> const & b); // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Returns:</b> <code>a == b.get()</code>.</p>
|
<p><b>Returns:</b> <code>a == b.get()</code>.</p>
|
||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<pre>template<class T>
|
<pre>template<class T, class U>
|
||||||
bool operator!=(T * a, intrusive_ptr<T> const & b); // never throws</pre>
|
bool operator!=(T * a, intrusive_ptr<U> const & b); // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Returns:</b> <code>a != b.get()</code>.</p>
|
<p><b>Returns:</b> <code>a != b.get()</code>.</p>
|
||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
@@ -278,9 +284,8 @@ intrusive_ptr & operator=(T * r);</pre>
|
|||||||
<p>
|
<p>
|
||||||
$Date$</p>
|
$Date$</p>
|
||||||
<p>
|
<p>
|
||||||
<small>Copyright <20> 2003 Peter Dimov. Permission to copy, use, modify, sell and
|
<small>Copyright <20> 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
distribute this document is granted provided this copyright notice appears in
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
all copies. This document is provided "as is" without express or implied
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
105
pointer_cast.html
Normal file
105
pointer_cast.html
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>pointer_cast.hpp</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1><IMG height="86" alt="C++ Boost" src="../../boost.png" width="277" align="middle" border="0">Pointer
|
||||||
|
cast functions</h1>
|
||||||
|
<p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
|
||||||
|
<code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>)
|
||||||
|
provide a way to write generic pointer castings for raw pointers. The functions
|
||||||
|
are defined in <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A>.</CITE></p>
|
||||||
|
<P>There is test/example code in <CITE><A href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</A></CITE>.</p>
|
||||||
|
<h2><a name="rationale">Rationale</a></h2>
|
||||||
|
<P>Boost smart pointers usually overload those functions to provide a mechanism to
|
||||||
|
emulate pointers casts. For example, <code>boost::shared_ptr<...></code> implements
|
||||||
|
a static pointer cast this way:</P>
|
||||||
|
<pre>
|
||||||
|
template<class T, class U>
|
||||||
|
shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r);
|
||||||
|
</pre>
|
||||||
|
<P>Pointer cast functions from <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE>
|
||||||
|
are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>,
|
||||||
|
<code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code>
|
||||||
|
for raw pointers. This way when developing pointer type independent classes,
|
||||||
|
for example, memory managers or shared memory compatible classes, the same code
|
||||||
|
can be used for raw and smart pointers.</p>
|
||||||
|
<H2><A name="synopsis">Synopsis</A></H2>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<PRE>
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* static_pointer_cast(U *ptr)
|
||||||
|
{ return static_cast<T*>(ptr); }
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* dynamic_pointer_cast(U *ptr)
|
||||||
|
{ return dynamic_cast<T*>(ptr); }
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* const_pointer_cast(U *ptr)
|
||||||
|
{ return const_cast<T*>(ptr); }
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
inline T* reinterpret_pointer_cast(U *ptr)
|
||||||
|
{ return reinterpret_cast<T*>(ptr); }
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
</PRE>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
<P>As you can see from the above synopsis, the pointer cast functions are just
|
||||||
|
wrappers around standard C++ cast operators.</P>
|
||||||
|
<H2><A name="example">Example</A></H2>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<PRE>
|
||||||
|
#include <boost/pointer_cast.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
class base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class derived: public base
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class BasePtr>
|
||||||
|
void check_if_it_is_derived(const BasePtr &ptr)
|
||||||
|
{
|
||||||
|
assert(boost::dynamic_pointer_cast<derived>(ptr) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
<I>// Create a raw and a shared_ptr</I>
|
||||||
|
|
||||||
|
base *ptr = new derived;
|
||||||
|
boost::shared_ptr<base> sptr(new derived);
|
||||||
|
|
||||||
|
<I>// Check that base pointer points actually to derived class</I>
|
||||||
|
|
||||||
|
check_if_it_is_derived(ptr);
|
||||||
|
check_if_it_is_derived(sptr);
|
||||||
|
|
||||||
|
// <EM>Ok!</EM>
|
||||||
|
|
||||||
|
delete ptr;
|
||||||
|
return 0;
|
||||||
|
}</PRE>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
<P>The example demonstrates how the generic pointer casts help us create pointer
|
||||||
|
independent code.</P>
|
||||||
|
<hr>
|
||||||
|
<p>Revised: $Date$</p>
|
||||||
|
<p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to
|
||||||
|
the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt">
|
||||||
|
LICENSE_1_0.txt</A> or a copy at <<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>>.)</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
108
pointer_to_other.html
Normal file
108
pointer_to_other.html
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>pointer_to_other.hpp</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#ffffff" text="#000000">
|
||||||
|
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Header
|
||||||
|
<a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a></h1>
|
||||||
|
<p>
|
||||||
|
The pointer to other utility provides a way, given a source pointer type,
|
||||||
|
to obtain a pointer of the same type to another pointee type. The utility is
|
||||||
|
defined in <cite><a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a>.</cite></p>
|
||||||
|
<p>There is test/example code in <cite><a href="test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a></cite>.</p>
|
||||||
|
<h2><a name="contents">Contents</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#rationale">Rationale</a>
|
||||||
|
<li>
|
||||||
|
<a href="#synopsis">Synopsis</a>
|
||||||
|
<li>
|
||||||
|
<a href="#example">Example</a></li>
|
||||||
|
</ul>
|
||||||
|
<h2><a name="rationale">Rationale</a></h2>
|
||||||
|
<p>When building pointer independent classes, like memory managers, allocators, or
|
||||||
|
containers, there is often a need to define pointers generically, so that if a
|
||||||
|
template parameter represents a pointer (for example, a raw or smart pointer to
|
||||||
|
an int), we can define another pointer of the same type to another pointee (a
|
||||||
|
raw or smart pointer to a float.)</p>
|
||||||
|
<pre>template <class IntPtr>
|
||||||
|
class FloatPointerHolder
|
||||||
|
{
|
||||||
|
<em>// Let's define a pointer to a float</em>
|
||||||
|
typedef typename boost::pointer_to_other
|
||||||
|
<IntPtr, float>::type float_ptr_t;
|
||||||
|
float_ptr_t float_ptr;
|
||||||
|
};</pre>
|
||||||
|
<h2><a name="synopsis">Synopsis</a></h2>
|
||||||
|
<pre>
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
struct pointer_to_other;
|
||||||
|
|
||||||
|
template<class T, class U, template <class> class Sp>
|
||||||
|
struct pointer_to_other< Sp<T>, U >
|
||||||
|
{
|
||||||
|
typedef Sp<U> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class T2, class U,
|
||||||
|
template <class, class> class Sp>
|
||||||
|
struct pointer_to_other< Sp<T, T2>, U >
|
||||||
|
{
|
||||||
|
typedef Sp<U, T2> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class T2, class T3, class U,
|
||||||
|
template <class, class, class> class Sp>
|
||||||
|
struct pointer_to_other< Sp<T, T2, T3>, U >
|
||||||
|
{
|
||||||
|
typedef Sp<U, T2, T3> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
struct pointer_to_other< T*, U >
|
||||||
|
{
|
||||||
|
typedef U* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} <em>// namespace boost</em></pre>
|
||||||
|
<p>If these definitions are not correct for a specific smart pointer, we can define
|
||||||
|
a specialization of pointer_to_other.</p>
|
||||||
|
<h2><a name="example">Example</a></h2>
|
||||||
|
<pre><em>// Let's define a memory allocator that can
|
||||||
|
// work with raw and smart pointers</em>
|
||||||
|
|
||||||
|
#include <boost/pointer_to_other.hpp>
|
||||||
|
|
||||||
|
template <class VoidPtr>
|
||||||
|
class memory_allocator
|
||||||
|
{<em>
|
||||||
|
// Predefine a memory_block </em>
|
||||||
|
struct block;<em>
|
||||||
|
|
||||||
|
// Define a pointer to a memory_block from a void pointer
|
||||||
|
// If VoidPtr is void *, block_ptr_t is block*
|
||||||
|
// If VoidPtr is smart_ptr<void>, block_ptr_t is smart_ptr<block></em>
|
||||||
|
typedef typename boost::pointer_to_other
|
||||||
|
<VoidPtr, block>::type block_ptr_t;
|
||||||
|
|
||||||
|
struct block
|
||||||
|
{
|
||||||
|
std::size_t size;
|
||||||
|
block_ptr_t next_block;
|
||||||
|
};
|
||||||
|
|
||||||
|
block_ptr_t free_blocks;
|
||||||
|
};</pre>
|
||||||
|
<p>As we can see, using pointer_to_other we can create pointer independent code.</p>
|
||||||
|
<hr>
|
||||||
|
<p>Last revised: $Date$</p>
|
||||||
|
<p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification,
|
||||||
|
and distribution are subject to the Boost Software License, Version 1.0.<br>
|
||||||
|
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a
|
||||||
|
copy at < <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</small></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="#ffffff" text="#000000">
|
<body bgcolor="#ffffff" text="#000000">
|
||||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"><a name="scoped_array">scoped_array</a>
|
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||||
class template</h1>
|
border="0"></A>scoped_array class template</h1>
|
||||||
<p>The <b>scoped_array</b> class template stores a pointer to a dynamically
|
<p>The <b>scoped_array</b> class template stores a pointer to a dynamically
|
||||||
allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
|
allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
|
||||||
expression.) The array pointed to is guaranteed to be deleted, either on
|
expression.) The array pointed to is guaranteed to be deleted, either on
|
||||||
@@ -14,10 +14,9 @@
|
|||||||
<p>The <b>scoped_array</b> template is a simple solution for simple needs. It
|
<p>The <b>scoped_array</b> template is a simple solution for simple needs. It
|
||||||
supplies a basic "resource acquisition is initialization" facility, without
|
supplies a basic "resource acquisition is initialization" facility, without
|
||||||
shared-ownership or transfer-of-ownership semantics. Both its name and
|
shared-ownership or transfer-of-ownership semantics. Both its name and
|
||||||
enforcement of semantics (by being
|
enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
|
||||||
<a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>) signal its intent to retain ownership solely within the
|
noncopyable</a>) signal its intent to retain ownership solely within the
|
||||||
current scope. Because it is
|
current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
|
||||||
<a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
|
|
||||||
it is safer than <b>shared_array</b> for pointers which should not be copied.</p>
|
it is safer than <b>shared_array</b> for pointers which should not be copied.</p>
|
||||||
<p>Because <b>scoped_array</b> is so simple, in its usual implementation every
|
<p>Because <b>scoped_array</b> is so simple, in its usual implementation every
|
||||||
operation is as fast as a built-in array pointer and it has no more space
|
operation is as fast as a built-in array pointer and it has no more space
|
||||||
@@ -48,6 +47,8 @@
|
|||||||
T & <a href="#operator[]">operator[]</a>(std::ptrdiff_t i) const; // never throws
|
T & <a href="#operator[]">operator[]</a>(std::ptrdiff_t i) const; // never throws
|
||||||
T * <a href="#get">get</a>() const; // never throws
|
T * <a href="#get">get</a>() const; // never throws
|
||||||
|
|
||||||
|
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
|
||||||
|
|
||||||
void <a href="#swap">swap</a>(scoped_array & b); // never throws
|
void <a href="#swap">swap</a>(scoped_array & b); // never throws
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,6 +91,10 @@
|
|||||||
<pre>T * get() const; // never throws</pre>
|
<pre>T * get() const; // never throws</pre>
|
||||||
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
|
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
|
||||||
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
|
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
|
||||||
|
<h3><a name="conversions">conversions</a></h3>
|
||||||
|
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
|
||||||
|
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
|
||||||
|
to <code>get() != 0</code>.</p>
|
||||||
<h3><a name="swap">swap</a></h3>
|
<h3><a name="swap">swap</a></h3>
|
||||||
<pre>void swap(scoped_array & b); // never throws</pre>
|
<pre>void swap(scoped_array & b); // never throws</pre>
|
||||||
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
|
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
|
||||||
@@ -101,11 +106,11 @@
|
|||||||
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
|
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
|
||||||
Provided as an aid to generic programming.</p>
|
Provided as an aid to generic programming.</p>
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan-->09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
|
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan-->
|
||||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
|
||||||
Permission to copy, use, modify, sell and distribute this document is granted
|
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||||
provided this copyright notice appears in all copies. This document is provided
|
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
"as is" without express or implied warranty, and with no claim as to its
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
suitability for any purpose.</p>
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="#ffffff" text="#000000">
|
<body bgcolor="#ffffff" text="#000000">
|
||||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"><a name="scoped_ptr">scoped_ptr</a>
|
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||||
class template</h1>
|
border="0"></A>scoped_ptr class template</h1>
|
||||||
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated
|
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated
|
||||||
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
|
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
|
||||||
The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>,
|
The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>,
|
||||||
@@ -48,6 +48,8 @@
|
|||||||
T * <a href="#indirection">operator-></a>() const; // never throws
|
T * <a href="#indirection">operator-></a>() const; // never throws
|
||||||
T * <a href="#get">get</a>() const; // never throws
|
T * <a href="#get">get</a>() const; // never throws
|
||||||
|
|
||||||
|
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
|
||||||
|
|
||||||
void <a href="#swap">swap</a>(scoped_ptr & b); // never throws
|
void <a href="#swap">swap</a>(scoped_ptr & b); // never throws
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,6 +92,10 @@
|
|||||||
<pre>T * get() const; // never throws</pre>
|
<pre>T * get() const; // never throws</pre>
|
||||||
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
|
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
|
||||||
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
|
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
|
||||||
|
<h3><a name="conversions">conversions</a></h3>
|
||||||
|
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
|
||||||
|
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
|
||||||
|
to <code>get() != 0</code>.</p>
|
||||||
<h3><a name="swap">swap</a></h3>
|
<h3><a name="swap">swap</a></h3>
|
||||||
<pre>void swap(scoped_ptr & b); // never throws</pre>
|
<pre>void swap(scoped_ptr & b); // never throws</pre>
|
||||||
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
|
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
|
||||||
@@ -150,8 +156,8 @@ Buckle my shoe</pre>
|
|||||||
<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called
|
<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called
|
||||||
pimpl) idiom which avoids exposing the body (implementation) in the header
|
pimpl) idiom which avoids exposing the body (implementation) in the header
|
||||||
file.</p>
|
file.</p>
|
||||||
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a> sample
|
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
|
||||||
program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
|
sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
|
||||||
which uses a <b>scoped_ptr<></b> to an incomplete type to hide the
|
which uses a <b>scoped_ptr<></b> to an incomplete type to hide the
|
||||||
implementation. The instantiation of member functions which require a complete
|
implementation. The instantiation of member functions which require a complete
|
||||||
type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
|
type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
|
||||||
@@ -167,10 +173,9 @@ Buckle my shoe</pre>
|
|||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
|
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
|
||||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
||||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||||
Copyright 2002 Peter Dimov. Permission to copy, use, modify, sell and
|
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
distribute this document is granted provided this copyright notice appears in
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
all copies. This document is provided "as is" without express or implied
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
warranty, and with no claim as to its suitability for any purpose.</p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="#ffffff" text="#000000">
|
<body bgcolor="#ffffff" text="#000000">
|
||||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86">shared_array
|
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||||
class template</h1>
|
border="0"></A>shared_array class template</h1>
|
||||||
<p>The <b>shared_array</b> class template stores a pointer to a dynamically
|
<p>The <b>shared_array</b> class template stores a pointer to a dynamically
|
||||||
allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
|
allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
|
||||||
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
|
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
|
||||||
@@ -53,6 +53,8 @@
|
|||||||
bool <a href="#unique">unique</a>() const; // never throws
|
bool <a href="#unique">unique</a>() const; // never throws
|
||||||
long <a href="#use_count">use_count</a>() const; // never throws
|
long <a href="#use_count">use_count</a>() const; // never throws
|
||||||
|
|
||||||
|
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
|
||||||
|
|
||||||
void <a href="#swap">swap</a>(shared_array<T> & b); // never throws
|
void <a href="#swap">swap</a>(shared_array<T> & b); // never throws
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -139,6 +141,10 @@
|
|||||||
implementations of <b>shared_array</b> that do not use an explicit reference
|
implementations of <b>shared_array</b> that do not use an explicit reference
|
||||||
count, it might be removed from some future version. Thus it should be used for
|
count, it might be removed from some future version. Thus it should be used for
|
||||||
debugging purposes only, and not production code.</p>
|
debugging purposes only, and not production code.</p>
|
||||||
|
<h3><a name="conversions">conversions</a></h3>
|
||||||
|
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
|
||||||
|
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent
|
||||||
|
to <code>get() != 0</code>.</p>
|
||||||
<h3><a name="swap">swap</a></h3>
|
<h3><a name="swap">swap</a></h3>
|
||||||
<pre>void swap(shared_ptr & b); // never throws</pre>
|
<pre>void swap(shared_ptr & b); // never throws</pre>
|
||||||
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
|
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
|
||||||
@@ -171,10 +177,9 @@ template<class T>
|
|||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
|
||||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
||||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||||
Permission to copy, use, modify, sell and distribute this document is granted
|
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
provided this copyright notice appears in all copies. This document is provided
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
"as is" without express or implied warranty, and with no claim as to its
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
suitability for any purpose.</p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body text="#000000" bgColor="#ffffff">
|
<body text="#000000" bgColor="#ffffff">
|
||||||
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">shared_ptr
|
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||||
class template</h1>
|
border="0"></A>shared_ptr class template</h1>
|
||||||
<p><A href="#Introduction">Introduction</A><br>
|
<p><A href="#Introduction">Introduction</A><br>
|
||||||
<A href="#BestPractices">Best Practices</A><br>
|
<A href="#BestPractices">Best Practices</A><br>
|
||||||
<A href="#Synopsis">Synopsis</A><br>
|
<A href="#Synopsis">Synopsis</A><br>
|
||||||
@@ -106,10 +106,12 @@ void bad()
|
|||||||
<A href="#constructors" >shared_ptr</A>(); // never throws
|
<A href="#constructors" >shared_ptr</A>(); // never throws
|
||||||
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(Y * p);
|
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(Y * p);
|
||||||
template<class Y, class D> <A href="#constructors" >shared_ptr</A>(Y * p, D d);
|
template<class Y, class D> <A href="#constructors" >shared_ptr</A>(Y * p, D d);
|
||||||
|
template<class Y, class D, class A> <A href="#allocator_constructor" >shared_ptr</A>(Y * p, D d, A a);
|
||||||
<A href="#destructor" >~shared_ptr</A>(); // never throws
|
<A href="#destructor" >~shared_ptr</A>(); // never throws
|
||||||
|
|
||||||
<A href="#constructors" >shared_ptr</A>(shared_ptr const & r); // never throws
|
<A href="#constructors" >shared_ptr</A>(shared_ptr const & r); // never throws
|
||||||
template<class Y> <A href="#constructors" >shared_ptr</A>(shared_ptr<Y> const & r); // never throws
|
template<class Y> <A href="#constructors" >shared_ptr</A>(shared_ptr<Y> const & r); // never throws
|
||||||
|
template<class Y> <A href="#constructors" >shared_ptr</A>(shared_ptr<Y> const & r, T * p); // never throws
|
||||||
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r);
|
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r);
|
||||||
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(std::auto_ptr<Y> & r);
|
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(std::auto_ptr<Y> & r);
|
||||||
|
|
||||||
@@ -120,6 +122,8 @@ void bad()
|
|||||||
void <A href="#reset" >reset</A>(); // never throws
|
void <A href="#reset" >reset</A>(); // never throws
|
||||||
template<class Y> void <A href="#reset" >reset</A>(Y * p);
|
template<class Y> void <A href="#reset" >reset</A>(Y * p);
|
||||||
template<class Y, class D> void <A href="#reset" >reset</A>(Y * p, D d);
|
template<class Y, class D> void <A href="#reset" >reset</A>(Y * p, D d);
|
||||||
|
template<class Y, class D, class A> void <A href="#reset" >reset</A>(Y * p, D d, A a);
|
||||||
|
template<class Y> void <A href="#reset" >reset</A>(shared_ptr<Y> const & r, T * p); // never throws
|
||||||
|
|
||||||
T & <A href="#indirection" >operator*</A>() const; // never throws
|
T & <A href="#indirection" >operator*</A>() const; // never throws
|
||||||
T * <A href="#indirection" >operator-></A>() const; // never throws
|
T * <A href="#indirection" >operator-></A>() const; // never throws
|
||||||
@@ -203,15 +207,20 @@ void bad()
|
|||||||
The current implementation uses a different mechanism, <A href="enable_shared_from_this.html">
|
The current implementation uses a different mechanism, <A href="enable_shared_from_this.html">
|
||||||
enable_shared_from_this</A>, to solve the "<STRONG>shared_ptr</STRONG> from <STRONG>
|
enable_shared_from_this</A>, to solve the "<STRONG>shared_ptr</STRONG> from <STRONG>
|
||||||
this</STRONG>" problem.</EM><EM>]</EM></P>
|
this</STRONG>" problem.</EM><EM>]</EM></P>
|
||||||
<pre>template<class Y, class D> shared_ptr(Y * p, D d);</pre>
|
<a name="allocator_constructor"></a>
|
||||||
|
<pre>template<class Y, class D> shared_ptr(Y * p, D d);
|
||||||
|
template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. <STRONG>D</STRONG>
|
<p><b>Requirements:</b> <B>p</B> must be convertible to <B>T *</B>. <STRONG>D</STRONG>
|
||||||
must be <STRONG>CopyConstructible</STRONG>. The copy constructor and destructor
|
must be <STRONG>CopyConstructible</STRONG>. The copy constructor and destructor
|
||||||
of <b>D</b> must not throw. The expression <code>d(p)</code> must be
|
of <b>D</b> must not throw. The expression <code>d(p)</code> must be
|
||||||
well-formed, must not invoke undefined behavior, and must not throw exceptions.
|
well-formed, must not invoke undefined behavior, and must not throw exceptions. <STRONG>
|
||||||
|
A</STRONG> must be an <EM>Allocator</EM>, as described in section 20.1.5 (<STRONG>Allocator
|
||||||
|
requirements</STRONG>) of the C++ Standard.
|
||||||
</p>
|
</p>
|
||||||
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <STRONG>
|
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <STRONG>
|
||||||
p</STRONG> and the deleter <b>d</b>.</p>
|
p</STRONG> and the deleter <b>d</b>. The second constructor allocates
|
||||||
|
memory using a copy of <STRONG>a</STRONG>.</p>
|
||||||
<p><b>Postconditions:</b> <code>use_count() == 1 && get() == p</code>.</p>
|
<p><b>Postconditions:</b> <code>use_count() == 1 && get() == p</code>.</p>
|
||||||
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
|
<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
|
||||||
exception when a resource other than memory could not be obtained.</p>
|
exception when a resource other than memory could not be obtained.</p>
|
||||||
@@ -246,6 +255,13 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never
|
|||||||
r.use_count()</code>.</p>
|
r.use_count()</code>.</p>
|
||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
<pre>template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Effects:</b> constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
|
||||||
|
<b>r</b> and stores <b>p</b>.</p>
|
||||||
|
<p><b>Postconditions:</b> <code>get() == p && use_count() == r.use_count()</code>.</p>
|
||||||
|
<p><b>Throws:</b> nothing.</p>
|
||||||
|
</blockquote>
|
||||||
<pre>template<class Y> explicit shared_ptr(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r);</pre>
|
<pre>template<class Y> explicit shared_ptr(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r);</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
|
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
|
||||||
@@ -317,6 +333,14 @@ q = p;
|
|||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</P>
|
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
<pre>template<class Y, class D, class A> void reset(Y * p, D d, A a);</pre>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d, a).swap(*this)</code>.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
<pre>template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws</pre>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P><B>Effects:</B> Equivalent to <code>shared_ptr(r, p).swap(*this)</code>.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
<h3><a name="indirection">indirection</a></h3>
|
<h3><a name="indirection">indirection</a></h3>
|
||||||
<pre>T & operator*() const; // never throws</pre>
|
<pre>T & operator*() const; // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
@@ -621,7 +645,7 @@ p3.reset(new int(2)); // undefined, multiple writes
|
|||||||
day a highly configurable smart pointer may be invented that is also very easy
|
day a highly configurable smart pointer may be invented that is also very easy
|
||||||
to use and very hard to misuse. Until then, <B>shared_ptr</B> is the smart
|
to use and very hard to misuse. Until then, <B>shared_ptr</B> is the smart
|
||||||
pointer of choice for a wide range of applications. (Those interested in policy
|
pointer of choice for a wide range of applications. (Those interested in policy
|
||||||
based smart pointers should read <A href="http://cseng.aw.com/book/0,,0201704315,00.html">
|
based smart pointers should read <A href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&rl=1">
|
||||||
Modern C++ Design</A> by Andrei Alexandrescu.)<BR>
|
Modern C++ Design</A> by Andrei Alexandrescu.)<BR>
|
||||||
</P>
|
</P>
|
||||||
<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate
|
<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate
|
||||||
@@ -685,9 +709,8 @@ int * p = a.release();
|
|||||||
<p>
|
<p>
|
||||||
$Date$</p>
|
$Date$</p>
|
||||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||||
Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and
|
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
distribute this document is granted provided this copyright notice appears in
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
all copies. This document is provided "as is" without express or implied
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="#ffffff" text="#000000">
|
<body bgcolor="#ffffff" text="#000000">
|
||||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86">Smart
|
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||||
Pointers</h1>
|
border="0"></A>Smart Pointers</h1>
|
||||||
<p><a href="#Introduction">Introduction</a><br>
|
<p><a href="#Introduction">Introduction</a><br>
|
||||||
<a href="#common_requirements">Common Requirements</a><br>
|
<a href="#common_requirements">Common Requirements</a><br>
|
||||||
<a href="#Exception_Safety">Exception Safety</a><br>
|
<a href="#Exception_Safety">Exception Safety</a><br>
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
and that is thrown only by functions which are explicitly documented as
|
and that is thrown only by functions which are explicitly documented as
|
||||||
possibly throwing <b>std::bad_alloc</b>.</p>
|
possibly throwing <b>std::bad_alloc</b>.</p>
|
||||||
<h2><a name="Exception-specifications">Exception-specifications</a></h2>
|
<h2><a name="Exception-specifications">Exception-specifications</a></h2>
|
||||||
<p>Exception-specifications are not used; see <a href="../../more/lib_guide.htm#Exception-specification">
|
<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
|
||||||
exception-specification rationale</a>.</p>
|
exception-specification rationale</a>.</p>
|
||||||
<p>All the smart pointer templates contain member functions which can never throw
|
<p>All the smart pointer templates contain member functions which can never throw
|
||||||
exceptions, because they neither throw exceptions themselves nor call other
|
exceptions, because they neither throw exceptions themselves nor call other
|
||||||
@@ -177,10 +177,9 @@
|
|||||||
and an extensive bibliography.</p>
|
and an extensive bibliography.</p>
|
||||||
<hr>
|
<hr>
|
||||||
<p>$Date$</p>
|
<p>$Date$</p>
|
||||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||||
Permission to copy, use, modify, sell and distribute this document is granted
|
Distributed under the Boost Software License, Version 1.0. See accompanying
|
||||||
provided this copyright notice appears in all copies. This document is provided
|
file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at
|
||||||
"as is" without express or implied warranty, and with no claim as to its
|
<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
suitability for any purpose.</p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -21,10 +21,10 @@
|
|||||||
mailing list and the tests which this page describes were performed to provide
|
mailing list and the tests which this page describes were performed to provide
|
||||||
a guide for current and future investigations into smart pointer implementation
|
a guide for current and future investigations into smart pointer implementation
|
||||||
strategies.</p>
|
strategies.</p>
|
||||||
<p>Thanks are due to <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>,
|
<p>Thanks are due to <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>,
|
||||||
Gavin Collings,
|
Gavin Collings,
|
||||||
<a href="../../people/greg_colvin.htm">Greg Colvin</a> and
|
<a href="http://www.boost.org/people/greg_colvin.htm">Greg Colvin</a> and
|
||||||
<a href="../../people/beman_dawes.html">Beman Dawes</a>
|
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a>
|
||||||
for test code and trial implementations, the final version of which can be found
|
for test code and trial implementations, the final version of which can be found
|
||||||
in .zip format <a href="smarttest.zip">here</a>.</p>
|
in .zip format <a href="smarttest.zip">here</a>.</p>
|
||||||
<h2>Description</h2>
|
<h2>Description</h2>
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body text="#000000" bgColor="#ffffff">
|
<body text="#000000" bgColor="#ffffff">
|
||||||
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">Smart
|
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||||
Pointer Programming Techniques</h1>
|
border="0"></A>Smart Pointer Programming Techniques</h1>
|
||||||
<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
|
<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
|
||||||
<A href="#pimpl">The "Pimpl" idiom</A><br>
|
<A href="#pimpl">The "Pimpl" idiom</A><br>
|
||||||
<A href="#abstract">Using abstract classes for implementation hiding</A><br>
|
<A href="#abstract">Using abstract classes for implementation hiding</A><br>
|
||||||
@@ -519,6 +519,9 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
<p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member
|
||||||
|
in <code><A href="enable_shared_from_this.html">enable_shared_from_this</A></code>.
|
||||||
|
Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p>
|
||||||
<h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2>
|
<h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2>
|
||||||
<p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
|
<p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
|
||||||
incomplete class technique</A> described above. An example:</p>
|
incomplete class technique</A> described above. An example:</p>
|
||||||
@@ -755,9 +758,8 @@ public:
|
|||||||
all weak pointers will automatically expire.</p>
|
all weak pointers will automatically expire.</p>
|
||||||
<hr>
|
<hr>
|
||||||
<p>$Date$</p>
|
<p>$Date$</p>
|
||||||
<p><small>Copyright <20> 2003 Peter Dimov. Permission to copy, use, modify, sell and
|
<p><small>Copyright <20> 2003 Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
distribute this document is granted provided this copyright notice appears in
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
all copies. This document is provided "as is" without express or implied
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
44
test/Jamfile
44
test/Jamfile
@@ -1,44 +0,0 @@
|
|||||||
# Boost.SmartPtr Library test Jamfile
|
|
||||||
#
|
|
||||||
# Copyright (c) 2003-2005 Peter Dimov
|
|
||||||
# Copyright (c) 2003 Dave Abrahams
|
|
||||||
#
|
|
||||||
# Permission to copy, use, modify, sell and distribute this software
|
|
||||||
# is granted provided this copyright notice appears in all copies.
|
|
||||||
# This software is provided "as is" without express or implied
|
|
||||||
# warranty, and with no claim as to its suitability for any purpose.
|
|
||||||
|
|
||||||
subproject libs/smart_ptr/test ;
|
|
||||||
|
|
||||||
# bring in rules for testing
|
|
||||||
import testing ;
|
|
||||||
|
|
||||||
# Make tests run by default.
|
|
||||||
DEPENDS all : smart_ptr ;
|
|
||||||
|
|
||||||
{
|
|
||||||
test-suite "smart_ptr"
|
|
||||||
: [ run smart_ptr_test.cpp ]
|
|
||||||
[ run shared_ptr_basic_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
|
|
||||||
[ run shared_ptr_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
|
|
||||||
[ run weak_ptr_test.cpp ]
|
|
||||||
[ run shared_from_this_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
|
|
||||||
[ run get_deleter_test.cpp ]
|
|
||||||
[ run intrusive_ptr_test.cpp ]
|
|
||||||
[ run intrusive_ptr_test.cpp ]
|
|
||||||
[ run atomic_count_test.cpp ]
|
|
||||||
[ run lw_mutex_test.cpp ]
|
|
||||||
[ compile-fail shared_ptr_assign_fail.cpp ]
|
|
||||||
[ compile-fail shared_ptr_delete_fail.cpp ]
|
|
||||||
;
|
|
||||||
|
|
||||||
# this one is too slow to run unless explicitly requested, and ALL
|
|
||||||
# tests are run by default when this file is subincluded from
|
|
||||||
# boost/status, so it's guarded from that case. It will only be
|
|
||||||
# built from this directory when the targets "test" (all tests) or
|
|
||||||
# "shared_ptr_alloc_test" are requested.
|
|
||||||
if [ in-invocation-subdir ]
|
|
||||||
{
|
|
||||||
run shared_ptr_alloc_test.cpp ;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,12 +1,11 @@
|
|||||||
# Boost.SmartPtr Library test Jamfile
|
# Boost.SmartPtr Library test Jamfile
|
||||||
#
|
#
|
||||||
# Copyright (c) 2003-2005 Peter Dimov
|
# Copyright (c) 2003-2007 Peter Dimov
|
||||||
# Copyright (c) 2003 Dave Abrahams
|
# Copyright (c) 2003 Dave Abrahams
|
||||||
#
|
#
|
||||||
# Permission to copy, use, modify, sell and distribute this software
|
# Distributed under the Boost Software License, Version 1.0. (See
|
||||||
# is granted provided this copyright notice appears in all copies.
|
# accompanying file LICENSE_1_0.txt or copy at
|
||||||
# This software is provided "as is" without express or implied
|
# http://www.boost.org/LICENSE_1_0.txt)
|
||||||
# warranty, and with no claim as to its suitability for any purpose.
|
|
||||||
|
|
||||||
# bring in rules for testing
|
# bring in rules for testing
|
||||||
import testing ;
|
import testing ;
|
||||||
@@ -24,5 +23,15 @@ import testing ;
|
|||||||
[ run lw_mutex_test.cpp ]
|
[ run lw_mutex_test.cpp ]
|
||||||
[ compile-fail shared_ptr_assign_fail.cpp ]
|
[ compile-fail shared_ptr_assign_fail.cpp ]
|
||||||
[ compile-fail shared_ptr_delete_fail.cpp ]
|
[ compile-fail shared_ptr_delete_fail.cpp ]
|
||||||
|
[ compile-fail shared_ptr_compare_fail.cpp ]
|
||||||
|
[ run shared_ptr_alloc2_test.cpp ]
|
||||||
|
[ run pointer_cast_test.cpp ]
|
||||||
|
[ compile pointer_to_other_test.cpp ]
|
||||||
|
[ run auto_ptr_rv_test.cpp ]
|
||||||
|
[ run shared_ptr_alias_test.cpp ]
|
||||||
|
[ run shared_ptr_rv_test.cpp ]
|
||||||
|
[ run shared_ptr_move_test.cpp ]
|
||||||
|
[ compile-fail shared_ptr_pv_fail.cpp ]
|
||||||
|
[ run sp_unary_addr_test.cpp ]
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
111
test/auto_ptr_rv_test.cpp
Normal file
111
test/auto_ptr_rv_test.cpp
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
//
|
||||||
|
// auto_ptr_rv_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
static long instances;
|
||||||
|
|
||||||
|
X()
|
||||||
|
{
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~X()
|
||||||
|
{
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::auto_ptr<X> create()
|
||||||
|
{
|
||||||
|
return std::auto_ptr<X>( new X );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
X( X const & );
|
||||||
|
X & operator=( X const & );
|
||||||
|
};
|
||||||
|
|
||||||
|
long X::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X const> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<void> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<void const> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
126
test/pointer_cast_test.cpp
Normal file
126
test/pointer_cast_test.cpp
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
//
|
||||||
|
// pointer_cast_test.cpp - a test for boost/pointer_cast.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 Ion Gazta<74>aga
|
||||||
|
// Copyright (c) 2005 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/pointer_cast.hpp>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <boost/get_pointer.hpp>
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
// Let's create these inheritance relationship:
|
||||||
|
//
|
||||||
|
// base base2
|
||||||
|
// | |
|
||||||
|
// derived
|
||||||
|
// |
|
||||||
|
// derived_derived
|
||||||
|
//
|
||||||
|
|
||||||
|
class base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~base(){}
|
||||||
|
int filler [5];
|
||||||
|
};
|
||||||
|
|
||||||
|
class base2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~base2(){}
|
||||||
|
int filler [5];
|
||||||
|
};
|
||||||
|
|
||||||
|
class derived
|
||||||
|
: public base, public base2
|
||||||
|
{
|
||||||
|
int filler [5];
|
||||||
|
};
|
||||||
|
|
||||||
|
class derived_derived
|
||||||
|
: public derived
|
||||||
|
{
|
||||||
|
int filler [5];
|
||||||
|
};
|
||||||
|
|
||||||
|
// And now some simple check functions
|
||||||
|
|
||||||
|
template <class BasePtr>
|
||||||
|
bool check_dynamic_pointer_cast(const BasePtr &ptr)
|
||||||
|
{
|
||||||
|
//Check that dynamic_pointer_cast versus dynamic_cast
|
||||||
|
return
|
||||||
|
//Correct cast with dynamic_pointer_cast
|
||||||
|
boost::get_pointer(boost::dynamic_pointer_cast<derived>(ptr)) ==
|
||||||
|
//Correct cast with dynamic_cast
|
||||||
|
dynamic_cast<derived*>(boost::get_pointer(ptr))
|
||||||
|
&&
|
||||||
|
//Incorrect cast with dynamic_pointer_cast
|
||||||
|
boost::get_pointer(boost::dynamic_pointer_cast<derived_derived>(ptr)) ==
|
||||||
|
//Incorrect cast with dynamic_cast
|
||||||
|
dynamic_cast<derived_derived*>(boost::get_pointer(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class BasePtr>
|
||||||
|
bool check_static_pointer_cast(const BasePtr &ptr)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
//Cast base -> derived -> base2 using static_pointer_cast
|
||||||
|
boost::get_pointer(
|
||||||
|
boost::static_pointer_cast<base2>(
|
||||||
|
boost::static_pointer_cast<derived>(ptr))) ==
|
||||||
|
//Now the same with static_cast
|
||||||
|
static_cast<base2*>(static_cast<derived*>(boost::get_pointer(ptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class BasePtr>
|
||||||
|
bool check_const_pointer_cast(const BasePtr &ptr)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
//Unconst and const again using const_pointer_cast
|
||||||
|
boost::get_pointer(
|
||||||
|
boost::const_pointer_cast<const base>
|
||||||
|
(boost::const_pointer_cast<base>(ptr))) ==
|
||||||
|
//Now the same with const_cast
|
||||||
|
const_cast<const base*>(const_cast<base*>(boost::get_pointer(ptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// Try casts with shared_ptr
|
||||||
|
|
||||||
|
boost::shared_ptr<base> ptr(new derived);
|
||||||
|
|
||||||
|
BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
|
||||||
|
BOOST_TEST( check_static_pointer_cast( ptr ) );
|
||||||
|
BOOST_TEST( check_const_pointer_cast( ptr ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Try casts with raw pointer
|
||||||
|
|
||||||
|
boost::scoped_ptr<base> ptr(new derived);
|
||||||
|
|
||||||
|
BOOST_TEST( check_dynamic_pointer_cast( ptr.get() ) );
|
||||||
|
BOOST_TEST( check_static_pointer_cast( ptr.get() ) );
|
||||||
|
BOOST_TEST( check_const_pointer_cast( ptr.get() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
74
test/pointer_to_other_test.cpp
Normal file
74
test/pointer_to_other_test.cpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// pointer_to_other_test.cpp - a test for boost/pointer_to_other.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/pointer_to_other.hpp>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/shared_array.hpp>
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <boost/scoped_array.hpp>
|
||||||
|
#include <boost/intrusive_ptr.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
template<class T, class U> void assert_same_type( T** pt = 0, U** pu = 0 )
|
||||||
|
{
|
||||||
|
pt = pu;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct X;
|
||||||
|
struct Y;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// shared_ptr
|
||||||
|
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::shared_ptr<X>, Y >::type, boost::shared_ptr<Y> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::shared_ptr<X>, void >::type, boost::shared_ptr<void> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::shared_ptr<void>, Y >::type, boost::shared_ptr<Y> >();
|
||||||
|
|
||||||
|
// shared_array
|
||||||
|
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::shared_array<X>, Y >::type, boost::shared_array<Y> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::shared_array<X>, void >::type, boost::shared_array<void> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::shared_array<void>, Y >::type, boost::shared_array<Y> >();
|
||||||
|
|
||||||
|
// scoped_ptr
|
||||||
|
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::scoped_ptr<X>, Y >::type, boost::scoped_ptr<Y> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::scoped_ptr<X>, void >::type, boost::scoped_ptr<void> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::scoped_ptr<void>, Y >::type, boost::scoped_ptr<Y> >();
|
||||||
|
|
||||||
|
// scoped_array
|
||||||
|
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::scoped_array<X>, Y >::type, boost::scoped_array<Y> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::scoped_array<X>, void >::type, boost::scoped_array<void> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::scoped_array<void>, Y >::type, boost::scoped_array<Y> >();
|
||||||
|
|
||||||
|
// intrusive_ptr
|
||||||
|
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::intrusive_ptr<X>, Y >::type, boost::intrusive_ptr<Y> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::intrusive_ptr<X>, void >::type, boost::intrusive_ptr<void> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< boost::intrusive_ptr<void>, Y >::type, boost::intrusive_ptr<Y> >();
|
||||||
|
|
||||||
|
// auto_ptr
|
||||||
|
|
||||||
|
assert_same_type< boost::pointer_to_other< std::auto_ptr<X>, Y >::type, std::auto_ptr<Y> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< std::auto_ptr<X>, void >::type, std::auto_ptr<void> >();
|
||||||
|
assert_same_type< boost::pointer_to_other< std::auto_ptr<void>, Y >::type, std::auto_ptr<Y> >();
|
||||||
|
|
||||||
|
// raw pointer
|
||||||
|
|
||||||
|
assert_same_type< boost::pointer_to_other< X *, Y >::type, Y * >();
|
||||||
|
assert_same_type< boost::pointer_to_other< X *, void >::type, void * >();
|
||||||
|
assert_same_type< boost::pointer_to_other< void *, Y >::type, Y * >();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
146
test/shared_ptr_alias_test.cpp
Normal file
146
test/shared_ptr_alias_test.cpp
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
// shared_ptr_alias_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
class incomplete;
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
int v_;
|
||||||
|
|
||||||
|
explicit X( int v ): v_( v )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~X()
|
||||||
|
{
|
||||||
|
v_ = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
int m = 0;
|
||||||
|
boost::shared_ptr< int > p;
|
||||||
|
boost::shared_ptr< int > p2( p, &m );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == &m );
|
||||||
|
BOOST_TEST( p2? true: false );
|
||||||
|
BOOST_TEST( !!p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||||
|
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||||
|
|
||||||
|
p2.reset( p, 0 );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
BOOST_TEST( p2? false: true );
|
||||||
|
BOOST_TEST( !p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||||
|
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int m = 0;
|
||||||
|
boost::shared_ptr< int > p( new int );
|
||||||
|
boost::shared_ptr< int const > p2( p, &m );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == &m );
|
||||||
|
BOOST_TEST( p2? true: false );
|
||||||
|
BOOST_TEST( !!p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||||
|
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||||
|
|
||||||
|
boost::shared_ptr< int volatile > p3;
|
||||||
|
p2.reset( p3, 0 );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
BOOST_TEST( p2? false: true );
|
||||||
|
BOOST_TEST( !p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p3.use_count() );
|
||||||
|
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< int > p( new int );
|
||||||
|
boost::shared_ptr< void const > p2( p, 0 );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
BOOST_TEST( p2? false: true );
|
||||||
|
BOOST_TEST( !p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||||
|
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||||
|
|
||||||
|
int m = 0;
|
||||||
|
boost::shared_ptr< void volatile > p3;
|
||||||
|
|
||||||
|
p2.reset( p3, &m );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == &m );
|
||||||
|
BOOST_TEST( p2? true: false );
|
||||||
|
BOOST_TEST( !!p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p3.use_count() );
|
||||||
|
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< incomplete > p;
|
||||||
|
boost::shared_ptr< incomplete > p2( p, 0 );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
BOOST_TEST( p2? false: true );
|
||||||
|
BOOST_TEST( !p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||||
|
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||||
|
|
||||||
|
p2.reset( p, 0 );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
BOOST_TEST( p2? false: true );
|
||||||
|
BOOST_TEST( !p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||||
|
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X > p( new X( 5 ) );
|
||||||
|
boost::shared_ptr< int const > p2( p, &p->v_ );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == &p->v_ );
|
||||||
|
BOOST_TEST( p2? true: false );
|
||||||
|
BOOST_TEST( !!p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||||
|
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( *p2 == 5 );
|
||||||
|
|
||||||
|
boost::shared_ptr< X const > p3( new X( 8 ) );
|
||||||
|
p2.reset( p3, &p3->v_ );
|
||||||
|
|
||||||
|
BOOST_TEST( p2.get() == &p3->v_ );
|
||||||
|
BOOST_TEST( p2? true: false );
|
||||||
|
BOOST_TEST( !!p2 );
|
||||||
|
BOOST_TEST( p2.use_count() == p3.use_count() );
|
||||||
|
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
|
||||||
|
|
||||||
|
p3.reset();
|
||||||
|
BOOST_TEST( *p2 == 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
224
test/shared_ptr_alloc2_test.cpp
Normal file
224
test/shared_ptr_alloc2_test.cpp
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
// shared_ptr_alloc2_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
// test_allocator
|
||||||
|
|
||||||
|
struct test_allocator_base
|
||||||
|
{
|
||||||
|
int id_;
|
||||||
|
|
||||||
|
static int last_global_id_;
|
||||||
|
static int count_;
|
||||||
|
|
||||||
|
explicit test_allocator_base( int id ): id_( id )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int test_allocator_base::last_global_id_ = 0;
|
||||||
|
int test_allocator_base::count_ = 0;
|
||||||
|
|
||||||
|
template<class T> class test_allocator: public test_allocator_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T * pointer;
|
||||||
|
typedef T const * const_pointer;
|
||||||
|
typedef T & reference;
|
||||||
|
typedef T const & const_reference;
|
||||||
|
typedef T value_type;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static T * last_pointer_;
|
||||||
|
static std::size_t last_n_;
|
||||||
|
static int last_id_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<class U> struct rebind
|
||||||
|
{
|
||||||
|
typedef test_allocator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
pointer address( reference r ) const
|
||||||
|
{
|
||||||
|
return &r;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer address( const_reference s ) const
|
||||||
|
{
|
||||||
|
return &s;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit test_allocator( int id = 0 ): test_allocator_base( id )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U> test_allocator & operator=( test_allocator<U> const & r )
|
||||||
|
{
|
||||||
|
test_allocator_base::operator=( r );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate( pointer p, size_type n )
|
||||||
|
{
|
||||||
|
BOOST_TEST( p == last_pointer_ );
|
||||||
|
BOOST_TEST( n == last_n_ );
|
||||||
|
BOOST_TEST( id_ == last_id_ );
|
||||||
|
|
||||||
|
--count_;
|
||||||
|
|
||||||
|
::operator delete( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer allocate( size_type n, void const * )
|
||||||
|
{
|
||||||
|
T * p = static_cast< T* >( ::operator new( n * sizeof( T ) ) );
|
||||||
|
|
||||||
|
last_pointer_ = p;
|
||||||
|
last_n_ = n;
|
||||||
|
last_id_ = id_;
|
||||||
|
|
||||||
|
last_global_id_ = id_;
|
||||||
|
++count_;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void construct( pointer p, T const & t )
|
||||||
|
{
|
||||||
|
new( p ) T( t );
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy( pointer p )
|
||||||
|
{
|
||||||
|
p->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type max_size() const
|
||||||
|
{
|
||||||
|
return size_type( -1 ) / sizeof( T );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> T * test_allocator<T>::last_pointer_ = 0;
|
||||||
|
template<class T> std::size_t test_allocator<T>::last_n_ = 0;
|
||||||
|
template<class T> int test_allocator<T>::last_id_ = 0;
|
||||||
|
|
||||||
|
template<class T, class U> inline bool operator==( test_allocator<T> const & a1, test_allocator<U> const & a2 )
|
||||||
|
{
|
||||||
|
return a1.id_ == a2.id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class U> inline bool operator!=( test_allocator<T> const & a1, test_allocator<U> const & a2 )
|
||||||
|
{
|
||||||
|
return a1.id_ != a2.id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> class test_allocator<void>: public test_allocator_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef void * pointer;
|
||||||
|
typedef void const * const_pointer;
|
||||||
|
typedef void value_type;
|
||||||
|
|
||||||
|
template<class U> struct rebind
|
||||||
|
{
|
||||||
|
typedef test_allocator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit test_allocator( int id = 0 ): test_allocator_base( id )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class U> test_allocator & operator=( test_allocator<U> const & r )
|
||||||
|
{
|
||||||
|
test_allocator_base::operator=( r );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
static int instances;
|
||||||
|
|
||||||
|
X()
|
||||||
|
{
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~X()
|
||||||
|
{
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
X( X const & );
|
||||||
|
X & operator=( X const & );
|
||||||
|
};
|
||||||
|
|
||||||
|
int X::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
boost::shared_ptr<void> pv( new X, boost::checked_deleter<X>(), std::allocator<X>() );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
pv.reset( new X, boost::checked_deleter<X>(), test_allocator<float>( 42 ) );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
BOOST_TEST( test_allocator_base::last_global_id_ == 42 );
|
||||||
|
BOOST_TEST( test_allocator_base::count_ > 0 );
|
||||||
|
|
||||||
|
pv.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
BOOST_TEST( test_allocator_base::count_ == 0 );
|
||||||
|
|
||||||
|
pv.reset( new X, boost::checked_deleter<X>(), test_allocator<void>( 43 ) );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
BOOST_TEST( test_allocator_base::last_global_id_ == 43 );
|
||||||
|
|
||||||
|
pv.reset( new X, boost::checked_deleter<X>(), std::allocator<void>() );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
pv.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
27
test/shared_ptr_compare_fail.cpp
Normal file
27
test/shared_ptr_compare_fail.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||||
|
#pragma warning(disable: 4710) // function not inlined
|
||||||
|
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||||
|
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// shared_ptr_compare_fail.cpp - a negative test for "p > q"
|
||||||
|
//
|
||||||
|
// Copyright 2006 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int> p, q;
|
||||||
|
p > q; // must fail
|
||||||
|
return 0;
|
||||||
|
}
|
95
test/shared_ptr_move_test.cpp
Normal file
95
test/shared_ptr_move_test.cpp
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// shared_ptr_move_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
static long instances;
|
||||||
|
|
||||||
|
X()
|
||||||
|
{
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~X()
|
||||||
|
{
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
X( X const & );
|
||||||
|
X & operator=( X const & );
|
||||||
|
};
|
||||||
|
|
||||||
|
long X::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> p( new X );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
boost::shared_ptr<X> p2( static_cast< boost::shared_ptr<X> && >( p ) );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
BOOST_TEST( p.get() == 0 );
|
||||||
|
|
||||||
|
boost::shared_ptr<void> p3( static_cast< boost::shared_ptr<X> && >( p2 ) );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
|
||||||
|
p3.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> p( new X );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
boost::shared_ptr<X> p2;
|
||||||
|
p2 = static_cast< boost::shared_ptr<X> && >( p );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
BOOST_TEST( p.get() == 0 );
|
||||||
|
|
||||||
|
boost::shared_ptr<void> p3;
|
||||||
|
p3 = static_cast< boost::shared_ptr<X> && >( p2 );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
|
||||||
|
p3.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> p( new X );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
boost::shared_ptr<X> p2( new X );
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
p2 = static_cast< boost::shared_ptr<X> && >( p );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
BOOST_TEST( p.get() == 0 );
|
||||||
|
|
||||||
|
boost::shared_ptr<void> p3( new X );
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
p3 = static_cast< boost::shared_ptr<X> && >( p2 );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
BOOST_TEST( p2.get() == 0 );
|
||||||
|
|
||||||
|
p3.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
31
test/shared_ptr_pv_fail.cpp
Normal file
31
test/shared_ptr_pv_fail.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||||
|
#pragma warning(disable: 4710) // function not inlined
|
||||||
|
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||||
|
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// shared_ptr_pv_fail.cpp - a negative test for converting a shared_ptr to void*
|
||||||
|
//
|
||||||
|
// Copyright 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
void f( void* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int> p;
|
||||||
|
f( p ); // must fail
|
||||||
|
return 0;
|
||||||
|
}
|
110
test/shared_ptr_rv_test.cpp
Normal file
110
test/shared_ptr_rv_test.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// shared_ptr_rv_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
static long instances;
|
||||||
|
|
||||||
|
X()
|
||||||
|
{
|
||||||
|
++instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
~X()
|
||||||
|
{
|
||||||
|
--instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boost::shared_ptr<X> create()
|
||||||
|
{
|
||||||
|
return boost::shared_ptr<X>( new X );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
X( X const & );
|
||||||
|
X & operator=( X const & );
|
||||||
|
};
|
||||||
|
|
||||||
|
long X::instances = 0;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X const> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<void> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<void const> p( X::create() );
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
|
||||||
|
p.reset();
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
p = X::create();
|
||||||
|
BOOST_TEST( X::instances == 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
@@ -40,9 +40,9 @@
|
|||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
class Incomplete;
|
class Incomplete;
|
||||||
|
|
||||||
@@ -51,12 +51,6 @@ Incomplete * get_ptr( boost::shared_ptr<Incomplete>& incomplete )
|
|||||||
return incomplete.get();
|
return incomplete.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using boost::scoped_ptr;
|
|
||||||
using boost::scoped_array;
|
|
||||||
using boost::shared_ptr;
|
|
||||||
using boost::shared_array;
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void ck( const T* v1, T v2 ) { BOOST_TEST( *v1 == v2 ); }
|
void ck( const T* v1, T v2 ) { BOOST_TEST( *v1 == v2 ); }
|
||||||
|
|
||||||
@@ -72,7 +66,7 @@ class UDT {
|
|||||||
explicit UDT( long value=0 ) : value_(value) { ++UDT_use_count; }
|
explicit UDT( long value=0 ) : value_(value) { ++UDT_use_count; }
|
||||||
~UDT() {
|
~UDT() {
|
||||||
--UDT_use_count;
|
--UDT_use_count;
|
||||||
cout << "UDT with value " << value_ << " being destroyed\n";
|
std::cout << "UDT with value " << value_ << " being destroyed\n";
|
||||||
}
|
}
|
||||||
long value() const { return value_; }
|
long value() const { return value_; }
|
||||||
void value( long v ) { value_ = v;; }
|
void value( long v ) { value_ = v;; }
|
||||||
@@ -86,16 +80,16 @@ class UDT {
|
|||||||
|
|
||||||
class Incomplete;
|
class Incomplete;
|
||||||
|
|
||||||
Incomplete * check_incomplete( scoped_ptr<Incomplete>& incomplete )
|
Incomplete * check_incomplete( boost::scoped_ptr<Incomplete>& incomplete )
|
||||||
{
|
{
|
||||||
return incomplete.get();
|
return incomplete.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Incomplete * check_incomplete( shared_ptr<Incomplete>& incomplete,
|
Incomplete * check_incomplete( boost::shared_ptr<Incomplete>& incomplete,
|
||||||
shared_ptr<Incomplete>& i2 )
|
boost::shared_ptr<Incomplete>& i2 )
|
||||||
{
|
{
|
||||||
incomplete.swap(i2);
|
incomplete.swap(i2);
|
||||||
cout << incomplete.use_count() << ' ' << incomplete.unique() << '\n';
|
std::cout << incomplete.use_count() << ' ' << incomplete.unique() << '\n';
|
||||||
return incomplete.get();
|
return incomplete.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +101,7 @@ void test()
|
|||||||
|
|
||||||
// test scoped_ptr with a built-in type
|
// test scoped_ptr with a built-in type
|
||||||
long * lp = new long;
|
long * lp = new long;
|
||||||
scoped_ptr<long> sp ( lp );
|
boost::scoped_ptr<long> sp ( lp );
|
||||||
BOOST_TEST( sp.get() == lp );
|
BOOST_TEST( sp.get() == lp );
|
||||||
BOOST_TEST( lp == sp.get() );
|
BOOST_TEST( lp == sp.get() );
|
||||||
BOOST_TEST( &*sp == lp );
|
BOOST_TEST( &*sp == lp );
|
||||||
@@ -122,7 +116,7 @@ void test()
|
|||||||
BOOST_TEST( sp.get() == 0 );
|
BOOST_TEST( sp.get() == 0 );
|
||||||
|
|
||||||
// test scoped_ptr with a user defined type
|
// test scoped_ptr with a user defined type
|
||||||
scoped_ptr<UDT> udt_sp ( new UDT( 999888777 ) );
|
boost::scoped_ptr<UDT> udt_sp ( new UDT( 999888777 ) );
|
||||||
BOOST_TEST( udt_sp->value() == 999888777 );
|
BOOST_TEST( udt_sp->value() == 999888777 );
|
||||||
udt_sp.reset();
|
udt_sp.reset();
|
||||||
udt_sp.reset( new UDT( 111222333 ) );
|
udt_sp.reset( new UDT( 111222333 ) );
|
||||||
@@ -132,7 +126,7 @@ void test()
|
|||||||
|
|
||||||
// test scoped_array with a build-in type
|
// test scoped_array with a build-in type
|
||||||
char * sap = new char [ 100 ];
|
char * sap = new char [ 100 ];
|
||||||
scoped_array<char> sa ( sap );
|
boost::scoped_array<char> sa ( sap );
|
||||||
BOOST_TEST( sa.get() == sap );
|
BOOST_TEST( sa.get() == sap );
|
||||||
BOOST_TEST( sap == sa.get() );
|
BOOST_TEST( sap == sa.get() );
|
||||||
|
|
||||||
@@ -152,7 +146,7 @@ void test()
|
|||||||
|
|
||||||
// test shared_ptr with a built-in type
|
// test shared_ptr with a built-in type
|
||||||
int * ip = new int;
|
int * ip = new int;
|
||||||
shared_ptr<int> cp ( ip );
|
boost::shared_ptr<int> cp ( ip );
|
||||||
BOOST_TEST( ip == cp.get() );
|
BOOST_TEST( ip == cp.get() );
|
||||||
BOOST_TEST( cp.use_count() == 1 );
|
BOOST_TEST( cp.use_count() == 1 );
|
||||||
|
|
||||||
@@ -162,7 +156,7 @@ void test()
|
|||||||
ck( static_cast<int*>(cp.get()), 54321 );
|
ck( static_cast<int*>(cp.get()), 54321 );
|
||||||
ck( static_cast<int*>(ip), *cp );
|
ck( static_cast<int*>(ip), *cp );
|
||||||
|
|
||||||
shared_ptr<int> cp2 ( cp );
|
boost::shared_ptr<int> cp2 ( cp );
|
||||||
BOOST_TEST( ip == cp2.get() );
|
BOOST_TEST( ip == cp2.get() );
|
||||||
BOOST_TEST( cp.use_count() == 2 );
|
BOOST_TEST( cp.use_count() == 2 );
|
||||||
BOOST_TEST( cp2.use_count() == 2 );
|
BOOST_TEST( cp2.use_count() == 2 );
|
||||||
@@ -172,7 +166,7 @@ void test()
|
|||||||
ck( static_cast<int*>(cp2.get()), 54321 );
|
ck( static_cast<int*>(cp2.get()), 54321 );
|
||||||
ck( static_cast<int*>(ip), *cp2 );
|
ck( static_cast<int*>(ip), *cp2 );
|
||||||
|
|
||||||
shared_ptr<int> cp3 ( cp );
|
boost::shared_ptr<int> cp3 ( cp );
|
||||||
BOOST_TEST( cp.use_count() == 3 );
|
BOOST_TEST( cp.use_count() == 3 );
|
||||||
BOOST_TEST( cp2.use_count() == 3 );
|
BOOST_TEST( cp2.use_count() == 3 );
|
||||||
BOOST_TEST( cp3.use_count() == 3 );
|
BOOST_TEST( cp3.use_count() == 3 );
|
||||||
@@ -202,20 +196,20 @@ void test()
|
|||||||
BOOST_TEST( cp.use_count() == 3 );
|
BOOST_TEST( cp.use_count() == 3 );
|
||||||
BOOST_TEST( *cp == 87654 );
|
BOOST_TEST( *cp == 87654 );
|
||||||
|
|
||||||
shared_ptr<int> cp4;
|
boost::shared_ptr<int> cp4;
|
||||||
swap( cp2, cp4 );
|
swap( cp2, cp4 );
|
||||||
BOOST_TEST( cp4.use_count() == 3 );
|
BOOST_TEST( cp4.use_count() == 3 );
|
||||||
BOOST_TEST( *cp4 == 87654 );
|
BOOST_TEST( *cp4 == 87654 );
|
||||||
BOOST_TEST( cp2.get() == 0 );
|
BOOST_TEST( cp2.get() == 0 );
|
||||||
|
|
||||||
set< shared_ptr<int> > scp;
|
std::set< boost::shared_ptr<int> > scp;
|
||||||
scp.insert(cp4);
|
scp.insert(cp4);
|
||||||
BOOST_TEST( scp.find(cp4) != scp.end() );
|
BOOST_TEST( scp.find(cp4) != scp.end() );
|
||||||
BOOST_TEST( scp.find(cp4) == scp.find( shared_ptr<int>(cp4) ) );
|
BOOST_TEST( scp.find(cp4) == scp.find( boost::shared_ptr<int>(cp4) ) );
|
||||||
|
|
||||||
// test shared_array with a built-in type
|
// test shared_array with a built-in type
|
||||||
char * cap = new char [ 100 ];
|
char * cap = new char [ 100 ];
|
||||||
shared_array<char> ca ( cap );
|
boost::shared_array<char> ca ( cap );
|
||||||
BOOST_TEST( ca.get() == cap );
|
BOOST_TEST( ca.get() == cap );
|
||||||
BOOST_TEST( cap == ca.get() );
|
BOOST_TEST( cap == ca.get() );
|
||||||
BOOST_TEST( &ca[0] == cap );
|
BOOST_TEST( &ca[0] == cap );
|
||||||
@@ -227,8 +221,8 @@ void test()
|
|||||||
BOOST_TEST( ca[0] == 'H' );
|
BOOST_TEST( ca[0] == 'H' );
|
||||||
BOOST_TEST( ca[30] == 'h' );
|
BOOST_TEST( ca[30] == 'h' );
|
||||||
|
|
||||||
shared_array<char> ca2 ( ca );
|
boost::shared_array<char> ca2 ( ca );
|
||||||
shared_array<char> ca3 ( ca2 );
|
boost::shared_array<char> ca3 ( ca2 );
|
||||||
|
|
||||||
ca[0] = 'N';
|
ca[0] = 'N';
|
||||||
ca[4] = 'd';
|
ca[4] = 'd';
|
||||||
@@ -246,24 +240,24 @@ void test()
|
|||||||
ca.reset();
|
ca.reset();
|
||||||
BOOST_TEST( ca.get() == 0 );
|
BOOST_TEST( ca.get() == 0 );
|
||||||
|
|
||||||
shared_array<char> ca4;
|
boost::shared_array<char> ca4;
|
||||||
swap( ca3, ca4 );
|
swap( ca3, ca4 );
|
||||||
BOOST_TEST( ca4.use_count() == 1 );
|
BOOST_TEST( ca4.use_count() == 1 );
|
||||||
BOOST_TEST( strcmp( ca4.get(), "Not dog with mustard and relish" ) == 0 );
|
BOOST_TEST( strcmp( ca4.get(), "Not dog with mustard and relish" ) == 0 );
|
||||||
BOOST_TEST( ca3.get() == 0 );
|
BOOST_TEST( ca3.get() == 0 );
|
||||||
|
|
||||||
set< shared_array<char> > sca;
|
std::set< boost::shared_array<char> > sca;
|
||||||
sca.insert(ca4);
|
sca.insert(ca4);
|
||||||
BOOST_TEST( sca.find(ca4) != sca.end() );
|
BOOST_TEST( sca.find(ca4) != sca.end() );
|
||||||
BOOST_TEST( sca.find(ca4) == sca.find( shared_array<char>(ca4) ) );
|
BOOST_TEST( sca.find(ca4) == sca.find( boost::shared_array<char>(ca4) ) );
|
||||||
|
|
||||||
// test shared_array with user defined type
|
// test shared_array with user defined type
|
||||||
shared_array<UDT> udta ( new UDT[3] );
|
boost::shared_array<UDT> udta ( new UDT[3] );
|
||||||
|
|
||||||
udta[0].value( 111 );
|
udta[0].value( 111 );
|
||||||
udta[1].value( 222 );
|
udta[1].value( 222 );
|
||||||
udta[2].value( 333 );
|
udta[2].value( 333 );
|
||||||
shared_array<UDT> udta2 ( udta );
|
boost::shared_array<UDT> udta2 ( udta );
|
||||||
|
|
||||||
BOOST_TEST( udta[0].value() == 111 );
|
BOOST_TEST( udta[0].value() == 111 );
|
||||||
BOOST_TEST( udta[1].value() == 222 );
|
BOOST_TEST( udta[1].value() == 222 );
|
||||||
@@ -280,7 +274,7 @@ void test()
|
|||||||
|
|
||||||
// test shared_ptr with a user defined type
|
// test shared_ptr with a user defined type
|
||||||
UDT * up = new UDT;
|
UDT * up = new UDT;
|
||||||
shared_ptr<UDT> sup ( up );
|
boost::shared_ptr<UDT> sup ( up );
|
||||||
BOOST_TEST( up == sup.get() );
|
BOOST_TEST( up == sup.get() );
|
||||||
BOOST_TEST( sup.use_count() == 1 );
|
BOOST_TEST( sup.use_count() == 1 );
|
||||||
|
|
||||||
@@ -288,7 +282,7 @@ void test()
|
|||||||
BOOST_TEST( sup->value() == 54321 );
|
BOOST_TEST( sup->value() == 54321 );
|
||||||
BOOST_TEST( up->value() == 54321 );
|
BOOST_TEST( up->value() == 54321 );
|
||||||
|
|
||||||
shared_ptr<UDT> sup2;
|
boost::shared_ptr<UDT> sup2;
|
||||||
sup2 = sup;
|
sup2 = sup;
|
||||||
BOOST_TEST( sup2->value() == 54321 );
|
BOOST_TEST( sup2->value() == 54321 );
|
||||||
BOOST_TEST( sup.use_count() == 2 );
|
BOOST_TEST( sup.use_count() == 2 );
|
||||||
@@ -298,7 +292,7 @@ void test()
|
|||||||
BOOST_TEST( sup.use_count() == 2 );
|
BOOST_TEST( sup.use_count() == 2 );
|
||||||
BOOST_TEST( sup2.use_count() == 2 );
|
BOOST_TEST( sup2.use_count() == 2 );
|
||||||
|
|
||||||
cout << "OK\n";
|
std::cout << "OK\n";
|
||||||
|
|
||||||
new char[12345]; // deliberate memory leak to verify leaks detected
|
new char[12345]; // deliberate memory leak to verify leaks detected
|
||||||
}
|
}
|
||||||
|
62
test/sp_unary_addr_test.cpp
Normal file
62
test/sp_unary_addr_test.cpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// sp_unary_addr_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct deleter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
void operator& ();
|
||||||
|
void operator& () const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
int data;
|
||||||
|
|
||||||
|
deleter(): data( 17041 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()( void * )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
X x;
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> p( &x, deleter() );
|
||||||
|
|
||||||
|
deleter * q = boost::get_deleter<deleter>( p );
|
||||||
|
|
||||||
|
BOOST_TEST( q != 0 );
|
||||||
|
BOOST_TEST( q != 0 && q->data == 17041 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> p( &x, deleter(), std::allocator<X>() );
|
||||||
|
|
||||||
|
deleter * q = boost::get_deleter<deleter>( p );
|
||||||
|
|
||||||
|
BOOST_TEST( q != 0 );
|
||||||
|
BOOST_TEST( q != 0 && q->data == 17041 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
12
weak_ptr.htm
12
weak_ptr.htm
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
</head>
|
||||||
<body text="#000000" bgColor="#ffffff">
|
<body text="#000000" bgColor="#ffffff">
|
||||||
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle">weak_ptr
|
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||||
class template</h1>
|
border="0"></A>weak_ptr class template</h1>
|
||||||
<p><A href="#Introduction">Introduction</A><br>
|
<p><A href="#Introduction">Introduction</A><br>
|
||||||
<A href="#Synopsis">Synopsis</A><br>
|
<A href="#Synopsis">Synopsis</A><br>
|
||||||
<A href="#Members">Members</A><br>
|
<A href="#Members">Members</A><br>
|
||||||
@@ -235,10 +235,8 @@ public:
|
|||||||
<hr>
|
<hr>
|
||||||
<p>$Date$</p>
|
<p>$Date$</p>
|
||||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||||
Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and
|
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||||
distribute this document is granted provided this copyright notice appears in
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
all copies. This document is provided "as is" without express or implied
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
|
||||||
</A>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Reference in New Issue
Block a user