forked from boostorg/smart_ptr
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			boost-1.36
			...
			boost-1.31
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					552eed7027 | ||
| 
						 | 
					cf612d7b95 | 
@@ -1,88 +1,105 @@
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
 | 
			
		||||
<html>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>Smart Pointer Changes</title>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</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"
 | 
			
		||||
					border="0"></A>Smart Pointer Changes</h1>
 | 
			
		||||
		<p>The February 2002 change to the Boost smart pointers introduced a number of 
 | 
			
		||||
			changes. Since the previous version of the smart pointers was in use for a long 
 | 
			
		||||
			time, it's useful to have a detailed list of what changed from a library user's 
 | 
			
		||||
			point of view.</p>
 | 
			
		||||
		<p>Note that for compilers that don't support member templates well enough, a 
 | 
			
		||||
			separate implementation is used that lacks many of the new features and is more 
 | 
			
		||||
			like the old version.</p>
 | 
			
		||||
		<h2>Features Requiring Code Changes to Take Advantage</h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				The smart pointer class templates now each have their own header file. For 
 | 
			
		||||
				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 
 | 
			
		||||
			templates.
 | 
			
		||||
			<li>
 | 
			
		||||
				The <b>weak_ptr</b>
 | 
			
		||||
			template was added.
 | 
			
		||||
			<li>
 | 
			
		||||
				The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that 
 | 
			
		||||
				the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
 | 
			
		||||
			destructor. This makes it easier to have shared_ptr members in classes without 
 | 
			
		||||
			explicit destructors.
 | 
			
		||||
			<li>
 | 
			
		||||
				A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
 | 
			
		||||
			<li>
 | 
			
		||||
				<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are 
 | 
			
		||||
				provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
 | 
			
		||||
				and <b>dynamic_cast</b>
 | 
			
		||||
			do for pointers.
 | 
			
		||||
			<li>
 | 
			
		||||
				The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>, 
 | 
			
		||||
				although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>. 
 | 
			
		||||
				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 
 | 
			
		||||
			assertions are off).
 | 
			
		||||
			<li>
 | 
			
		||||
				The <b>BOOST_SMART_PTR_CONVERSION</b>
 | 
			
		||||
			feature has been removed.
 | 
			
		||||
			<li>
 | 
			
		||||
				<b>shared_ptr<void></b> is now allowed.</li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<h2>Features That Improve Robustness</h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				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">
 | 
			
		||||
					<boost/detail/atomic_count.hpp></a>
 | 
			
		||||
			file for details
 | 
			
		||||
			<li>
 | 
			
		||||
				The new shared_ptr will always delete the object using the pointer it was 
 | 
			
		||||
				originally constructed with. This prevents subtle problems that could happen if 
 | 
			
		||||
				the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did 
 | 
			
		||||
				not have a virtual destructor.</li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<h2>Implementation Details</h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				Some bugs in the assignment operator implementations and in <b>reset</b>
 | 
			
		||||
			have been fixed by using the "copy and swap" idiom.
 | 
			
		||||
			<li>
 | 
			
		||||
				Assertions have been added to check preconditions of various functions; 
 | 
			
		||||
				however, since these use the new <a href="../../boost/assert.hpp"><boost/assert.hpp></a>
 | 
			
		||||
			header, the assertions are disabled by default.
 | 
			
		||||
			<li>
 | 
			
		||||
				The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
 | 
			
		||||
			overloads which accomplish the same thing without relying on undefined 
 | 
			
		||||
			behavior.
 | 
			
		||||
			<li>
 | 
			
		||||
				The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, 
 | 
			
		||||
				which has many of the same advantages for generic programming but does not 
 | 
			
		||||
				violate the C++ standard.</li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>Revised 1 February 2002</p>
 | 
			
		||||
		<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 
 | 
			
		||||
				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
	</body>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
<title>Smart Pointer Changes</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
 | 
			
		||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Smart
 | 
			
		||||
Pointer Changes</h1>
 | 
			
		||||
 | 
			
		||||
<p>The February 2002 change to the Boost smart pointers introduced a number
 | 
			
		||||
of changes. Since the previous version of the smart pointers was in use for
 | 
			
		||||
a long time, it's useful to have a detailed list of what changed from a library
 | 
			
		||||
user's point of view.</p>
 | 
			
		||||
 | 
			
		||||
<p>Note that for compilers that don't support member templates well enough,
 | 
			
		||||
a separate implementation is used that lacks many of the new features and is
 | 
			
		||||
more like the old version.</p>
 | 
			
		||||
 | 
			
		||||
<h2>Features Requiring Code Changes to Take Advantage</h2>
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
 | 
			
		||||
<li>The smart pointer class templates now each have their own header file.
 | 
			
		||||
For 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 templates.</li>
 | 
			
		||||
 | 
			
		||||
<li>The <b>weak_ptr</b> template was added.</li>
 | 
			
		||||
 | 
			
		||||
<li>The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that the pointed-to object's
 | 
			
		||||
destructor must be visible when instantiating the <b>shared_ptr</b> destructor.
 | 
			
		||||
This makes it easier to have shared_ptr members in classes without explicit destructors.</li>
 | 
			
		||||
 | 
			
		||||
<li>A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.</li>
 | 
			
		||||
 | 
			
		||||
<li><b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
 | 
			
		||||
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b> and
 | 
			
		||||
<b>dynamic_cast</b> do for pointers.</li>
 | 
			
		||||
 | 
			
		||||
<li>The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
 | 
			
		||||
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
 | 
			
		||||
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 assertions are off).</li>
 | 
			
		||||
 | 
			
		||||
<li>The <b>BOOST_SMART_PTR_CONVERSION</b> feature has been removed.</li>
 | 
			
		||||
 | 
			
		||||
<li><b>shared_ptr<void></b> is now allowed.</li>
 | 
			
		||||
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<h2>Features That Improve Robustness</h2>
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
 | 
			
		||||
<li>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"><boost/detail/atomic_count.hpp></a>
 | 
			
		||||
file for details</li>
 | 
			
		||||
 | 
			
		||||
<li>The new shared_ptr will always delete the object using the pointer it was originally constructed with.
 | 
			
		||||
This prevents subtle problems that could happen if the last <b>shared_ptr</b> was a pointer to a sub-object
 | 
			
		||||
of a class that did not have a virtual destructor.</li>
 | 
			
		||||
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<h2>Implementation Details</h2>
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
 | 
			
		||||
<li>Some bugs in the assignment operator implementations and in <b>reset</b>
 | 
			
		||||
have been fixed by using the "copy and swap" idiom.</li>
 | 
			
		||||
 | 
			
		||||
<li>Assertions have been added to check preconditions of various functions;
 | 
			
		||||
however, since these use the new
 | 
			
		||||
<a href="../../boost/assert.hpp"><boost/assert.hpp></a>
 | 
			
		||||
header, the assertions are disabled by default.</li>
 | 
			
		||||
 | 
			
		||||
<li>The partial specialization of <b>std::less</b> has been replaced by <b>operator<</b>
 | 
			
		||||
overloads which accomplish the same thing without relying on undefined behavior.</li>
 | 
			
		||||
 | 
			
		||||
<li>The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, which
 | 
			
		||||
has many of the same advantages for generic programming but does not violate the C++ standard.</li>
 | 
			
		||||
 | 
			
		||||
</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>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,10 @@
 | 
			
		||||
	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
 | 
			
		||||
		<table border="0" width="100%">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
 | 
			
		||||
				<td width="277">
 | 
			
		||||
					<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
 | 
			
		||||
				</td>
 | 
			
		||||
				<td align="center">
 | 
			
		||||
				<td align="middle">
 | 
			
		||||
					<h1>enable_shared_from_this.hpp</h1>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
@@ -84,8 +85,9 @@ public:
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<p>
 | 
			
		||||
			<br>
 | 
			
		||||
			<small>Copyright <20> 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version 
 | 
			
		||||
				1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 
 | 
			
		||||
				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
			<small>Copyright <20> 2002, 2003 by Peter Dimov. 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.</small></p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
// Boost scoped_ptr_example implementation file  -----------------------------//
 | 
			
		||||
 | 
			
		||||
//  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)
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.
 | 
			
		||||
//  See accompanying license for terms and conditions of use.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
//  Boost scoped_ptr_example header file  ------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  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)
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.
 | 
			
		||||
//  See accompanying license for terms and conditions of use.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
// Boost scoped_ptr_example_test main program  -------------------------------//
 | 
			
		||||
 | 
			
		||||
//  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)
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.
 | 
			
		||||
//  See accompanying license for terms and conditions of use.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
//  Boost shared_ptr_example.cpp  --------------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  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)
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.
 | 
			
		||||
//  See accompanying license for terms and conditions of use.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
// Boost shared_ptr_example2 implementation file  -----------------------------//
 | 
			
		||||
 | 
			
		||||
//  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)
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.
 | 
			
		||||
//  See accompanying license for terms and conditions of use.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
//  Boost shared_ptr_example2 header file  -----------------------------------//
 | 
			
		||||
 | 
			
		||||
//  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)
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.
 | 
			
		||||
//  See accompanying license for terms and conditions of use.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
// Boost shared_ptr_example2_test main program  ------------------------------//
 | 
			
		||||
 | 
			
		||||
//  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)
 | 
			
		||||
 | 
			
		||||
//  Copyright Beman Dawes 2001.
 | 
			
		||||
//  See accompanying license for terms and conditions of use.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr for documentation.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,9 +12,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  typedef <implementation-defined> boost::detail::atomic_count;
 | 
			
		||||
//
 | 
			
		||||
@@ -73,6 +74,9 @@
 | 
			
		||||
//      are called driven by smart_ptr interface...
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//  Note: atomic_count_linux.hpp has been disabled by default; see the
 | 
			
		||||
//        comments inside for more info.
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_HAS_THREADS
 | 
			
		||||
@@ -89,31 +93,17 @@ typedef long atomic_count;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined(BOOST_USE_ASM_ATOMIC_H)
 | 
			
		||||
#  include <boost/detail/atomic_count_linux.hpp>
 | 
			
		||||
#elif defined(BOOST_AC_USE_PTHREADS)
 | 
			
		||||
 | 
			
		||||
#  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__)
 | 
			
		||||
 | 
			
		||||
#  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__)
 | 
			
		||||
#  include <boost/detail/atomic_count_gcc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
 | 
			
		||||
#  define BOOST_AC_USE_PTHREADS
 | 
			
		||||
#  include <boost/detail/atomic_count_pthreads.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,11 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2002 Lars Gullik Bj<42>nnes <larsbj@lyx.org>
 | 
			
		||||
//  Copyright 2003-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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <bits/atomicity.h>
 | 
			
		||||
@@ -25,13 +25,6 @@ namespace boost
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if defined(__GLIBCXX__) // g++ 3.4+
 | 
			
		||||
 | 
			
		||||
using __gnu_cxx::__atomic_add;
 | 
			
		||||
using __gnu_cxx::__exchange_and_add;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
@@ -45,7 +38,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return __exchange_and_add(&value_, -1) - 1;
 | 
			
		||||
        return !__exchange_and_add(&value_, -1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
@@ -58,7 +51,7 @@ private:
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    mutable _Atomic_word value_;
 | 
			
		||||
    _Atomic_word value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 
 | 
			
		||||
@@ -1,84 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										70
									
								
								include/boost/detail/atomic_count_linux.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								include/boost/detail/atomic_count_linux.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_linux.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  This implementation uses <asm/atomic.h>. This is a kernel header;
 | 
			
		||||
//  using kernel headers in a user program may cause a number of problems,
 | 
			
		||||
//  and not all flavors of Linux provide the atomic instructions.
 | 
			
		||||
//
 | 
			
		||||
//  This file is only provided because the performance of this implementation
 | 
			
		||||
//  is significantly higher than the pthreads version. Use at your own risk
 | 
			
		||||
//  (by defining BOOST_USE_ASM_ATOMIC_H.)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <asm/atomic.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count(long v)
 | 
			
		||||
    {
 | 
			
		||||
        atomic_t init = ATOMIC_INIT(v);
 | 
			
		||||
        value_ = init;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator++()
 | 
			
		||||
    {
 | 
			
		||||
        atomic_inc(&value_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return !atomic_dec_and_test(&value_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return atomic_read(&value_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    atomic_t value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_LINUX_HPP_INCLUDED
 | 
			
		||||
@@ -6,9 +6,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -10,14 +10,17 @@
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_win32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001-2005 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/interlocked.hpp>
 | 
			
		||||
#ifdef BOOST_USE_WINDOWS_H
 | 
			
		||||
#  include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -25,35 +28,67 @@ namespace boost
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN64
 | 
			
		||||
 | 
			
		||||
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
 | 
			
		||||
 | 
			
		||||
extern "C" long_type __cdecl _InterlockedIncrement(long volatile *);
 | 
			
		||||
extern "C" long_type __cdecl _InterlockedDecrement(long volatile *);
 | 
			
		||||
 | 
			
		||||
#pragma intrinsic(_InterlockedIncrement)
 | 
			
		||||
#pragma intrinsic(_InterlockedDecrement)
 | 
			
		||||
 | 
			
		||||
inline long InterlockedIncrement(long volatile * lp)
 | 
			
		||||
{ 
 | 
			
		||||
    return _InterlockedIncrement(lp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline long InterlockedDecrement(long volatile* lp)
 | 
			
		||||
{ 
 | 
			
		||||
    return _InterlockedDecrement(lp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else  // _WIN64
 | 
			
		||||
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *);
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *);
 | 
			
		||||
 | 
			
		||||
#endif // _WIN64
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ): value_( v )
 | 
			
		||||
    explicit atomic_count(long v): value_(v)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_INTERLOCKED_INCREMENT( &value_ );
 | 
			
		||||
        // Some older <windows.h> versions do not accept volatile
 | 
			
		||||
        return InterlockedIncrement(const_cast<long*>(&value_));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_INTERLOCKED_DECREMENT( &value_ );
 | 
			
		||||
        return InterlockedDecrement(const_cast<long*>(&value_));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<long const volatile &>( value_ );
 | 
			
		||||
        return value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_count( atomic_count const & );
 | 
			
		||||
    atomic_count & operator=( atomic_count const & );
 | 
			
		||||
    atomic_count(atomic_count const &);
 | 
			
		||||
    atomic_count & operator=(atomic_count const &);
 | 
			
		||||
 | 
			
		||||
    long value_;
 | 
			
		||||
    volatile long value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
#ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/bad_weak_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// 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 <exception>
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn -8026     // Functions with excep. spec. are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// The standard library that comes with Borland C++ 5.5.1, 5.6.4
 | 
			
		||||
// defines std::exception and its members as having C calling
 | 
			
		||||
// convention (-pc). When the definition of bad_weak_ptr
 | 
			
		||||
// is compiled with -ps, the compiler issues an error.
 | 
			
		||||
// Hence, the temporary #pragma option -pc below.
 | 
			
		||||
 | 
			
		||||
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
 | 
			
		||||
# pragma option push -pc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class bad_weak_ptr: public std::exception
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual char const * what() const throw()
 | 
			
		||||
    {
 | 
			
		||||
        return "tr1::bad_weak_ptr";
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
 | 
			
		||||
# pragma option pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn .8026     // Functions with excep. spec. are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
@@ -12,28 +12,85 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  typedef <unspecified> boost::detail::lightweight_mutex;
 | 
			
		||||
//
 | 
			
		||||
//  boost::detail::lightweight_mutex is a header-only implementation of
 | 
			
		||||
//  a subset of the Mutex concept requirements:
 | 
			
		||||
//  boost::detail::lightweight_mutex meets a subset of the Mutex concept
 | 
			
		||||
//  requirements: http://www.boost.org/libs/thread/doc/mutex_concept.html#Mutex
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
 | 
			
		||||
//  * Used by the smart pointer library
 | 
			
		||||
//  * Performance oriented
 | 
			
		||||
//  * Header-only implementation
 | 
			
		||||
//  * Small memory footprint
 | 
			
		||||
//  * Not a general purpose mutex, use boost::mutex, CRITICAL_SECTION or
 | 
			
		||||
//    pthread_mutex instead.
 | 
			
		||||
//  * Never spin in a tight lock/do-something/unlock loop, since
 | 
			
		||||
//    lightweight_mutex does not guarantee fairness.
 | 
			
		||||
//  * Never keep a lightweight_mutex locked for long periods.
 | 
			
		||||
//
 | 
			
		||||
//  It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
 | 
			
		||||
//  The current implementation can use a pthread_mutex, a CRITICAL_SECTION,
 | 
			
		||||
//  or a platform-specific spinlock.
 | 
			
		||||
//
 | 
			
		||||
//  You can force a particular implementation by defining BOOST_LWM_USE_PTHREADS,
 | 
			
		||||
//  BOOST_LWM_USE_CRITICAL_SECTION, or BOOST_LWM_USE_SPINLOCK.
 | 
			
		||||
//
 | 
			
		||||
//  If neither macro has been defined, the default is to use a spinlock on Win32,
 | 
			
		||||
//  and a pthread_mutex otherwise.
 | 
			
		||||
//
 | 
			
		||||
//  Note that a spinlock is not a general synchronization primitive. In particular,
 | 
			
		||||
//  it is not guaranteed to be a memory barrier, and it is possible to "livelock"
 | 
			
		||||
//  if a lower-priority thread has acquired the spinlock but a higher-priority
 | 
			
		||||
//  thread is spinning trying to acquire the same lock.
 | 
			
		||||
//
 | 
			
		||||
//  For these reasons, spinlocks have been disabled by default except on Windows,
 | 
			
		||||
//  where a spinlock can be several orders of magnitude faster than a CRITICAL_SECTION.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  Note: lwm_linux.hpp has been disabled by default; see the comments
 | 
			
		||||
//        inside for more info.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
//  Note to implementors: if you write a platform-specific spinlock
 | 
			
		||||
//  for a platform that supports pthreads, be sure to test its performance
 | 
			
		||||
//  against the pthreads-based version using shared_ptr_timing_test.cpp and
 | 
			
		||||
//  shared_ptr_mt_test.cpp. Custom versions are usually not worth the trouble
 | 
			
		||||
//  _unless_ the performance gains are substantial.
 | 
			
		||||
//
 | 
			
		||||
//  Be sure to compare against a "real" pthreads library;
 | 
			
		||||
//  shared_ptr_timing_test.cpp will compile succesfully with a stub do-nothing
 | 
			
		||||
//  pthreads library, since it doesn't create any threads.
 | 
			
		||||
 | 
			
		||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(BOOST_LWM_USE_CRITICAL_SECTION) && !defined(BOOST_LWM_USE_PTHREADS)
 | 
			
		||||
# define BOOST_LWM_WIN32
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_HAS_THREADS)
 | 
			
		||||
# include <boost/detail/lwm_nop.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
#  include <boost/detail/lwm_pthreads.hpp>
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
 | 
			
		||||
#  if defined(BOOST_LWM_WIN32)
 | 
			
		||||
#    include <boost/detail/lwm_win32_nt.hpp>
 | 
			
		||||
#  else
 | 
			
		||||
#    include <boost/detail/lwm_nop.hpp>
 | 
			
		||||
#  endif
 | 
			
		||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(BOOST_USE_ASM_ATOMIC_H)
 | 
			
		||||
#  include <boost/detail/lwm_linux.hpp>
 | 
			
		||||
#elif defined(BOOST_LWM_USE_CRITICAL_SECTION)
 | 
			
		||||
#  include <boost/detail/lwm_win32_cs.hpp>
 | 
			
		||||
#elif defined(BOOST_LWM_USE_PTHREADS)
 | 
			
		||||
#  include <boost/detail/lwm_pthreads.hpp>
 | 
			
		||||
#elif defined(BOOST_LWM_WIN32)
 | 
			
		||||
#  include <boost/detail/lwm_win32.hpp>
 | 
			
		||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__sgi)
 | 
			
		||||
#  include <boost/detail/lwm_irix.hpp>
 | 
			
		||||
#elif defined(BOOST_LWM_USE_SPINLOCK) && defined(__GLIBCPP__)
 | 
			
		||||
#  include <boost/detail/lwm_gcc.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
#  define BOOST_LWM_USE_PTHREADS
 | 
			
		||||
#  include <boost/detail/lwm_pthreads.hpp>
 | 
			
		||||
#else
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
#  error Unrecognized threading platform
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								include/boost/detail/lwm_gcc.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								include/boost/detail/lwm_gcc.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_gcc.hpp
 | 
			
		||||
//
 | 
			
		||||
//  lightweight_mutex for GNU libstdc++ v3
 | 
			
		||||
//
 | 
			
		||||
//  http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2002 Lars Gullik Bj<42>nnes <larsbj@lyx.org>
 | 
			
		||||
//
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <bits/atomicity.h>
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    _Atomic_word a_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(): a_(1)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
    friend class scoped_lock;
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        lightweight_mutex & m_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock(scoped_lock const &);
 | 
			
		||||
        scoped_lock & operator=(scoped_lock const &);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock(lightweight_mutex & m): m_(m)
 | 
			
		||||
        {
 | 
			
		||||
            while( !__exchange_and_add(&m_.a_, -1) )
 | 
			
		||||
            {
 | 
			
		||||
                __atomic_add(&m_.a_, 1);
 | 
			
		||||
                sched_yield();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            __atomic_add(&m_.a_, 1);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_GCC_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										74
									
								
								include/boost/detail/lwm_irix.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								include/boost/detail/lwm_irix.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_irix.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright (c) 2002 Dan Gohman
 | 
			
		||||
//
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <sgidefs.h>
 | 
			
		||||
#include <mutex.h>
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    __uint32_t l_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(): l_(0)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
    friend class scoped_lock;
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        lightweight_mutex & m_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock(scoped_lock const &);
 | 
			
		||||
        scoped_lock & operator=(scoped_lock const &);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock(lightweight_mutex & m): m_(m)
 | 
			
		||||
        {
 | 
			
		||||
            while( test_and_set32(&m_.l_, 1) )
 | 
			
		||||
            {
 | 
			
		||||
                sched_yield();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            m_.l_ = 0;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_IRIX_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										85
									
								
								include/boost/detail/lwm_linux.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								include/boost/detail/lwm_linux.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_linux.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  This implementation uses <asm/atomic.h>. This is a kernel header;
 | 
			
		||||
//  using kernel headers in a user program may cause a number of problems,
 | 
			
		||||
//  and not all flavors of Linux provide the atomic instructions.
 | 
			
		||||
//
 | 
			
		||||
//  This file is only provided because the performance of this implementation
 | 
			
		||||
//  is about 3.5 times higher than the pthreads version. Use at your own risk
 | 
			
		||||
//  (by defining BOOST_USE_ASM_ATOMIC_H.)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <asm/atomic.h>
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    atomic_t a_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex()
 | 
			
		||||
    {
 | 
			
		||||
        atomic_t a = ATOMIC_INIT(1);
 | 
			
		||||
        a_ = a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
    friend class scoped_lock;
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        lightweight_mutex & m_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock(scoped_lock const &);
 | 
			
		||||
        scoped_lock & operator=(scoped_lock const &);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock(lightweight_mutex & m): m_(m)
 | 
			
		||||
        {
 | 
			
		||||
            while( !atomic_dec_and_test(&m_.a_) )
 | 
			
		||||
            {
 | 
			
		||||
                atomic_inc(&m_.a_);
 | 
			
		||||
                sched_yield();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            atomic_inc(&m_.a_);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_LINUX_HPP_INCLUDED
 | 
			
		||||
@@ -12,9 +12,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
 
 | 
			
		||||
@@ -12,9 +12,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
// 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										123
									
								
								include/boost/detail/lwm_win32.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								include/boost/detail/lwm_win32.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_win32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_USE_WINDOWS_H
 | 
			
		||||
#  include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn -8027     // Functions containing while are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN64
 | 
			
		||||
 | 
			
		||||
// Intel 6.0 on Win64 version, posted by Tim Fenders to [boost-users]
 | 
			
		||||
 | 
			
		||||
extern "C" long_type __cdecl _InterlockedExchange(long volatile *, long);
 | 
			
		||||
 | 
			
		||||
#pragma intrinsic(_InterlockedExchange)
 | 
			
		||||
 | 
			
		||||
inline long InterlockedExchange(long volatile* lp, long l)
 | 
			
		||||
{
 | 
			
		||||
    return _InterlockedExchange(lp, l);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else  // _WIN64
 | 
			
		||||
 | 
			
		||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
 | 
			
		||||
 | 
			
		||||
#endif // _WIN64
 | 
			
		||||
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    long l_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(): l_(0)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
    friend class scoped_lock;
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        lightweight_mutex & m_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock(scoped_lock const &);
 | 
			
		||||
        scoped_lock & operator=(scoped_lock const &);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock(lightweight_mutex & m): m_(m)
 | 
			
		||||
        {
 | 
			
		||||
            while( InterlockedExchange(&m_.l_, 1) )
 | 
			
		||||
            {
 | 
			
		||||
                // Note: changed to Sleep(1) from Sleep(0).
 | 
			
		||||
                // According to MSDN, Sleep(0) will never yield
 | 
			
		||||
                // to a lower-priority thread, whereas Sleep(1)
 | 
			
		||||
                // will. Performance seems not to be affected.
 | 
			
		||||
 | 
			
		||||
                Sleep(1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            InterlockedExchange(&m_.l_, 0);
 | 
			
		||||
 | 
			
		||||
            // Note: adding a yield here will make
 | 
			
		||||
            // the spinlock more fair and will increase the overall
 | 
			
		||||
            // performance of some applications substantially in
 | 
			
		||||
            // high contention situations, but will penalize the
 | 
			
		||||
            // low contention / single thread case up to 5x
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn .8027     // Functions containing while are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_HPP_INCLUDED
 | 
			
		||||
@@ -12,9 +12,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_USE_WINDOWS_H
 | 
			
		||||
@@ -29,7 +30,7 @@ namespace detail
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
struct critical_section
 | 
			
		||||
struct CRITICAL_SECTION
 | 
			
		||||
{
 | 
			
		||||
    struct critical_section_debug * DebugInfo;
 | 
			
		||||
    long LockCount;
 | 
			
		||||
@@ -43,14 +44,10 @@ struct critical_section
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
typedef ::CRITICAL_SECTION critical_section;
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
 | 
			
		||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
@@ -58,7 +55,7 @@ class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    critical_section cs_;
 | 
			
		||||
    CRITICAL_SECTION cs_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								include/boost/detail/lwm_win32_nt.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								include/boost/detail/lwm_win32_nt.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lwm_win32_nt.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  "No threads" version of lwm_win32.hpp; binary compatible but no-op.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    long l_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(): l_(0)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
    friend class scoped_lock;
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        scoped_lock(scoped_lock const &);
 | 
			
		||||
        scoped_lock & operator=(scoped_lock const &);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock(lightweight_mutex &)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_NT_HPP_INCLUDED
 | 
			
		||||
@@ -7,9 +7,10 @@
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
@@ -11,37 +11,294 @@
 | 
			
		||||
//  detail/shared_count.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn -8027     // Functions containing try are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/throw_exception.hpp>
 | 
			
		||||
#include <boost/detail/bad_weak_ptr.hpp>
 | 
			
		||||
#include <boost/detail/sp_counted_base.hpp>
 | 
			
		||||
#include <boost/detail/sp_counted_impl.hpp>
 | 
			
		||||
// In order to avoid circular dependencies with Boost.TR1
 | 
			
		||||
// we make sure that our include of <memory> doesn't try to
 | 
			
		||||
// pull in the TR1 headers: that's why we use this header 
 | 
			
		||||
// rather than including <memory> directly:
 | 
			
		||||
#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
 | 
			
		||||
#include <boost/detail/lightweight_mutex.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
#include <boost/detail/quick_allocator.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <memory>           // std::auto_ptr, std::allocator
 | 
			
		||||
#include <functional>       // std::less
 | 
			
		||||
#include <exception>        // std::exception
 | 
			
		||||
#include <new>              // std::bad_alloc
 | 
			
		||||
#include <typeinfo>         // std::type_info in get_deleter
 | 
			
		||||
#include <cstddef>          // std::size_t
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn -8026     // Functions with excep. spec. are not expanded inline
 | 
			
		||||
# pragma warn -8027     // Functions containing try are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Debug hooks
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn);
 | 
			
		||||
void sp_array_constructor_hook(void * px);
 | 
			
		||||
void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn);
 | 
			
		||||
void sp_array_destructor_hook(void * px);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// The standard library that comes with Borland C++ 5.5.1
 | 
			
		||||
// defines std::exception and its members as having C calling
 | 
			
		||||
// convention (-pc). When the definition of bad_weak_ptr
 | 
			
		||||
// is compiled with -ps, the compiler issues an error.
 | 
			
		||||
// Hence, the temporary #pragma option -pc below. The version
 | 
			
		||||
// check is deliberately conservative.
 | 
			
		||||
 | 
			
		||||
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
 | 
			
		||||
# pragma option push -pc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class bad_weak_ptr: public std::exception
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    virtual char const * what() const throw()
 | 
			
		||||
    {
 | 
			
		||||
        return "boost::bad_weak_ptr";
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
 | 
			
		||||
# pragma option pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    typedef detail::lightweight_mutex mutex_type;
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    // destruct() is called when weak_count_ drops to zero.
 | 
			
		||||
 | 
			
		||||
    virtual void destruct() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter(std::type_info const & ti) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_HAS_THREADS)
 | 
			
		||||
        mutex_type::scoped_lock lock(mtx_);
 | 
			
		||||
#endif
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void add_ref_lock()
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_HAS_THREADS)
 | 
			
		||||
        mutex_type::scoped_lock lock(mtx_);
 | 
			
		||||
#endif
 | 
			
		||||
        if(use_count_ == 0) boost::throw_exception(boost::bad_weak_ptr());
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
#if defined(BOOST_HAS_THREADS)
 | 
			
		||||
            mutex_type::scoped_lock lock(mtx_);
 | 
			
		||||
#endif
 | 
			
		||||
            long new_use_count = --use_count_;
 | 
			
		||||
 | 
			
		||||
            if(new_use_count != 0) return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dispose();
 | 
			
		||||
        weak_release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_HAS_THREADS)
 | 
			
		||||
        mutex_type::scoped_lock lock(mtx_);
 | 
			
		||||
#endif
 | 
			
		||||
        ++weak_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        long new_weak_count;
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
#if defined(BOOST_HAS_THREADS)
 | 
			
		||||
            mutex_type::scoped_lock lock(mtx_);
 | 
			
		||||
#endif
 | 
			
		||||
            new_weak_count = --weak_count_;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(new_weak_count == 0)
 | 
			
		||||
        {
 | 
			
		||||
            destruct();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_HAS_THREADS)
 | 
			
		||||
        mutex_type::scoped_lock lock(mtx_);
 | 
			
		||||
#endif
 | 
			
		||||
        return use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(sp_counted_base const &);
 | 
			
		||||
    sp_counted_base & operator= (sp_counted_base const &);
 | 
			
		||||
 | 
			
		||||
    long use_count_;        // #shared
 | 
			
		||||
    long weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32)
 | 
			
		||||
    mutable mutex_type mtx_;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
 | 
			
		||||
{
 | 
			
		||||
    boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
 | 
			
		||||
{
 | 
			
		||||
    boost::sp_array_constructor_hook(px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
 | 
			
		||||
{
 | 
			
		||||
    boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
 | 
			
		||||
{
 | 
			
		||||
    boost::sp_array_destructor_hook(px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class P, class D> void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Borland's Codeguard trips up over the -Vx- option here:
 | 
			
		||||
//
 | 
			
		||||
#ifdef __CODEGUARD__
 | 
			
		||||
# pragma option push -Vx-
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class P, class D> class sp_counted_base_impl: public sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    P ptr; // copy constructor must not throw
 | 
			
		||||
    D del; // copy constructor must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_base_impl(sp_counted_base_impl const &);
 | 
			
		||||
    sp_counted_base_impl & operator= (sp_counted_base_impl const &);
 | 
			
		||||
 | 
			
		||||
    typedef sp_counted_base_impl<P, D> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // pre: initial_use_count <= initial_weak_count, d(p) must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_base_impl(P p, D d): ptr(p), del(d)
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        detail::cbi_call_constructor_hook(this, p, d, 0);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        detail::cbi_call_destructor_hook(this, ptr, del, 0);
 | 
			
		||||
#endif
 | 
			
		||||
        del(ptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter(std::type_info const & ti)
 | 
			
		||||
    {
 | 
			
		||||
        return ti == typeid(D)? &del: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 | 
			
		||||
 | 
			
		||||
    void * operator new(std::size_t)
 | 
			
		||||
    {
 | 
			
		||||
        return std::allocator<this_type>().allocate(1, static_cast<this_type *>(0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete(void * p)
 | 
			
		||||
    {
 | 
			
		||||
        std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
 | 
			
		||||
    void * operator new(std::size_t)
 | 
			
		||||
    {
 | 
			
		||||
        return quick_allocator<this_type>::alloc();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete(void * p)
 | 
			
		||||
    {
 | 
			
		||||
        quick_allocator<this_type>::dealloc(p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
int const shared_count_id = 0x2C35F101;
 | 
			
		||||
@@ -49,8 +306,6 @@ int const   weak_count_id = 0x298C38A4;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct sp_nothrow_tag {};
 | 
			
		||||
 | 
			
		||||
class weak_count;
 | 
			
		||||
 | 
			
		||||
class shared_count
 | 
			
		||||
@@ -74,7 +329,7 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> explicit shared_count( Y * p ): pi_( 0 )
 | 
			
		||||
    template<class P, class D> shared_count(P p, D d): pi_(0)
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
@@ -83,44 +338,7 @@ public:
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = new sp_counted_impl_p<Y>( p );
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_delete( p );
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = new sp_counted_impl_p<Y>( p );
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            boost::checked_delete( p );
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
 | 
			
		||||
    template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
 | 
			
		||||
#else
 | 
			
		||||
    template<class P, class D> shared_count( P p, D d ): pi_(0)
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
 | 
			
		||||
        typedef Y* P;
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = new sp_counted_impl_pd<P, D>(p, d);
 | 
			
		||||
            pi_ = new sp_counted_base_impl<P, D>(p, d);
 | 
			
		||||
        }
 | 
			
		||||
        catch(...)
 | 
			
		||||
        {
 | 
			
		||||
@@ -130,7 +348,7 @@ public:
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = new sp_counted_impl_pd<P, D>(p, d);
 | 
			
		||||
        pi_ = new sp_counted_base_impl<P, D>(p, d);
 | 
			
		||||
 | 
			
		||||
        if(pi_ == 0)
 | 
			
		||||
        {
 | 
			
		||||
@@ -138,52 +356,6 @@ public:
 | 
			
		||||
            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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -192,20 +364,11 @@ public:
 | 
			
		||||
    // auto_ptr<Y> is special cased to provide the strong guarantee
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
 | 
			
		||||
    explicit shared_count(std::auto_ptr<Y> & r): pi_(new sp_counted_base_impl< Y *, checked_deleter<Y> >(r.get(), checked_deleter<Y>()))
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
#ifdef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            boost::throw_exception(std::bad_alloc());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        r.release();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -213,7 +376,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    ~shared_count() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( pi_ != 0 ) pi_->release();
 | 
			
		||||
        if(pi_ != 0) pi_->release();
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        id_ = 0;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -224,22 +387,17 @@ public:
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        if( pi_ != 0 ) pi_->add_ref_copy();
 | 
			
		||||
        if(pi_ != 0) pi_->add_ref_copy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
 | 
			
		||||
    shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
 | 
			
		||||
 | 
			
		||||
    shared_count & operator= (shared_count const & r) // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if( tmp != 0 ) tmp->add_ref_copy();
 | 
			
		||||
            if( pi_ != 0 ) pi_->release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
        if(tmp != 0) tmp->add_ref_copy();
 | 
			
		||||
        if(pi_ != 0) pi_->release();
 | 
			
		||||
        pi_ = tmp;
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -261,11 +419,6 @@ public:
 | 
			
		||||
        return use_count() == 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool empty() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return pi_ == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend inline bool operator==(shared_count const & a, shared_count const & b)
 | 
			
		||||
    {
 | 
			
		||||
        return a.pi_ == b.pi_;
 | 
			
		||||
@@ -273,15 +426,19 @@ public:
 | 
			
		||||
 | 
			
		||||
    friend inline bool operator<(shared_count const & a, shared_count const & b)
 | 
			
		||||
    {
 | 
			
		||||
        return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
 | 
			
		||||
        return std::less<sp_counted_base *>()(a.pi_, b.pi_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * get_deleter( sp_typeinfo const & ti ) const
 | 
			
		||||
    void * get_deleter(std::type_info const & ti) const
 | 
			
		||||
    {
 | 
			
		||||
        return pi_? pi_->get_deleter( ti ): 0;
 | 
			
		||||
        return pi_? pi_->get_deleter(ti): 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __CODEGUARD__
 | 
			
		||||
# pragma option pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class weak_count
 | 
			
		||||
{
 | 
			
		||||
@@ -331,13 +488,9 @@ public:
 | 
			
		||||
    weak_count & operator= (shared_count const & r) // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
            if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
        if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
        if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
        pi_ = tmp;
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -345,13 +498,9 @@ public:
 | 
			
		||||
    weak_count & operator= (weak_count const & r) // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
            if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
        if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
        if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
        pi_ = tmp;
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -379,25 +528,18 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
 | 
			
		||||
inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
    if( pi_ == 0 || !pi_->add_ref_lock() )
 | 
			
		||||
    if(pi_ != 0)
 | 
			
		||||
    {
 | 
			
		||||
        boost::throw_exception( boost::bad_weak_ptr() );
 | 
			
		||||
        pi_->add_ref_lock();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
    if( pi_ != 0 && !pi_->add_ref_lock() )
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        pi_ = 0;
 | 
			
		||||
        boost::throw_exception(boost::bad_weak_ptr());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -407,6 +549,7 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_(
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
# pragma warn .8027     // Functions containing try are not expanded inline
 | 
			
		||||
# pragma warn .8026     // Functions with excep. spec. are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,10 @@
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
@@ -1,76 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  detail/sp_convertible.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2008 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_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
 | 
			
		||||
# define BOOST_SP_NO_SP_CONVERTIBLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
 | 
			
		||||
# define BOOST_SP_NO_SP_CONVERTIBLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x600 )
 | 
			
		||||
# define BOOST_SP_NO_SP_CONVERTIBLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_convertible
 | 
			
		||||
{
 | 
			
		||||
    typedef char (&yes) [1];
 | 
			
		||||
    typedef char (&no)  [2];
 | 
			
		||||
 | 
			
		||||
    static yes f( T* );
 | 
			
		||||
    static no  f( ... );
 | 
			
		||||
 | 
			
		||||
    enum _vt { value = sizeof( f( (Y*)0 ) ) == sizeof(yes) };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sp_empty
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< bool > struct sp_enable_if_convertible_impl;
 | 
			
		||||
 | 
			
		||||
template<> struct sp_enable_if_convertible_impl<true>
 | 
			
		||||
{
 | 
			
		||||
    typedef sp_empty type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct sp_enable_if_convertible_impl<false>
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2005, 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/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_SP_DISABLE_THREADS )
 | 
			
		||||
# include <boost/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_SPINLOCK )
 | 
			
		||||
# include <boost/detail/sp_counted_base_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
# include <boost/detail/sp_counted_base_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
 | 
			
		||||
# include <boost/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 | 
			
		||||
# include <boost/detail/sp_counted_base_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
 | 
			
		||||
# 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__ )
 | 
			
		||||
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
 | 
			
		||||
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa )
 | 
			
		||||
# 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__ )
 | 
			
		||||
# include <boost/detail/sp_counted_base_w32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_HAS_THREADS )
 | 
			
		||||
# include <boost/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
# include <boost/detail/sp_counted_base_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
@@ -1,150 +0,0 @@
 | 
			
		||||
#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 <boost/detail/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
 | 
			
		||||
@@ -1,170 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( register long * pw )
 | 
			
		||||
{
 | 
			
		||||
    register int a;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
loop:
 | 
			
		||||
 | 
			
		||||
    lwarx   a, 0, pw
 | 
			
		||||
    addi    a, a, 1
 | 
			
		||||
    stwcx.  a, 0, pw
 | 
			
		||||
    bne-    loop
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline long atomic_decrement( register long * pw )
 | 
			
		||||
{
 | 
			
		||||
    register int a;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
    sync
 | 
			
		||||
 | 
			
		||||
loop:
 | 
			
		||||
 | 
			
		||||
    lwarx   a, 0, pw
 | 
			
		||||
    addi    a, a, -1
 | 
			
		||||
    stwcx.  a, 0, pw
 | 
			
		||||
    bne-    loop
 | 
			
		||||
 | 
			
		||||
    isync
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline long atomic_conditional_increment( register long * pw )
 | 
			
		||||
{
 | 
			
		||||
    register int a;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
loop:
 | 
			
		||||
 | 
			
		||||
    lwarx   a, 0, pw
 | 
			
		||||
    cmpwi   a, 0
 | 
			
		||||
    beq     store
 | 
			
		||||
 | 
			
		||||
    addi    a, a, 1
 | 
			
		||||
 | 
			
		||||
store:
 | 
			
		||||
 | 
			
		||||
    stwcx.  a, 0, pw
 | 
			
		||||
    bne-    loop
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    long use_count_;        // #shared
 | 
			
		||||
    long 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<long const volatile &>( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
@@ -1,158 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2005 Peter Dimov
 | 
			
		||||
//  Copyright 2005 Rene Rivera
 | 
			
		||||
//
 | 
			
		||||
//  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 <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline int atomic_exchange_and_add( int * pw, int dv )
 | 
			
		||||
{
 | 
			
		||||
    // int r = *pw;
 | 
			
		||||
    // *pw += dv;
 | 
			
		||||
    // return r;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
        mov esi, [pw]
 | 
			
		||||
        mov eax, dv
 | 
			
		||||
        lock xadd dword ptr [esi], eax
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    //atomic_exchange_and_add( pw, 1 );
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
        mov esi, [pw]
 | 
			
		||||
        lock inc dword ptr [esi]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // int rv = *pw;
 | 
			
		||||
    // if( rv != 0 ) ++*pw;
 | 
			
		||||
    // return rv;
 | 
			
		||||
 | 
			
		||||
    asm
 | 
			
		||||
    {
 | 
			
		||||
        mov esi, [pw]
 | 
			
		||||
        mov eax, dword ptr [esi]
 | 
			
		||||
    L0:
 | 
			
		||||
        test eax, eax
 | 
			
		||||
        je L1
 | 
			
		||||
        mov ebx, eax
 | 
			
		||||
        inc ebx
 | 
			
		||||
        lock cmpxchg dword ptr [esi], ebx
 | 
			
		||||
        jne L0
 | 
			
		||||
    L1:
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_exchange_and_add( &use_count_, -1 ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<int const volatile &>( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
@@ -1,157 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2006 Peter Dimov
 | 
			
		||||
//  Copyright 2005 Ben Hutchings
 | 
			
		||||
//
 | 
			
		||||
//  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 <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    int tmp;
 | 
			
		||||
 | 
			
		||||
    // No barrier is required here but fetchadd always has an acquire or
 | 
			
		||||
    // release barrier associated with it.  We choose release as it should be
 | 
			
		||||
    // cheaper.
 | 
			
		||||
    __asm__ ("fetchadd4.rel %0=%1,1" :
 | 
			
		||||
         "=r"(tmp), "=m"(*pw) :
 | 
			
		||||
         "m"( *pw ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    __asm__ ("     fetchadd4.rel %0=%1,-1 ;; \n"
 | 
			
		||||
             "     cmp.eq        p7,p0=1,%0 ;; \n"
 | 
			
		||||
             "(p7) ld4.acq       %0=%1    " :
 | 
			
		||||
             "=&r"(rv), "=m"(*pw) :
 | 
			
		||||
             "m"( *pw ) :
 | 
			
		||||
             "p7");
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp, tmp2;
 | 
			
		||||
 | 
			
		||||
    __asm__ ("0:   ld4          %0=%3           ;; \n"
 | 
			
		||||
         "     cmp.eq       p7,p0=0,%0        ;; \n"
 | 
			
		||||
         "(p7) br.cond.spnt 1f                \n"
 | 
			
		||||
         "     mov          ar.ccv=%0         \n"
 | 
			
		||||
         "     add          %1=1,%0           ;; \n"
 | 
			
		||||
         "     cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
 | 
			
		||||
         "     cmp.ne       p7,p0=%0,%2       ;; \n"
 | 
			
		||||
         "(p7) br.cond.spnt 0b                \n"
 | 
			
		||||
         "     mov          %0=%1             ;; \n"
 | 
			
		||||
         "1:" : 
 | 
			
		||||
         "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
 | 
			
		||||
         "m"( *pw ) :
 | 
			
		||||
         "ar.ccv", "p7");
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
@@ -1,181 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    int tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "lwarx %1, 0, %2\n\t"
 | 
			
		||||
        "addi %1, %1, 1\n\t"
 | 
			
		||||
        "stwcx. %1, 0, %2\n\t"
 | 
			
		||||
        "bne- 0b":
 | 
			
		||||
 | 
			
		||||
        "=m"( *pw ), "=&b"( tmp ):
 | 
			
		||||
        "r"( pw ), "m"( *pw ):
 | 
			
		||||
        "cc"
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "sync\n\t"
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "lwarx %1, 0, %2\n\t"
 | 
			
		||||
        "addi %1, %1, -1\n\t"
 | 
			
		||||
        "stwcx. %1, 0, %2\n\t"
 | 
			
		||||
        "bne- 0b\n\t"
 | 
			
		||||
        "isync":
 | 
			
		||||
 | 
			
		||||
        "=m"( *pw ), "=&b"( rv ):
 | 
			
		||||
        "r"( pw ), "m"( *pw ):
 | 
			
		||||
        "memory", "cc"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int rv;
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "lwarx %1, 0, %2\n\t"
 | 
			
		||||
        "cmpwi %1, 0\n\t"
 | 
			
		||||
        "beq 1f\n\t"
 | 
			
		||||
        "addi %1, %1, 1\n\t"
 | 
			
		||||
        "1:\n\t"
 | 
			
		||||
        "stwcx. %1, 0, %2\n\t"
 | 
			
		||||
        "bne- 0b":
 | 
			
		||||
 | 
			
		||||
        "=m"( *pw ), "=&b"( rv ):
 | 
			
		||||
        "r"( pw ), "m"( *pw ):
 | 
			
		||||
        "cc"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
@@ -1,166 +0,0 @@
 | 
			
		||||
#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 <boost/detail/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
 | 
			
		||||
@@ -1,173 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline 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)
 | 
			
		||||
        "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
 | 
			
		||||
        "memory", "cc" // clobbers
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    //atomic_exchange_and_add( pw, 1 );
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "lock\n\t"
 | 
			
		||||
        "incl %0":
 | 
			
		||||
        "=m"( *pw ): // output (%0)
 | 
			
		||||
        "m"( *pw ): // input (%1)
 | 
			
		||||
        "cc" // clobbers
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // int rv = *pw;
 | 
			
		||||
    // if( rv != 0 ) ++*pw;
 | 
			
		||||
    // return rv;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__
 | 
			
		||||
    (
 | 
			
		||||
        "movl %0, %%eax\n\t"
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        "test %%eax, %%eax\n\t"
 | 
			
		||||
        "je 1f\n\t"
 | 
			
		||||
        "movl %%eax, %2\n\t"
 | 
			
		||||
        "incl %2\n\t"
 | 
			
		||||
        "lock\n\t"
 | 
			
		||||
        "cmpxchgl %2, %0\n\t"
 | 
			
		||||
        "jne 0b\n\t"
 | 
			
		||||
        "1:":
 | 
			
		||||
        "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
 | 
			
		||||
        "m"( *pw ): // input (%3)
 | 
			
		||||
        "cc" // clobbers
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_exchange_and_add( &use_count_, -1 ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<int const volatile &>( use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
@@ -1,107 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_nt.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    long use_count_;        // #shared
 | 
			
		||||
    long 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()
 | 
			
		||||
    {
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
    {
 | 
			
		||||
        if( use_count_ == 0 ) return false;
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( --use_count_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        ++weak_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( --weak_count_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return use_count_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
@@ -1,135 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_pt.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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/sp_typeinfo.hpp>
 | 
			
		||||
#include <pthread.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 & );
 | 
			
		||||
 | 
			
		||||
    long use_count_;        // #shared
 | 
			
		||||
    long weak_count_;       // #weak + (#shared != 0)
 | 
			
		||||
 | 
			
		||||
    mutable pthread_mutex_t m_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 | 
			
		||||
    {
 | 
			
		||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
 | 
			
		||||
 | 
			
		||||
#if defined(__hpux) && defined(_DECTHREADS_)
 | 
			
		||||
        pthread_mutex_init( &m_, pthread_mutexattr_default );
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_init( &m_, 0 );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~sp_counted_base() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_destroy( &m_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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()
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        bool r = use_count_ == 0? false: ( ++use_count_, true );
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        long new_use_count = --use_count_;
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
 | 
			
		||||
        if( new_use_count == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        ++weak_count_;
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        long new_weak_count = --weak_count_;
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
 | 
			
		||||
        if( new_weak_count == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_lock( &m_ );
 | 
			
		||||
        long r = use_count_;
 | 
			
		||||
        pthread_mutex_unlock( &m_ );
 | 
			
		||||
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
@@ -1,113 +0,0 @@
 | 
			
		||||
#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 <boost/detail/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
 | 
			
		||||
@@ -1,131 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-2008 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/sp_typeinfo.hpp>
 | 
			
		||||
#include <boost/detail/spinlock_pool.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline int atomic_exchange_and_add( int * pw, int dv )
 | 
			
		||||
{
 | 
			
		||||
    spinlock_pool<1>::scoped_lock lock( pw );
 | 
			
		||||
 | 
			
		||||
    int r = *pw;
 | 
			
		||||
    *pw += dv;
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    spinlock_pool<1>::scoped_lock lock( pw );
 | 
			
		||||
    ++*pw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    spinlock_pool<1>::scoped_lock lock( pw );
 | 
			
		||||
 | 
			
		||||
    int rv = *pw;
 | 
			
		||||
    if( rv != 0 ) ++*pw;
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_exchange_and_add( &use_count_, -1 ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        atomic_increment( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            destroy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        spinlock_pool<1>::scoped_lock lock( &use_count_ );
 | 
			
		||||
        return use_count_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
@@ -1,155 +0,0 @@
 | 
			
		||||
#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 <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
 | 
			
		||||
# include <ia64intrin.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1,130 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_w32.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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)
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/interlocked.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_counted_base( sp_counted_base const & );
 | 
			
		||||
    sp_counted_base & operator= ( sp_counted_base const & );
 | 
			
		||||
 | 
			
		||||
    long use_count_;        // #shared
 | 
			
		||||
    long 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()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_INTERLOCKED_INCREMENT( &use_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool add_ref_lock() // true on success
 | 
			
		||||
    {
 | 
			
		||||
        for( ;; )
 | 
			
		||||
        {
 | 
			
		||||
            long tmp = static_cast< long const volatile& >( use_count_ );
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            dispose();
 | 
			
		||||
            weak_release();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_add_ref() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void weak_release() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if( BOOST_INTERLOCKED_DECREMENT( &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_W32_HPP_INCLUDED
 | 
			
		||||
@@ -1,231 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_impl.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//  Copyright 2004-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/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/detail/sp_counted_base.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
#include <boost/detail/quick_allocator.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 | 
			
		||||
#include <memory>           // std::allocator
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cstddef>          // std::size_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
 | 
			
		||||
void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class X> class sp_counted_impl_p: public sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X * px_;
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_p( sp_counted_impl_p const & );
 | 
			
		||||
    sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
 | 
			
		||||
 | 
			
		||||
    typedef sp_counted_impl_p<X> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit sp_counted_impl_p( X * px ): px_( px )
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_constructor_hook( px, sizeof(X), this );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
 | 
			
		||||
#endif
 | 
			
		||||
        boost::checked_delete( px_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & )
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t )
 | 
			
		||||
    {
 | 
			
		||||
        return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete( void * p )
 | 
			
		||||
    {
 | 
			
		||||
        std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t )
 | 
			
		||||
    {
 | 
			
		||||
        return quick_allocator<this_type>::alloc();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete( void * p )
 | 
			
		||||
    {
 | 
			
		||||
        quick_allocator<this_type>::dealloc( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Borland's Codeguard trips up over the -Vx- option here:
 | 
			
		||||
//
 | 
			
		||||
#ifdef __CODEGUARD__
 | 
			
		||||
# pragma option push -Vx-
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    P ptr; // copy constructor must not throw
 | 
			
		||||
    D del; // copy constructor must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pd( sp_counted_impl_pd const & );
 | 
			
		||||
    sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
 | 
			
		||||
 | 
			
		||||
    typedef sp_counted_impl_pd<P, D> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    // pre: d(p) must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void dispose() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        del( ptr );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & ti )
 | 
			
		||||
    {
 | 
			
		||||
        return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t )
 | 
			
		||||
    {
 | 
			
		||||
        return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete( void * p )
 | 
			
		||||
    {
 | 
			
		||||
        std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t )
 | 
			
		||||
    {
 | 
			
		||||
        return quick_allocator<this_type>::alloc();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete( void * p )
 | 
			
		||||
    {
 | 
			
		||||
        quick_allocator<this_type>::dealloc( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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__
 | 
			
		||||
# pragma option pop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
@@ -1,83 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/spinlock.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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)
 | 
			
		||||
//
 | 
			
		||||
//  struct spinlock
 | 
			
		||||
//  {
 | 
			
		||||
//      void lock();
 | 
			
		||||
//      bool try_lock();
 | 
			
		||||
//      void unlock();
 | 
			
		||||
//
 | 
			
		||||
//      class scoped_lock;
 | 
			
		||||
//  };
 | 
			
		||||
//
 | 
			
		||||
//  #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__) && defined( __arm__ )
 | 
			
		||||
#  include <boost/detail/spinlock_gcc_arm.hpp>
 | 
			
		||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
 | 
			
		||||
#  include <boost/detail/spinlock_sync.hpp>
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 | 
			
		||||
#  include <boost/detail/spinlock_w32.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
#  include <boost/detail/spinlock_pt.hpp>
 | 
			
		||||
#elif !defined(BOOST_HAS_THREADS)
 | 
			
		||||
#  include <boost/detail/spinlock_nt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
#  error Unrecognized threading platform
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
 | 
			
		||||
@@ -1,85 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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/yield_k.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class spinlock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    int v_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        int r;
 | 
			
		||||
 | 
			
		||||
        __asm__ __volatile__(
 | 
			
		||||
            "swp %0, %1, [%2]":
 | 
			
		||||
            "=&r"( r ): // outputs
 | 
			
		||||
            "r"( 1 ), "r"( &v_ ): // inputs
 | 
			
		||||
            "memory", "cc" );
 | 
			
		||||
 | 
			
		||||
        return r == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
        for( unsigned k = 0; !try_lock(); ++k )
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::yield( k );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        __asm__ __volatile__( "" ::: "memory" );
 | 
			
		||||
        *const_cast< int volatile* >( &v_ ) = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        spinlock & sp_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock( scoped_lock const & );
 | 
			
		||||
        scoped_lock & operator=( scoped_lock const & );
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock( spinlock & sp ): sp_( sp )
 | 
			
		||||
        {
 | 
			
		||||
            sp.lock();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            sp_.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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/assert.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class spinlock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    bool locked_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    inline bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        if( locked_ )
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            locked_ = true;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void lock()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( !locked_ );
 | 
			
		||||
        locked_ = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( locked_ );
 | 
			
		||||
        locked_ = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        spinlock & sp_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock( scoped_lock const & );
 | 
			
		||||
        scoped_lock & operator=( scoped_lock const & );
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock( spinlock & sp ): sp_( sp )
 | 
			
		||||
        {
 | 
			
		||||
            sp.lock();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            sp_.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_INIT { false }
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/spinlock_pool.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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)
 | 
			
		||||
//
 | 
			
		||||
//  spinlock_pool<0> is reserved for atomic<>, when/if it arrives
 | 
			
		||||
//  spinlock_pool<1> is reserved for shared_ptr reference counts
 | 
			
		||||
//  spinlock_pool<2> is reserved for shared_ptr atomic access
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/detail/spinlock.hpp>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template< int I > class spinlock_pool
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    static spinlock pool_[ 41 ];
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static spinlock & spinlock_for( void const * pv )
 | 
			
		||||
    {
 | 
			
		||||
        std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
 | 
			
		||||
        return pool_[ i ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        spinlock & sp_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock( scoped_lock const & );
 | 
			
		||||
        scoped_lock & operator=( scoped_lock const & );
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
 | 
			
		||||
        {
 | 
			
		||||
            sp_.lock();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            sp_.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
 | 
			
		||||
{
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, 
 | 
			
		||||
    BOOST_DETAIL_SPINLOCK_INIT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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 <pthread.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class spinlock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_t v_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        return pthread_mutex_trylock( &v_ ) == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_lock( &v_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_unlock( &v_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        spinlock & sp_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock( scoped_lock const & );
 | 
			
		||||
        scoped_lock & operator=( scoped_lock const & );
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock( spinlock & sp ): sp_( sp )
 | 
			
		||||
        {
 | 
			
		||||
            sp.lock();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            sp_.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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/yield_k.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
 | 
			
		||||
# include <ia64intrin.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class spinlock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    int v_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        int r = __sync_lock_test_and_set( &v_, 1 );
 | 
			
		||||
        return r == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
        for( unsigned k = 0; !try_lock(); ++k )
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::yield( k );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        __sync_lock_release( &v_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        spinlock & sp_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock( scoped_lock const & );
 | 
			
		||||
        scoped_lock & operator=( scoped_lock const & );
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock( spinlock & sp ): sp_( sp )
 | 
			
		||||
        {
 | 
			
		||||
            sp.lock();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            sp_.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
 | 
			
		||||
@@ -1,113 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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/interlocked.hpp>
 | 
			
		||||
#include <boost/detail/yield_k.hpp>
 | 
			
		||||
 | 
			
		||||
// BOOST_COMPILER_FENCE
 | 
			
		||||
 | 
			
		||||
#if defined(__INTEL_COMPILER)
 | 
			
		||||
 | 
			
		||||
#define BOOST_COMPILER_FENCE __memory_barrier();
 | 
			
		||||
 | 
			
		||||
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
 | 
			
		||||
 | 
			
		||||
extern "C" void _ReadWriteBarrier();
 | 
			
		||||
#pragma intrinsic( _ReadWriteBarrier )
 | 
			
		||||
 | 
			
		||||
#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
 | 
			
		||||
#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#define BOOST_COMPILER_FENCE
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class spinlock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    long v_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
 | 
			
		||||
 | 
			
		||||
        BOOST_COMPILER_FENCE
 | 
			
		||||
 | 
			
		||||
        return r == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void lock()
 | 
			
		||||
    {
 | 
			
		||||
        for( unsigned k = 0; !try_lock(); ++k )
 | 
			
		||||
        {
 | 
			
		||||
            boost::detail::yield( k );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unlock()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_COMPILER_FENCE
 | 
			
		||||
        *const_cast< long volatile* >( &v_ ) = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    class scoped_lock
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        spinlock & sp_;
 | 
			
		||||
 | 
			
		||||
        scoped_lock( scoped_lock const & );
 | 
			
		||||
        scoped_lock & operator=( scoped_lock const & );
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        explicit scoped_lock( spinlock & sp ): sp_( sp )
 | 
			
		||||
        {
 | 
			
		||||
            sp.lock();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            sp_.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
 | 
			
		||||
@@ -1,149 +0,0 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_YIELD_K_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/yield_k.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  void yield( unsigned k );
 | 
			
		||||
//
 | 
			
		||||
//  Typical use:
 | 
			
		||||
//
 | 
			
		||||
//  for( unsigned k = 0; !try_lock(); ++k ) yield( k );
 | 
			
		||||
//
 | 
			
		||||
//  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>
 | 
			
		||||
 | 
			
		||||
// BOOST_SMT_PAUSE
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
 | 
			
		||||
 | 
			
		||||
extern "C" void _mm_pause();
 | 
			
		||||
#pragma intrinsic( _mm_pause )
 | 
			
		||||
 | 
			
		||||
#define BOOST_SMT_PAUSE _mm_pause();
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
 | 
			
		||||
 | 
			
		||||
#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_USE_WINDOWS_H )
 | 
			
		||||
# include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_USE_WINDOWS_H )
 | 
			
		||||
  extern "C" void __stdcall Sleep( unsigned ms );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline void yield( unsigned k )
 | 
			
		||||
{
 | 
			
		||||
    if( k < 4 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
#if defined( BOOST_SMT_PAUSE )
 | 
			
		||||
    else if( k < 16 )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_SMT_PAUSE
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    else if( k < 32 )
 | 
			
		||||
    {
 | 
			
		||||
        Sleep( 0 );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        Sleep( 1 );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void yield( unsigned k )
 | 
			
		||||
{
 | 
			
		||||
    if( k < 4 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
#if defined( BOOST_SMT_PAUSE )
 | 
			
		||||
    else if( k < 16 )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_SMT_PAUSE
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    else if( k < 32 || k & 1 )
 | 
			
		||||
    {
 | 
			
		||||
        sched_yield();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // g++ -Wextra warns on {} or {0}
 | 
			
		||||
        struct timespec rqtp = { 0, 0 };
 | 
			
		||||
 | 
			
		||||
        // POSIX says that timespec has tv_sec and tv_nsec
 | 
			
		||||
        // But it doesn't guarantee order or placement
 | 
			
		||||
 | 
			
		||||
        rqtp.tv_sec = 0;
 | 
			
		||||
        rqtp.tv_nsec = 1000;
 | 
			
		||||
 | 
			
		||||
        nanosleep( &rqtp, 0 );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void yield( unsigned )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
 | 
			
		||||
@@ -6,9 +6,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
 | 
			
		||||
//
 | 
			
		||||
@@ -58,14 +59,8 @@ public:
 | 
			
		||||
        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
 | 
			
		||||
    mutable weak_ptr<_internal_element_type> _internal_weak_this;
 | 
			
		||||
    weak_ptr<_internal_element_type> _internal_weak_this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
// Copyright Peter Dimov and David Abrahams 2002.
 | 
			
		||||
// 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)
 | 
			
		||||
// Copyright Peter Dimov and David Abrahams 2002. Permission to copy,
 | 
			
		||||
// use, modify, sell and distribute this software is granted provided
 | 
			
		||||
// this copyright notice appears in all copies of the source. This
 | 
			
		||||
// software is provided "as is" without express or implied warranty,
 | 
			
		||||
// and with no claim as to its suitability for any purpose.
 | 
			
		||||
#ifndef GET_POINTER_DWA20021219_HPP
 | 
			
		||||
# define GET_POINTER_DWA20021219_HPP
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
 | 
			
		||||
//
 | 
			
		||||
@@ -22,17 +23,9 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/detail/sp_convertible.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/config/no_tr1/functional.hpp>           // for std::less
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
#if !defined(BOOST_NO_IOSFWD)
 | 
			
		||||
#include <functional>           // for std::less
 | 
			
		||||
#include <iosfwd>               // for std::basic_ostream
 | 
			
		||||
#else
 | 
			
		||||
#include <ostream>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
@@ -74,19 +67,9 @@ public:
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
    template<class U>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr( intrusive_ptr<U> const & rhs )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : p_( rhs.get() )
 | 
			
		||||
    template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
 | 
			
		||||
    {
 | 
			
		||||
        if( p_ != 0 ) intrusive_ptr_add_ref( p_ );
 | 
			
		||||
        if(p_ != 0) intrusive_ptr_add_ref(p_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -123,16 +106,6 @@ public:
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset()
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset( T * rhs )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( rhs ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const
 | 
			
		||||
    {
 | 
			
		||||
        return p_;
 | 
			
		||||
@@ -140,13 +113,11 @@ public:
 | 
			
		||||
 | 
			
		||||
    T & operator*() const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( p_ != 0 );
 | 
			
		||||
        return *p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator->() const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( p_ != 0 );
 | 
			
		||||
        return p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -204,22 +175,22 @@ template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, in
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
 | 
			
		||||
template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
 | 
			
		||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
 | 
			
		||||
template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
 | 
			
		||||
template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a != b.get();
 | 
			
		||||
}
 | 
			
		||||
@@ -269,9 +240,7 @@ template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U
 | 
			
		||||
 | 
			
		||||
// operator<<
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
 | 
			
		||||
#if defined(__GNUC__) &&  (__GNUC__ < 3)
 | 
			
		||||
 | 
			
		||||
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
 | 
			
		||||
{
 | 
			
		||||
@@ -281,10 +250,7 @@ template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
 | 
			
		||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
 | 
			
		||||
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)
 | 
			
		||||
@@ -296,11 +262,7 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // _STLP_NO_IOSTREAMS
 | 
			
		||||
 | 
			
		||||
#endif // __GNUC__ < 3
 | 
			
		||||
 | 
			
		||||
#endif // !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,433 +0,0 @@
 | 
			
		||||
#ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
#define BOOST_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//  make_shared.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007, 2008 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/make_shared.html
 | 
			
		||||
//  for documentation.
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/type_traits/type_with_alignment.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <new>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template< std::size_t N, std::size_t A > struct sp_aligned_storage
 | 
			
		||||
{
 | 
			
		||||
    union type
 | 
			
		||||
    {
 | 
			
		||||
        char data_[ N ];
 | 
			
		||||
        typename boost::type_with_alignment< A >::type align_;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class T > class sp_ms_deleter
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
 | 
			
		||||
 | 
			
		||||
    bool initialized_;
 | 
			
		||||
    storage_type storage_;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void destroy()
 | 
			
		||||
    {
 | 
			
		||||
        if( initialized_ )
 | 
			
		||||
        {
 | 
			
		||||
            reinterpret_cast< T* >( storage_.data_ )->~T();
 | 
			
		||||
            initialized_ = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_ms_deleter(): initialized_( false )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~sp_ms_deleter()
 | 
			
		||||
    {
 | 
			
		||||
        destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator()( T * )
 | 
			
		||||
    {
 | 
			
		||||
        destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * address()
 | 
			
		||||
    {
 | 
			
		||||
        return storage_.data_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_initialized()
 | 
			
		||||
    {
 | 
			
		||||
        initialized_ = true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template< class T > T forward( T t )
 | 
			
		||||
{
 | 
			
		||||
    return t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
// Zero-argument versions
 | 
			
		||||
//
 | 
			
		||||
// Used even when variadic templates are available because of the new T() vs new T issue
 | 
			
		||||
 | 
			
		||||
template< class T > boost::shared_ptr< T > make_shared()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T();
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T();
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// Variadic templates, rvalue reference
 | 
			
		||||
 | 
			
		||||
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( detail::forward<Args>( args )... );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( detail::forward<Args>( args )... );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// C++03 version
 | 
			
		||||
 | 
			
		||||
template< class T, class A1 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
 | 
			
		||||
 | 
			
		||||
    detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
 | 
			
		||||
#define BOOST_MEMORY_ORDER_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  boost/memory_order.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Defines enum boost::memory_order per the C++0x working draft
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
enum memory_order
 | 
			
		||||
{
 | 
			
		||||
    memory_order_relaxed = 0,
 | 
			
		||||
    memory_order_acquire = 1,
 | 
			
		||||
    memory_order_release = 2,
 | 
			
		||||
    memory_order_acq_rel = 3, // acquire | release
 | 
			
		||||
    memory_order_seq_cst = 7  // acq_rel | 4
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// (C) Copyright Ion Gaztanaga 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
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
 | 
			
		||||
#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  pointer_to_other.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Ion Gaztanaga 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
 | 
			
		||||
@@ -4,9 +4,10 @@
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_array.htm
 | 
			
		||||
//
 | 
			
		||||
@@ -46,9 +47,6 @@ private:
 | 
			
		||||
 | 
			
		||||
    typedef scoped_array<T> this_type;
 | 
			
		||||
 | 
			
		||||
    void operator==( scoped_array const& ) const;
 | 
			
		||||
    void operator!=( scoped_array const& ) const;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,10 @@
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
 | 
			
		||||
//
 | 
			
		||||
@@ -47,9 +48,6 @@ private:
 | 
			
		||||
 | 
			
		||||
    typedef scoped_ptr<T> this_type;
 | 
			
		||||
 | 
			
		||||
    void operator==( scoped_ptr const& ) const;
 | 
			
		||||
    void operator!=( scoped_ptr const& ) const;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,10 @@
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001, 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
@@ -20,8 +21,6 @@
 | 
			
		||||
#include <boost/detail/shared_array_nmt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <memory>             // TR1 cyclic inclusion fix
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -103,23 +102,7 @@ public:
 | 
			
		||||
        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 \
 | 
			
		||||
    ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
 | 
			
		||||
    ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) )
 | 
			
		||||
 | 
			
		||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
 | 
			
		||||
    typedef T * (this_type::*unspecified_bool_type)() const;
 | 
			
		||||
    
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,12 @@
 | 
			
		||||
//  shared_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001-2008 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
@@ -20,35 +21,17 @@
 | 
			
		||||
#include <boost/detail/shared_ptr_nmt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// In order to avoid circular dependencies with Boost.TR1
 | 
			
		||||
// we make sure that our include of <memory> doesn't try to
 | 
			
		||||
// pull in the TR1 headers: that's why we use this header 
 | 
			
		||||
// rather than including <memory> directly:
 | 
			
		||||
#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/throw_exception.hpp>
 | 
			
		||||
#include <boost/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/detail/sp_convertible.hpp>
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
 | 
			
		||||
#include <boost/detail/spinlock_pool.hpp>
 | 
			
		||||
#include <boost/memory_order.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <memory>               // for std::auto_ptr
 | 
			
		||||
#include <algorithm>            // for std::swap
 | 
			
		||||
#include <functional>           // for std::less
 | 
			
		||||
#include <typeinfo>             // for std::bad_cast
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
#if !defined(BOOST_NO_IOSFWD)
 | 
			
		||||
#include <iosfwd>               // for std::basic_ostream
 | 
			
		||||
#else
 | 
			
		||||
#include <ostream>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
 | 
			
		||||
# pragma warning(push)
 | 
			
		||||
@@ -100,56 +83,15 @@ template<> struct shared_ptr_traits<void const volatile>
 | 
			
		||||
 | 
			
		||||
// enable_shared_from_this support
 | 
			
		||||
 | 
			
		||||
template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, boost::enable_shared_from_this<T> const * pe, Y const * px )
 | 
			
		||||
template<class T, class Y> void sp_enable_shared_from_this(boost::enable_shared_from_this<T> * pe, Y * px, shared_count const & pn)
 | 
			
		||||
{
 | 
			
		||||
    if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
 | 
			
		||||
    if(pe != 0) pe->_internal_weak_this._internal_assign(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 )
 | 
			
		||||
inline void sp_enable_shared_from_this(void const volatile *, void const volatile *, shared_count const &)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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*/, ... )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -173,16 +115,16 @@ public:
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
    typedef T value_type;
 | 
			
		||||
    typedef T * pointer;
 | 
			
		||||
    typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
 | 
			
		||||
    typedef typename detail::shared_ptr_traits<T>::reference reference;
 | 
			
		||||
 | 
			
		||||
    shared_ptr(): px(0), pn() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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, checked_deleter<Y>()) // Y must be complete
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( pn, p, p );
 | 
			
		||||
        detail::sp_enable_shared_from_this(p, p, pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
@@ -193,14 +135,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
 | 
			
		||||
    {
 | 
			
		||||
        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 );
 | 
			
		||||
        detail::sp_enable_shared_from_this(p, p, pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine...
 | 
			
		||||
@@ -225,55 +160,31 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        if( !pn.empty() )
 | 
			
		||||
        {
 | 
			
		||||
            px = r.px;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    shared_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    shared_ptr( shared_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // aliasing
 | 
			
		||||
    template< class Y >
 | 
			
		||||
    shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    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, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, 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)
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, 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
 | 
			
		||||
        {
 | 
			
		||||
            pn = boost::detail::shared_count();
 | 
			
		||||
            pn = detail::shared_count();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    {
 | 
			
		||||
        if(px == 0)
 | 
			
		||||
        {
 | 
			
		||||
@@ -287,26 +198,13 @@ public:
 | 
			
		||||
    explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
 | 
			
		||||
    {
 | 
			
		||||
        Y * tmp = r.get();
 | 
			
		||||
        pn = boost::detail::shared_count(r);
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
 | 
			
		||||
        pn = detail::shared_count(r);
 | 
			
		||||
        detail::sp_enable_shared_from_this(tmp, tmp, pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
 | 
			
		||||
@@ -321,65 +219,12 @@ public:
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=( std::auto_ptr<Y> & r )
 | 
			
		||||
    shared_ptr & operator=(std::auto_ptr<Y> & r)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(r).swap(*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>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    shared_ptr( shared_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    shared_ptr( shared_ptr<Y> && r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : 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
 | 
			
		||||
 | 
			
		||||
    void reset() // never throws in 1.30+
 | 
			
		||||
@@ -393,19 +238,9 @@ public:
 | 
			
		||||
        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 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 );
 | 
			
		||||
        this_type(p, d).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reference operator* () const // never throws
 | 
			
		||||
@@ -419,7 +254,7 @@ public:
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
@@ -427,39 +262,22 @@ public:
 | 
			
		||||
 | 
			
		||||
    // implicit conversion to "bool"
 | 
			
		||||
 | 
			
		||||
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
 | 
			
		||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
 | 
			
		||||
 | 
			
		||||
    operator bool () const
 | 
			
		||||
    {
 | 
			
		||||
        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 \
 | 
			
		||||
    ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
 | 
			
		||||
    ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
 | 
			
		||||
    ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
 | 
			
		||||
 | 
			
		||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
 | 
			
		||||
    typedef T * (this_type::*unspecified_bool_type)() const;
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::get;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#else 
 | 
			
		||||
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
@@ -498,14 +316,9 @@ public:
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
 | 
			
		||||
    void * _internal_get_deleter(std::type_info const & ti) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn.get_deleter( ti );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool _internal_equiv( shared_ptr const & r ) const
 | 
			
		||||
    {
 | 
			
		||||
        return px == r.px && pn == r.pn;
 | 
			
		||||
        return pn.get_deleter(ti);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// Tasteless as this may seem, making all members public allows member templates
 | 
			
		||||
@@ -522,7 +335,7 @@ private:
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    boost::detail::shared_count pn;    // reference counter
 | 
			
		||||
    detail::shared_count pn;    // reference counter
 | 
			
		||||
 | 
			
		||||
};  // shared_ptr
 | 
			
		||||
 | 
			
		||||
@@ -559,34 +372,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)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::static_cast_tag());
 | 
			
		||||
    return shared_ptr<T>(r, detail::static_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::const_cast_tag());
 | 
			
		||||
    return shared_ptr<T>(r, detail::const_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
 | 
			
		||||
    return shared_ptr<T>(r, detail::dynamic_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::static_cast_tag());
 | 
			
		||||
    return shared_ptr<T>(r, detail::static_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
 | 
			
		||||
    return shared_ptr<T>(r, detail::dynamic_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
 | 
			
		||||
    return shared_ptr<T>(r, detail::polymorphic_cast_tag());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
 | 
			
		||||
@@ -604,9 +417,7 @@ template<class T> inline T * get_pointer(shared_ptr<T> const & p)
 | 
			
		||||
 | 
			
		||||
// operator<<
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
 | 
			
		||||
#if defined(__GNUC__) &&  (__GNUC__ < 3)
 | 
			
		||||
 | 
			
		||||
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
 | 
			
		||||
{
 | 
			
		||||
@@ -616,39 +427,30 @@ template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> co
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
 | 
			
		||||
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
 | 
			
		||||
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)
 | 
			
		||||
# else
 | 
			
		||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
 | 
			
		||||
# endif
 | 
			
		||||
# endif 
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // _STLP_NO_IOSTREAMS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // __GNUC__ < 3
 | 
			
		||||
// get_deleter (experimental)
 | 
			
		||||
 | 
			
		||||
#endif // !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
 | 
			
		||||
// get_deleter
 | 
			
		||||
 | 
			
		||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
 | 
			
		||||
    ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
 | 
			
		||||
    ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
 | 
			
		||||
#if (defined(__GNUC__) &&  (__GNUC__ < 3)) || (defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238))
 | 
			
		||||
 | 
			
		||||
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
 | 
			
		||||
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
 | 
			
		||||
// apparently EDG 2.38 also doesn't accept it
 | 
			
		||||
 | 
			
		||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
 | 
			
		||||
    void const * q = p._internal_get_deleter(typeid(D));
 | 
			
		||||
    return const_cast<D *>(static_cast<D const *>(q));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -656,86 +458,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)
 | 
			
		||||
{
 | 
			
		||||
    return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// atomic access
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
 | 
			
		||||
{
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
 | 
			
		||||
    return *p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
 | 
			
		||||
{
 | 
			
		||||
    return atomic_load( p );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
 | 
			
		||||
    p->swap( r );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
 | 
			
		||||
{
 | 
			
		||||
    atomic_store( p, r ); // std::move( r )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
 | 
			
		||||
 | 
			
		||||
    sp.lock();
 | 
			
		||||
    p->swap( r );
 | 
			
		||||
    sp.unlock();
 | 
			
		||||
 | 
			
		||||
    return r; // return std::move( r )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
 | 
			
		||||
{
 | 
			
		||||
    return atomic_exchange( p, r ); // std::move( r )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w )
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
 | 
			
		||||
 | 
			
		||||
    sp.lock();
 | 
			
		||||
 | 
			
		||||
    if( p->_internal_equiv( *v ) )
 | 
			
		||||
    {
 | 
			
		||||
        p->swap( w );
 | 
			
		||||
 | 
			
		||||
        sp.unlock();
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<T> tmp( *p );
 | 
			
		||||
 | 
			
		||||
        sp.unlock();
 | 
			
		||||
 | 
			
		||||
        tmp.swap( *v );
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
 | 
			
		||||
{
 | 
			
		||||
    return atomic_compare_exchange( p, v, w ); // std::move( w )
 | 
			
		||||
    return static_cast<D *>(p._internal_get_deleter(typeid(D)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -744,7 +467,7 @@ template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> *
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
#endif    
 | 
			
		||||
 | 
			
		||||
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,13 @@
 | 
			
		||||
//  For convenience, this header includes the rest of the smart
 | 
			
		||||
//  pointer library headers.
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2003 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)
 | 
			
		||||
//  Copyright (c) 1998-2002 boost.org
 | 
			
		||||
//  Copyright (c) 2003 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/smart_ptr.htm
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
@@ -6,15 +6,14 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
//  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>
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
 | 
			
		||||
@@ -61,35 +60,17 @@ public:
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : pn(r.pn) // never throws
 | 
			
		||||
    weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.lock().get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    weak_ptr( shared_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
 | 
			
		||||
@@ -111,7 +92,31 @@ public:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> lock() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
 | 
			
		||||
#if defined(BOOST_HAS_THREADS)
 | 
			
		||||
 | 
			
		||||
        // optimization: avoid throw overhead
 | 
			
		||||
        if(expired())
 | 
			
		||||
        {
 | 
			
		||||
            return shared_ptr<element_type>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            return shared_ptr<element_type>(*this);
 | 
			
		||||
        }
 | 
			
		||||
        catch(bad_weak_ptr const &)
 | 
			
		||||
        {
 | 
			
		||||
            // Q: how can we get here?
 | 
			
		||||
            // A: another thread may have invalidated r after the use_count test above.
 | 
			
		||||
            return shared_ptr<element_type>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        // optimization: avoid try/catch overhead when single threaded
 | 
			
		||||
        return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
@@ -135,7 +140,7 @@ public:
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
 | 
			
		||||
    void _internal_assign(T * px2, detail::shared_count const & pn2)
 | 
			
		||||
    {
 | 
			
		||||
        px = px2;
 | 
			
		||||
        pn = pn2;
 | 
			
		||||
@@ -158,8 +163,8 @@ private:
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    T * px;                       // contained pointer
 | 
			
		||||
    boost::detail::weak_count pn; // reference counter
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    detail::weak_count pn;      // reference counter
 | 
			
		||||
 | 
			
		||||
};  // weak_ptr
 | 
			
		||||
 | 
			
		||||
@@ -173,6 +178,12 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & 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
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,3 @@ Automatic redirection failed, please go to
 | 
			
		||||
<a href="smart_ptr.htm">smart_ptr.htm</a>.
 | 
			
		||||
</body>
 | 
			
		||||
</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">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body text="#000000" bgColor="#ffffff">
 | 
			
		||||
		<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
 | 
			
		||||
					border="0"></A>intrusive_ptr class template</h1>
 | 
			
		||||
		<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">intrusive_ptr 
 | 
			
		||||
			class template</h1>
 | 
			
		||||
		<p>
 | 
			
		||||
			<A href="#Introduction">Introduction</A><br>
 | 
			
		||||
			<A href="#Synopsis">Synopsis</A><br>
 | 
			
		||||
@@ -31,11 +31,11 @@
 | 
			
		||||
		<P>The main reasons to use <STRONG>intrusive_ptr</STRONG> are:</P>
 | 
			
		||||
		<UL>
 | 
			
		||||
			<LI>
 | 
			
		||||
			Some existing frameworks or OSes provide objects with embedded reference 
 | 
			
		||||
			counts;
 | 
			
		||||
				Some existing frameworks or OSes provide objects with embedded reference 
 | 
			
		||||
				counts;</LI>
 | 
			
		||||
			<LI>
 | 
			
		||||
				The memory footprint of <STRONG>intrusive_ptr</STRONG>
 | 
			
		||||
			is the same as the corresponding raw pointer;
 | 
			
		||||
				The memory footprint of <STRONG>intrusive_ptr</STRONG> is the same as the 
 | 
			
		||||
				corresponding raw pointer;</LI>
 | 
			
		||||
			<LI>
 | 
			
		||||
				<STRONG>intrusive_ptr<T></STRONG> can be constructed from an arbitrary 
 | 
			
		||||
				raw pointer of type <STRONG>T *</STRONG>.</LI></UL>
 | 
			
		||||
@@ -61,10 +61,7 @@
 | 
			
		||||
 | 
			
		||||
      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);
 | 
			
		||||
      intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
 | 
			
		||||
 | 
			
		||||
      void <a href="#reset" >reset</a>();
 | 
			
		||||
      void <a href="#reset" >reset</a>(T * r);
 | 
			
		||||
      template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
 | 
			
		||||
 | 
			
		||||
      T & <A href="#indirection" >operator*</A>() const; // never throws
 | 
			
		||||
      T * <A href="#indirection" >operator-></A>() const; // never throws
 | 
			
		||||
@@ -130,8 +127,8 @@
 | 
			
		||||
			<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>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>intrusive_ptr(intrusive_ptr const & r);
 | 
			
		||||
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);</pre>
 | 
			
		||||
		<pre>intrusive_ptr(intrusive_ptr const & r); // never throws
 | 
			
		||||
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<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>
 | 
			
		||||
@@ -142,22 +139,13 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);</pr
 | 
			
		||||
			<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<H3><a name="assignment">assignment</a></H3>
 | 
			
		||||
		<pre>intrusive_ptr & operator=(intrusive_ptr const & r);
 | 
			
		||||
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
 | 
			
		||||
		<pre>intrusive_ptr & operator=(intrusive_ptr const & r); // never throws
 | 
			
		||||
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r); // never throws
 | 
			
		||||
intrusive_ptr & operator=(T * r);</pre>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
 | 
			
		||||
			<P><B>Returns:</B> <code>*this</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<H3><a name="reset">reset</a></H3>
 | 
			
		||||
		<pre>void reset();</pre>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<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>
 | 
			
		||||
		<pre>T & operator*() const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
@@ -208,26 +196,26 @@ intrusive_ptr & operator=(T * r);</pre>
 | 
			
		||||
			<p><b>Returns:</b> <code>a.get() != b.get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator==(intrusive_ptr<T> const & a, U * b); // never throws</pre>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  bool operator==(intrusive_ptr<T> const & a, T * b); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a.get() == b</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator!=(intrusive_ptr<T> const & a, U * b); // never throws</pre>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  bool operator!=(intrusive_ptr<T> const & a, T * b); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a.get() != b</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator==(T * a, intrusive_ptr<U> const & b); // never throws</pre>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  bool operator==(T * a, intrusive_ptr<T> const & b); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a == b.get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class T, class U>
 | 
			
		||||
  bool operator!=(T * a, intrusive_ptr<U> const & b); // never throws</pre>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
  bool operator!=(T * a, intrusive_ptr<T> const & b); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>a != b.get()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
@@ -290,8 +278,9 @@ intrusive_ptr & operator=(T * r);</pre>
 | 
			
		||||
		<p>
 | 
			
		||||
			$Date$</p>
 | 
			
		||||
		<p>
 | 
			
		||||
			<small>Copyright <20> 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version 
 | 
			
		||||
				1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 
 | 
			
		||||
				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
			<small>Copyright <20> 2003 Peter Dimov. 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.</small></p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,105 +0,0 @@
 | 
			
		||||
<!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>
 | 
			
		||||
@@ -1,108 +0,0 @@
 | 
			
		||||
<!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">
 | 
			
		||||
	</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"
 | 
			
		||||
					border="0"></A>scoped_array class template</h1>
 | 
			
		||||
		<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86"><a name="scoped_array">scoped_array</a>
 | 
			
		||||
			class template</h1>
 | 
			
		||||
		<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>
 | 
			
		||||
			expression.) The array pointed to is guaranteed to be deleted, either on 
 | 
			
		||||
@@ -14,9 +14,10 @@
 | 
			
		||||
		<p>The <b>scoped_array</b> template is a simple solution for simple needs. It 
 | 
			
		||||
			supplies a basic "resource acquisition is initialization" facility, without 
 | 
			
		||||
			shared-ownership or transfer-of-ownership semantics. Both its name and 
 | 
			
		||||
			enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
 | 
			
		||||
				noncopyable</a>) signal its intent to retain ownership solely within the 
 | 
			
		||||
			current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>, 
 | 
			
		||||
			enforcement of semantics (by being
 | 
			
		||||
        <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>) signal its intent to retain ownership solely within the 
 | 
			
		||||
			current scope. Because it is
 | 
			
		||||
        <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>
 | 
			
		||||
		<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 
 | 
			
		||||
@@ -47,8 +48,6 @@
 | 
			
		||||
      T & <a href="#operator[]">operator[]</a>(std::ptrdiff_t i) 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
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -91,10 +90,6 @@
 | 
			
		||||
		<pre>T * get() const; // never throws</pre>
 | 
			
		||||
		<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>
 | 
			
		||||
		<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>
 | 
			
		||||
		<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 
 | 
			
		||||
@@ -106,11 +101,11 @@
 | 
			
		||||
		<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. 
 | 
			
		||||
			Provided as an aid to generic programming.</p>
 | 
			
		||||
		<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><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 
 | 
			
		||||
			1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 
 | 
			
		||||
			copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
		<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>Copyright 1999 Greg Colvin and Beman Dawes. 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>
 | 
			
		||||
@@ -5,8 +5,8 @@
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</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"
 | 
			
		||||
					border="0"></A>scoped_ptr class template</h1>
 | 
			
		||||
		<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86"><a name="scoped_ptr">scoped_ptr</a>
 | 
			
		||||
			class template</h1>
 | 
			
		||||
		<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.) 
 | 
			
		||||
			The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>, 
 | 
			
		||||
@@ -48,8 +48,6 @@
 | 
			
		||||
     T * <a href="#indirection">operator-></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
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -92,10 +90,6 @@
 | 
			
		||||
		<pre>T * get() const; // never throws</pre>
 | 
			
		||||
		<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>
 | 
			
		||||
		<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>
 | 
			
		||||
		<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 
 | 
			
		||||
@@ -121,7 +115,7 @@ class MyClass {
 | 
			
		||||
    int add_one() { return ++*ptr; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    boost::scoped_ptr<Shoe> x(new Shoe);
 | 
			
		||||
    MyClass my_instance;
 | 
			
		||||
@@ -156,8 +150,8 @@ Buckle my shoe</pre>
 | 
			
		||||
		<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 
 | 
			
		||||
			file.</p>
 | 
			
		||||
		<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
 | 
			
		||||
			sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>, 
 | 
			
		||||
		<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</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 
 | 
			
		||||
			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>
 | 
			
		||||
@@ -171,11 +165,12 @@ Buckle my shoe</pre>
 | 
			
		||||
			given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership 
 | 
			
		||||
			is required. (supplied by Dave Abrahams)</p>
 | 
			
		||||
		<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>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 
 | 
			
		||||
			1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 
 | 
			
		||||
			copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
		<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002 Peter Dimov. 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>
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,8 @@
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</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"
 | 
			
		||||
					border="0"></A>shared_array class template</h1>
 | 
			
		||||
		<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">shared_array 
 | 
			
		||||
			class template</h1>
 | 
			
		||||
		<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>
 | 
			
		||||
			expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
 | 
			
		||||
@@ -53,8 +53,6 @@
 | 
			
		||||
      bool <a href="#unique">unique</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
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@@ -141,10 +139,6 @@
 | 
			
		||||
			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 
 | 
			
		||||
			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>
 | 
			
		||||
		<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 
 | 
			
		||||
@@ -177,9 +171,10 @@ template<class T>
 | 
			
		||||
		<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><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 
 | 
			
		||||
			1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 
 | 
			
		||||
			copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
		<p>Copyright 1999 Greg Colvin and Beman Dawes. 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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										154
									
								
								shared_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								shared_ptr.htm
									
									
									
									
									
								
							@@ -5,8 +5,8 @@
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body text="#000000" bgColor="#ffffff">
 | 
			
		||||
		<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
 | 
			
		||||
					border="0"></A>shared_ptr class template</h1>
 | 
			
		||||
		<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">shared_ptr 
 | 
			
		||||
			class template</h1>
 | 
			
		||||
		<p><A href="#Introduction">Introduction</A><br>
 | 
			
		||||
			<A href="#BestPractices">Best Practices</A><br>
 | 
			
		||||
			<A href="#Synopsis">Synopsis</A><br>
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
			<A href="sp_techniques.html">Programming Techniques</A></p>
 | 
			
		||||
		<h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
		<p>The <b>shared_ptr</b> class template stores a pointer to a dynamically allocated 
 | 
			
		||||
			object, typically with a C++ <EM>new-expression</EM>. The object pointed to is 
 | 
			
		||||
			object, typically with a C++ <EM>new-expression</EM> . The object pointed to is 
 | 
			
		||||
			guaranteed to be deleted when the last <b>shared_ptr</b> pointing to it is 
 | 
			
		||||
			destroyed or reset. See the <A href="#example">example</A>.</p>
 | 
			
		||||
		<p>Every <b>shared_ptr</b> meets the <b>CopyConstructible</b> and <b>Assignable</b> 
 | 
			
		||||
@@ -47,13 +47,6 @@
 | 
			
		||||
			to <STRONG>shared_ptr<T const></STRONG>, to <STRONG>shared_ptr<U></STRONG>
 | 
			
		||||
			where <STRONG>U</STRONG> is an accessible base of <STRONG>T</STRONG>, and to <STRONG>
 | 
			
		||||
				shared_ptr<void></STRONG>.</P>
 | 
			
		||||
		<P><STRONG>shared_ptr</STRONG> is now part of <STRONG>TR1</STRONG>, the first C++ 
 | 
			
		||||
			Library Technical Report. The latest draft of <STRONG>TR1</STRONG> is available 
 | 
			
		||||
			at the following location:</P>
 | 
			
		||||
		<P><A href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf</A>
 | 
			
		||||
			(1.36Mb PDF)</P>
 | 
			
		||||
		<P>This implementation conforms to the TR1 specification, with the only exception 
 | 
			
		||||
			that it resides in namespace <code>boost</code> instead of <code>std::tr1</code>.</P>
 | 
			
		||||
		<h2><a name="BestPractices">Best Practices</a></h2>
 | 
			
		||||
		<P>A simple guideline that nearly eliminates the possibility of memory leaks is: 
 | 
			
		||||
			always use a named smart pointer variable to hold the result of <STRONG>new. </STRONG>
 | 
			
		||||
@@ -106,12 +99,10 @@ void bad()
 | 
			
		||||
      <A href="#constructors" >shared_ptr</A>(); // never throws
 | 
			
		||||
      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, 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="#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, 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>(std::auto_ptr<Y> & r);
 | 
			
		||||
 | 
			
		||||
@@ -122,8 +113,6 @@ void bad()
 | 
			
		||||
      void <A href="#reset" >reset</A>(); // never throws
 | 
			
		||||
      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, 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
 | 
			
		||||
@@ -165,6 +154,15 @@ void bad()
 | 
			
		||||
  template<class D, class T>
 | 
			
		||||
    D * <A href="#get_deleter">get_deleter</A>(shared_ptr<T> const & p);
 | 
			
		||||
}</pre>
 | 
			
		||||
		<P><EM>[It might be convenient to relax the requirements on <STRONG>shared_ptr</STRONG>'s 
 | 
			
		||||
				signature, allowing an additional, defaulted, template parameter; the parameter 
 | 
			
		||||
				can encode the threading model, for example. This would help in detecting 
 | 
			
		||||
				possible ODR violations.</EM></P>
 | 
			
		||||
		<P><EM>On the other hand, using <STRONG>shared_ptr</STRONG> as an argument to a 
 | 
			
		||||
				template template parameter requires an exact signature match. </EM><EM>Metaprogramming 
 | 
			
		||||
				experts tend to deemphasize template template parameters as they are too 
 | 
			
		||||
				inflexible, but the alternative is typically an std::allocator::rebind-type 
 | 
			
		||||
				"hack".]</EM></P>
 | 
			
		||||
		<h2><a name="Members">Members</a></h2>
 | 
			
		||||
		<h3><a name="element_type">element_type</a></h3>
 | 
			
		||||
		<pre>typedef T element_type;</pre>
 | 
			
		||||
@@ -174,13 +172,24 @@ void bad()
 | 
			
		||||
		<h3><a name="constructors">constructors</a></h3>
 | 
			
		||||
		<pre>shared_ptr(); // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Effects:</b> Constructs an <EM>empty</EM> <b>shared_ptr</b>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>use_count() == 0 && get() == 0</code>.</p>
 | 
			
		||||
			<p><b>Effects:</b> Constructs an <EM>empty</EM> <b>shared_ptr</b>. <EM>Empty</EM> <STRONG>
 | 
			
		||||
					shared_ptr</STRONG> objects have an unspecified <A href="#use_count">use_count</A>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() == 0</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<P><EM>[The nothrow guarantee is important, since <STRONG>reset()</STRONG> is specified 
 | 
			
		||||
				in terms of the default constructor; this implies that the constructor must not 
 | 
			
		||||
				allocate memory.]</EM></P>
 | 
			
		||||
				allocate memory.</EM></P>
 | 
			
		||||
		<P><EM>There are two possible implementations, one stores 0 as a pointer to the 
 | 
			
		||||
				reference count, the other uses a single statically allocated count for all 
 | 
			
		||||
				default-constructed <STRONG>shared_ptr</STRONG>s. The second option is 
 | 
			
		||||
				difficult to achieve in the current header-only reference implementation due to 
 | 
			
		||||
				thread safety issues and initialization order, but it should not be precluded 
 | 
			
		||||
				by the specification. That's why the use_count() has been left unspecified.</EM></P>
 | 
			
		||||
		<P><EM>A future release may enable <STRONG>shared_ptr</STRONG> construction from a 
 | 
			
		||||
				literal zero, for consistency with built-in pointers. It is not clear yet 
 | 
			
		||||
				whether this constructor should be left implicit, enabling <STRONG>0</STRONG> to 
 | 
			
		||||
				be used as a shorthand for <STRONG>shared_ptr<T>().</STRONG>]</EM></P>
 | 
			
		||||
		<pre>template<class Y> explicit shared_ptr(Y * p);</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Requirements:</b> <b>p</b> must be convertible to <b>T *</b>. <STRONG>Y</STRONG>
 | 
			
		||||
@@ -189,8 +198,8 @@ void bad()
 | 
			
		||||
			</p>
 | 
			
		||||
			<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>owns</EM> the pointer <b>p</b>.</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 
 | 
			
		||||
				exception when a resource other than memory could not be obtained.</p>
 | 
			
		||||
			<p><b>Throws:</b> <b>std::bad_alloc</b> or an implementation-defined exception when 
 | 
			
		||||
				a resource other than memory could not be obtained.</p>
 | 
			
		||||
			<p><b>Exception safety:</b> If an exception is thrown, <code>delete p</code> is 
 | 
			
		||||
				called.</p>
 | 
			
		||||
			<P><STRONG>Notes:</STRONG> <B>p</B> must be a pointer to an object that was 
 | 
			
		||||
@@ -207,23 +216,18 @@ void bad()
 | 
			
		||||
				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>
 | 
			
		||||
					this</STRONG>" problem.</EM><EM>]</EM></P>
 | 
			
		||||
		<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>
 | 
			
		||||
		<pre>template<class Y, class D> shared_ptr(Y * p, D d);</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<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 
 | 
			
		||||
				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. <STRONG>
 | 
			
		||||
					A</STRONG> must be an <EM>Allocator</EM>, as described in section 20.1.5 (<STRONG>Allocator 
 | 
			
		||||
					requirements</STRONG>) of the C++ Standard.
 | 
			
		||||
				well-formed, must not invoke undefined behavior, and must not throw exceptions.
 | 
			
		||||
			</p>
 | 
			
		||||
			<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>. The second constructor allocates 
 | 
			
		||||
				memory using a copy of <STRONG>a</STRONG>.</p>
 | 
			
		||||
					p</STRONG> and the deleter <b>d</b>.</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 
 | 
			
		||||
				exception when a resource other than memory could not be obtained.</p>
 | 
			
		||||
			<p><b>Throws:</b> <b>std::bad_alloc</b> or an implementation-defined exception when 
 | 
			
		||||
				a resource other than memory could not be obtained.</p>
 | 
			
		||||
			<p><b>Exception safety:</b> If an exception is thrown, <code>d(p)</code> is called.</p>
 | 
			
		||||
			<p><b>Notes:</b> When the the time comes to delete the object pointed to by <b>p</b>, 
 | 
			
		||||
				the stored copy of <STRONG>d</STRONG> is invoked with the stored copy of <STRONG>p</STRONG>
 | 
			
		||||
@@ -241,10 +245,17 @@ template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);</pre>
 | 
			
		||||
		<P><EM>The requirement that the copy constructor of <b>D</b> does not throw comes from 
 | 
			
		||||
				the pass by value. If the copy constructor throws, the pointer is leaked. 
 | 
			
		||||
				Removing the requirement requires a pass by (const) reference.</EM></P>
 | 
			
		||||
		<P><EM>The main problem with pass by reference lies in its interaction with rvalues. A 
 | 
			
		||||
				const reference may still cause a copy, and will require a const operator(). A 
 | 
			
		||||
				non-const reference won't bind to an rvalue at all. A good solution to this 
 | 
			
		||||
				problem is the rvalue reference proposed in <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">
 | 
			
		||||
		<P><EM>Pass by reference is problematic since (1) pass by value conveniently changes 
 | 
			
		||||
				functions (function references) to function pointers (this has to be performed 
 | 
			
		||||
				manually otherwise and some compilers may not be able to do it) and (2) const 
 | 
			
		||||
				references don't currently (per the standard) bind to functions. This can be 
 | 
			
		||||
				solved (I think) but it requires an overload set that breaks on many compilers 
 | 
			
		||||
				due to 14.5.5.2 problems (and of course it will break on compilers that don't 
 | 
			
		||||
				do partial ordering at all.)</EM></P>
 | 
			
		||||
		<P><EM>The main problem with pass by reference, though, lies in its interaction with 
 | 
			
		||||
				rvalues. A const reference may still cause a copy, and will require a const 
 | 
			
		||||
				operator(). A non-const reference won't bind to an rvalue at all. A good 
 | 
			
		||||
				solution to this problem is the rvalue reference proposed in <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">
 | 
			
		||||
					N1377</A>/<A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">N1385</A>.]</EM></P>
 | 
			
		||||
		<pre>shared_ptr(shared_ptr const & r); // never throws
 | 
			
		||||
template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws</pre>
 | 
			
		||||
@@ -255,17 +266,11 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never
 | 
			
		||||
					r.use_count()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
		</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>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
 | 
			
		||||
				<b>r</b> and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p>
 | 
			
		||||
			<p><b>Effects:</b> If <b>r</b> is <EM>empty</EM>, constructs an <EM>empty</EM> <b>shared_ptr</b>; 
 | 
			
		||||
				otherwise, constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with <b>r</b>
 | 
			
		||||
				and stores a copy of the pointer stored in <STRONG>r</STRONG>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>use_count() == r.use_count()</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> <b>bad_weak_ptr</b> when <code>r.use_count() == 0</code>.</p>
 | 
			
		||||
			<p><b>Exception safety:</b> If an exception is thrown, the constructor has no 
 | 
			
		||||
@@ -275,8 +280,8 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Constructs a <B>shared_ptr</B>, as if by storing a copy of <STRONG>r.release()</STRONG>.</P>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>use_count() == 1</code>.</p>
 | 
			
		||||
			<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>
 | 
			
		||||
			<p><b>Throws:</b> <b>std::bad_alloc</b> or an implementation-defined exception when 
 | 
			
		||||
				a resource other than memory could not be obtained.</p>
 | 
			
		||||
			<P><B>Exception safety:</B> If an exception is thrown, the constructor has no 
 | 
			
		||||
				effect.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
@@ -320,6 +325,12 @@ q = p;
 | 
			
		||||
</pre>
 | 
			
		||||
			<p>both assignments may be no-ops.</p>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<P><EM>[Some experts consider the note to be redundant, as it appears to essentially 
 | 
			
		||||
				mirror the "as if" rule. However, experience suggests that when C++ code is 
 | 
			
		||||
				used to describe effects, it is often misinterpreted as required 
 | 
			
		||||
				implementation. In addition, it is not entirely clear whether the "as if" rule 
 | 
			
		||||
				actually applies here, so it's better to be explicit about the possible 
 | 
			
		||||
				optimizations.]</EM></P>
 | 
			
		||||
		<h3><a name="reset">reset</a></h3>
 | 
			
		||||
		<pre>void reset(); // never throws</pre>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
@@ -333,14 +344,6 @@ q = p;
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</P>
 | 
			
		||||
		</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>
 | 
			
		||||
		<pre>T & operator*() const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
@@ -373,8 +376,8 @@ q = p;
 | 
			
		||||
		<pre>long use_count() const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> the number of <b>shared_ptr</b> objects, <STRONG>*this</STRONG> included, 
 | 
			
		||||
				that <i>share ownership</i> with <b>*this</b>, or 0 when <STRONG>*this</STRONG>
 | 
			
		||||
				is <EM>empty</EM>.</p>
 | 
			
		||||
				that <i>share ownership</i> with <b>*this</b>, or an unspecified nonnegative 
 | 
			
		||||
				value when <STRONG>*this</STRONG> is <EM>empty</EM>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only 
 | 
			
		||||
				for debugging and testing purposes, not for production code.</P>
 | 
			
		||||
@@ -424,7 +427,7 @@ q = p;
 | 
			
		||||
				<LI>
 | 
			
		||||
					under the equivalence relation defined by <STRONG>operator<</STRONG>, <code>!(a 
 | 
			
		||||
						< b) && !(b < a)</code>, two <STRONG>shared_ptr</STRONG> instances 
 | 
			
		||||
					are equivalent if and only if they <EM>share ownership</EM> or are both <EM>empty</EM>.</LI></UL>
 | 
			
		||||
					are equivalent if and only if they <EM>share ownership</EM>.</LI></UL>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in 
 | 
			
		||||
				associative containers.</P>
 | 
			
		||||
@@ -522,7 +525,6 @@ q = p;
 | 
			
		||||
			<P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG>
 | 
			
		||||
				of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&d</code>; 
 | 
			
		||||
				otherwise returns 0.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h2><a name="example">Example</a></h2>
 | 
			
		||||
		<p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a 
 | 
			
		||||
@@ -600,32 +602,11 @@ p3.reset(new int(1));
 | 
			
		||||
// thread B
 | 
			
		||||
p3.reset(new int(2)); // undefined, multiple writes
 | 
			
		||||
</pre>
 | 
			
		||||
		<p> </p>
 | 
			
		||||
		<P>Starting with Boost release 1.33.0, <STRONG>shared_ptr</STRONG> uses a lock-free 
 | 
			
		||||
			implementation on the following platforms:</P>
 | 
			
		||||
		<UL>
 | 
			
		||||
			<LI>
 | 
			
		||||
			GNU GCC on x86 or x86-64;
 | 
			
		||||
			<LI>
 | 
			
		||||
			GNU GCC on IA64;
 | 
			
		||||
			<LI>
 | 
			
		||||
			Metrowerks CodeWarrior on PowerPC;
 | 
			
		||||
			<LI>
 | 
			
		||||
			GNU GCC on PowerPC;
 | 
			
		||||
			<LI>
 | 
			
		||||
				Windows.</LI></UL>
 | 
			
		||||
		<P>If your program is single-threaded and does not link to any libraries that might 
 | 
			
		||||
			have used <STRONG>shared_ptr</STRONG> in its default configuration, you can <STRONG>
 | 
			
		||||
				#define</STRONG> the macro <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> on a 
 | 
			
		||||
			project-wide basis to switch to ordinary non-atomic reference count updates.</P>
 | 
			
		||||
		<P>(Defining <STRONG>BOOST_SP_DISABLE_THREADS</STRONG> in some, but not all, 
 | 
			
		||||
			translation units is technically a violation of the One Definition Rule and 
 | 
			
		||||
			undefined behavior. Nevertheless, the implementation attempts to do its best to 
 | 
			
		||||
			accommodate the request to use non-atomic updates in those translation units. 
 | 
			
		||||
			No guarantees, though.)</P>
 | 
			
		||||
		<P>You can define the macro <STRONG>BOOST_SP_USE_PTHREADS</STRONG> to turn off the 
 | 
			
		||||
			lock-free platform-specific implementation and fall back to the generic <STRONG>pthread_mutex_t</STRONG>-based 
 | 
			
		||||
			code.</P>
 | 
			
		||||
		<p><STRONG>shared_ptr</STRONG> uses <A href="../config/config.htm">Boost.Config</A> 
 | 
			
		||||
			to detect whether the implementation supports threads. If your program is 
 | 
			
		||||
			single-threaded, but your platform is autodetected by <STRONG>Boost.Config</STRONG>
 | 
			
		||||
			as supporting multiple threads, <STRONG>#define BOOST_DISABLE_THREADS</STRONG> to 
 | 
			
		||||
			eliminate the thread safety overhead.</p>
 | 
			
		||||
		<h2><a name="FAQ">Frequently Asked Questions</a></h2>
 | 
			
		||||
		<P><B>Q.</B> There are several variations of shared pointers, with different 
 | 
			
		||||
			tradeoffs; why does the smart pointer library supply only a single 
 | 
			
		||||
@@ -646,7 +627,7 @@ p3.reset(new int(2)); // undefined, multiple writes
 | 
			
		||||
			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 
 | 
			
		||||
			pointer of choice for a wide range of applications. (Those interested in policy 
 | 
			
		||||
			based smart pointers should read <A href="http://www.awprofessional.com/bookstore/product.asp?isbn=0201704315&rl=1">
 | 
			
		||||
			based smart pointers should read <A href="http://cseng.aw.com/book/0,,0201704315,00.html">
 | 
			
		||||
				Modern C++ Design</A> by Andrei Alexandrescu.)<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate 
 | 
			
		||||
@@ -710,8 +691,9 @@ int * p = a.release();
 | 
			
		||||
		<p>
 | 
			
		||||
			$Date$</p>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
				Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, 
 | 
			
		||||
				Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
 | 
			
		||||
				or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
				Copyright 2002, 2003 Peter Dimov. 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.</small></p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,8 @@
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</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"
 | 
			
		||||
					border="0"></A>Smart Pointers</h1>
 | 
			
		||||
		<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Smart 
 | 
			
		||||
			Pointers</h1>
 | 
			
		||||
		<p><a href="#Introduction">Introduction</a><br>
 | 
			
		||||
			<a href="#common_requirements">Common Requirements</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 
 | 
			
		||||
			possibly throwing <b>std::bad_alloc</b>.</p>
 | 
			
		||||
		<h2><a name="Exception-specifications">Exception-specifications</a></h2>
 | 
			
		||||
		<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
 | 
			
		||||
		<p>Exception-specifications are not used; see <a href="../../more/lib_guide.htm#Exception-specification">
 | 
			
		||||
				exception-specification rationale</a>.</p>
 | 
			
		||||
		<p>All the smart pointer templates contain member functions which can never throw 
 | 
			
		||||
			exceptions, because they neither throw exceptions themselves nor call other 
 | 
			
		||||
@@ -177,9 +177,10 @@
 | 
			
		||||
			and an extensive bibliography.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>$Date$</p>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. 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 copy at
 | 
			
		||||
			<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
		<p>Copyright 1999 Greg Colvin and Beman Dawes. 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>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF">
 | 
			
		||||
 | 
			
		||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Smart Pointer Timings</h1>
 | 
			
		||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" WIDTH="277" HEIGHT="86">Smart Pointer Timings</h1>
 | 
			
		||||
 | 
			
		||||
<p>In late January 2000, Mark Borgerding put forward a suggestion to boost for 
 | 
			
		||||
  a new design of smart pointer whereby an intrusive doubly linked list is used 
 | 
			
		||||
@@ -21,10 +21,10 @@
 | 
			
		||||
  mailing list and the tests which this page describes were performed to provide 
 | 
			
		||||
  a guide for current and future investigations into smart pointer implementation 
 | 
			
		||||
  strategies.</p>
 | 
			
		||||
<p>Thanks are due to <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>,
 | 
			
		||||
<p>Thanks are due to <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>,
 | 
			
		||||
Gavin Collings,
 | 
			
		||||
<a href="http://www.boost.org/people/greg_colvin.htm">Greg Colvin</a> and
 | 
			
		||||
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a> 
 | 
			
		||||
<a href="../../people/greg_colvin.htm">Greg Colvin</a> and
 | 
			
		||||
<a href="../../people/beman_dawes.html">Beman Dawes</a> 
 | 
			
		||||
  for test code and trial implementations, the final version of which can be found 
 | 
			
		||||
  in .zip format <a href="smarttest.zip">here</a>.</p>
 | 
			
		||||
<h2>Description</h2>
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,8 @@
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
	</head>
 | 
			
		||||
	<body text="#000000" bgColor="#ffffff">
 | 
			
		||||
		<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
 | 
			
		||||
					border="0"></A>Smart Pointer Programming Techniques</h1>
 | 
			
		||||
		<h1><IMG height="86" alt="c++boost.gif (8819 bytes)" src="../../c++boost.gif" width="277" align="middle">Smart 
 | 
			
		||||
			Pointer Programming Techniques</h1>
 | 
			
		||||
		<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
 | 
			
		||||
			<A href="#pimpl">The "Pimpl" idiom</A><br>
 | 
			
		||||
			<A href="#abstract">Using abstract classes for implementation hiding</A><br>
 | 
			
		||||
@@ -272,9 +272,6 @@ shared_ptr<X> createX()
 | 
			
		||||
			single reference created in <code>make_shared_from_COM</code>. Weak pointers 
 | 
			
		||||
			created from <code>pw</code> will be invalidated when the last <code>shared_ptr</code>
 | 
			
		||||
			is destroyed, regardless of whether the COM object itself is still alive.</p>
 | 
			
		||||
		<P>As <A href="../bind/mem_fn.html#Q3">explained</A> in the <code>mem_fn</code> documentation, 
 | 
			
		||||
			you need to <A href="../bind/mem_fn.html#stdcall">#define 
 | 
			
		||||
				BOOST_MEM_FN_ENABLE_STDCALL</A> first.</P>
 | 
			
		||||
		<h2><A name="intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object 
 | 
			
		||||
				with an embedded reference count</A></h2>
 | 
			
		||||
		<p>This is a generalization of the above technique. The example assumes that the 
 | 
			
		||||
@@ -519,9 +516,6 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
</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>
 | 
			
		||||
		<p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
 | 
			
		||||
				incomplete class technique</A> described above. An example:</p>
 | 
			
		||||
@@ -758,8 +752,9 @@ public:
 | 
			
		||||
			all weak pointers will automatically expire.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>$Date$</p>
 | 
			
		||||
		<p><small>Copyright <20> 2003 Peter Dimov. Distributed under the Boost Software License, Version 
 | 
			
		||||
				1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 
 | 
			
		||||
				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
 | 
			
		||||
		<p><small>Copyright <20> 2003 Peter Dimov. 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.</small></p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								test/Jamfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								test/Jamfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
#  Boost.SmartPtr Library test Jamfile
 | 
			
		||||
#
 | 
			
		||||
#  Copyright (c) 2003 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 ]
 | 
			
		||||
          [ compile-fail shared_ptr_assign_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,11 +1,12 @@
 | 
			
		||||
#  Boost.SmartPtr Library test Jamfile
 | 
			
		||||
#
 | 
			
		||||
#  Copyright (c) 2003-2007 Peter Dimov
 | 
			
		||||
#  Copyright (c) 2003 Peter Dimov
 | 
			
		||||
#  Copyright (c) 2003 Dave Abrahams
 | 
			
		||||
#
 | 
			
		||||
#  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)
 | 
			
		||||
#  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.
 | 
			
		||||
 | 
			
		||||
# bring in rules for testing
 | 
			
		||||
import testing ;
 | 
			
		||||
@@ -13,40 +14,23 @@ import testing ;
 | 
			
		||||
{
 | 
			
		||||
    test-suite "smart_ptr"
 | 
			
		||||
        : [ run smart_ptr_test.cpp ]
 | 
			
		||||
          [ run shared_ptr_basic_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
 | 
			
		||||
          [ run shared_ptr_basic_test.cpp : : : <toolset><gcc>:<cxxflags>-Wno-non-virtual-dtor ]
 | 
			
		||||
          [ run shared_ptr_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
 | 
			
		||||
          [ run weak_ptr_test.cpp ]
 | 
			
		||||
          [ run shared_from_this_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
 | 
			
		||||
          [ run get_deleter_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 ]
 | 
			
		||||
          [ 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 ]
 | 
			
		||||
          [ compile-fail scoped_ptr_eq_fail.cpp ]
 | 
			
		||||
          [ compile-fail scoped_array_eq_fail.cpp ]
 | 
			
		||||
          [ run esft_regtest.cpp ]
 | 
			
		||||
          [ run yield_k_test.cpp ]
 | 
			
		||||
          [ run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ]
 | 
			
		||||
          [ run spinlock_test.cpp ]
 | 
			
		||||
          [ run spinlock_try_test.cpp ]
 | 
			
		||||
          [ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
 | 
			
		||||
          [ run spinlock_pool_test.cpp ]
 | 
			
		||||
          [ run make_shared_test.cpp ]
 | 
			
		||||
          [ run sp_convertible_test.cpp ]
 | 
			
		||||
          [ run wp_convertible_test.cpp ]
 | 
			
		||||
          [ run ip_convertible_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_test.cpp ]
 | 
			
		||||
          [ run sp_atomic_test.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,189 +0,0 @@
 | 
			
		||||
//  allocate_shared_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007, 2008 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/make_shared.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const & );
 | 
			
		||||
    X & operator=( X const & );
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static int instances;
 | 
			
		||||
 | 
			
		||||
    int v;
 | 
			
		||||
 | 
			
		||||
    explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~X()
 | 
			
		||||
    {
 | 
			
		||||
        --instances;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int X::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>() );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( *pi == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>(), 5 );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( *pi == 5 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>() );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 0 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,40 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
// atomic_count_test.cpp
 | 
			
		||||
//
 | 
			
		||||
// Copyright 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/atomic_count.hpp>
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::atomic_count n( 4 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( n == 4L );
 | 
			
		||||
 | 
			
		||||
    ++n;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( n == 5L );
 | 
			
		||||
    BOOST_TEST( --n != 0L );
 | 
			
		||||
 | 
			
		||||
    boost::detail::atomic_count m( 0 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == 0 );
 | 
			
		||||
 | 
			
		||||
    ++m;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == 1 );
 | 
			
		||||
 | 
			
		||||
    ++m;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == 2 );
 | 
			
		||||
    BOOST_TEST( --m != 0 );
 | 
			
		||||
    BOOST_TEST( --m == 0 );
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,111 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  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();
 | 
			
		||||
}
 | 
			
		||||
@@ -3,9 +3,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,221 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  esft_regtest.cpp
 | 
			
		||||
//
 | 
			
		||||
//  A regression test for enable_shared_from_this
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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/enable_shared_from_this.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
class X: public boost::enable_shared_from_this< X >
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    int destroyed_;
 | 
			
		||||
    int deleted_;
 | 
			
		||||
    int expected_;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const& );
 | 
			
		||||
    X& operator=( X const& );
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static int instances;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~X()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( deleted_ == expected_ );
 | 
			
		||||
        BOOST_TEST( destroyed_ == 0 );
 | 
			
		||||
        ++destroyed_;
 | 
			
		||||
        --instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    typedef void (*deleter_type)( X* );
 | 
			
		||||
 | 
			
		||||
    static void deleter( X * px )
 | 
			
		||||
    {
 | 
			
		||||
        ++px->deleted_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void deleter2( X * px )
 | 
			
		||||
    {
 | 
			
		||||
        ++px->deleted_;
 | 
			
		||||
        delete px;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int X::instances = 0;
 | 
			
		||||
 | 
			
		||||
void test()
 | 
			
		||||
{
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        X x( 0 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        std::auto_ptr<X> px( new X( 0 ) );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<X> px( new X( 0 ) );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        boost::weak_ptr<X> wp( px );
 | 
			
		||||
        BOOST_TEST( !wp.expired() );
 | 
			
		||||
 | 
			
		||||
        px.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( wp.expired() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        X x( 1 );
 | 
			
		||||
        boost::shared_ptr<X> px( &x, X::deleter );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
 | 
			
		||||
        BOOST_TEST( pd != 0 && *pd == X::deleter );
 | 
			
		||||
 | 
			
		||||
        boost::weak_ptr<X> wp( px );
 | 
			
		||||
        BOOST_TEST( !wp.expired() );
 | 
			
		||||
 | 
			
		||||
        px.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( wp.expired() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<X> px( new X( 1 ), X::deleter2 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
 | 
			
		||||
        BOOST_TEST( pd != 0 && *pd == X::deleter2 );
 | 
			
		||||
 | 
			
		||||
        boost::weak_ptr<X> wp( px );
 | 
			
		||||
        BOOST_TEST( !wp.expired() );
 | 
			
		||||
 | 
			
		||||
        px.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( wp.expired() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct V: public boost::enable_shared_from_this<V>
 | 
			
		||||
{
 | 
			
		||||
    virtual ~V() {}
 | 
			
		||||
    std::string m_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct V2
 | 
			
		||||
{
 | 
			
		||||
    virtual ~V2() {}
 | 
			
		||||
    std::string m2_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct W: V2, V
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void test2()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr<W> p( new W );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test3()
 | 
			
		||||
{
 | 
			
		||||
    V * p = new W;
 | 
			
		||||
    boost::shared_ptr<void> pv( p );
 | 
			
		||||
    BOOST_TEST( pv.get() == p );
 | 
			
		||||
    BOOST_TEST( pv.use_count() == 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct null_deleter
 | 
			
		||||
{
 | 
			
		||||
    void operator()( void const* ) const {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void test4()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr<V> pv( new V );
 | 
			
		||||
    boost::shared_ptr<V> pv2( pv.get(), null_deleter() );
 | 
			
		||||
    BOOST_TEST( pv2.get() == pv.get() );
 | 
			
		||||
    BOOST_TEST( pv2.use_count() == 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test5()
 | 
			
		||||
{
 | 
			
		||||
    V v;
 | 
			
		||||
 | 
			
		||||
    boost::shared_ptr<V> p1( &v, null_deleter() );
 | 
			
		||||
    BOOST_TEST( p1.get() == &v );
 | 
			
		||||
    BOOST_TEST( p1.use_count() == 1 );
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        p1->shared_from_this();
 | 
			
		||||
    }
 | 
			
		||||
    catch( ... )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ERROR( "p1->shared_from_this() failed" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    p1.reset();
 | 
			
		||||
 | 
			
		||||
    boost::shared_ptr<V> p2( &v, null_deleter() );
 | 
			
		||||
    BOOST_TEST( p2.get() == &v );
 | 
			
		||||
    BOOST_TEST( p2.use_count() == 1 );
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        p2->shared_from_this();
 | 
			
		||||
    }
 | 
			
		||||
    catch( ... )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ERROR( "p2->shared_from_this() failed" );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    test();
 | 
			
		||||
    test2();
 | 
			
		||||
    test3();
 | 
			
		||||
    test4();
 | 
			
		||||
    test5();
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -3,9 +3,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
 
 | 
			
		||||
@@ -19,16 +19,16 @@
 | 
			
		||||
//
 | 
			
		||||
//  intrusive_ptr_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002-2005 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <boost/intrusive_ptr.hpp>
 | 
			
		||||
#include <boost/detail/atomic_count.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
@@ -42,7 +42,7 @@ class base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    boost::detail::atomic_count use_count_;
 | 
			
		||||
    long use_count_;
 | 
			
		||||
 | 
			
		||||
    base(base const &);
 | 
			
		||||
    base & operator=(base const &);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,54 +0,0 @@
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
//  wp_convertible_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 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/intrusive_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
struct W
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void intrusive_ptr_add_ref( W* )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void intrusive_ptr_release( W* )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct X: public virtual W
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Y: public virtual W
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Z: public X
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int f( boost::intrusive_ptr<X> )
 | 
			
		||||
{
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int f( boost::intrusive_ptr<Y> )
 | 
			
		||||
{
 | 
			
		||||
    return 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    BOOST_TEST( 1 == f( boost::intrusive_ptr<Z>() ) );
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
// lw_mutex_test.cpp
 | 
			
		||||
//
 | 
			
		||||
// Copyright 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_mutex.hpp>
 | 
			
		||||
 | 
			
		||||
// Sanity check only
 | 
			
		||||
 | 
			
		||||
boost::detail::lightweight_mutex m1;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::detail::lightweight_mutex::scoped_lock lock1( m1 );
 | 
			
		||||
 | 
			
		||||
    boost::detail::lightweight_mutex m2;
 | 
			
		||||
    boost::detail::lightweight_mutex m3;
 | 
			
		||||
 | 
			
		||||
    boost::detail::lightweight_mutex::scoped_lock lock2( m2 );
 | 
			
		||||
    boost::detail::lightweight_mutex::scoped_lock lock3( m3 );
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,189 +0,0 @@
 | 
			
		||||
//  make_shared_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2007, 2008 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/make_shared.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const & );
 | 
			
		||||
    X & operator=( X const & );
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static int instances;
 | 
			
		||||
 | 
			
		||||
    int v;
 | 
			
		||||
 | 
			
		||||
    explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~X()
 | 
			
		||||
    {
 | 
			
		||||
        --instances;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int X::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< int > pi = boost::make_shared< int >();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( *pi == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< int > pi = boost::make_shared< int >( 5 );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( *pi == 5 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >();
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 0 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
 | 
			
		||||
        boost::weak_ptr<X> wp( pi );
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST( pi.get() != 0 );
 | 
			
		||||
        BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
 | 
			
		||||
 | 
			
		||||
        pi.reset();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( X::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,126 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  pointer_cast_test.cpp - a test for boost/pointer_cast.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2005 Ion Gaztanaga
 | 
			
		||||
//  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();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,74 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  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;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// scoped_array_eq_fail.cpp - a negative test for "p == q"
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2008 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/scoped_array.hpp>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::scoped_array<int> p, q;
 | 
			
		||||
    p == q; // must fail
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// scoped_ptr_eq_fail.cpp - a negative test for "p == q"
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2008 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/scoped_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::scoped_ptr<int> p, q;
 | 
			
		||||
    p == q; // must fail
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -12,9 +12,10 @@
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 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)
 | 
			
		||||
//  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.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -133,8 +134,7 @@ void test3()
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<V> r = v2.shared_from_this();
 | 
			
		||||
        BOOST_TEST( p < r || r < p );
 | 
			
		||||
        BOOST_TEST( r.get() == &v2 );
 | 
			
		||||
        BOOST_ERROR("v2.shared_from_this() failed to throw");
 | 
			
		||||
    }
 | 
			
		||||
    catch(boost::bad_weak_ptr const &)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,146 +0,0 @@
 | 
			
		||||
#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();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,224 +0,0 @@
 | 
			
		||||
#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();
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user